mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' of github.com:Microsoft/TypeScript into rest-param-destructuring
This commit is contained in:
@@ -16,7 +16,7 @@ Please fill in the *entire* template below.
|
||||
-->
|
||||
|
||||
<!-- Please try to reproduce the issue with `typescript@next`. It may have already been fixed. -->
|
||||
**TypeScript Version:** 3.1.0-dev.201xxxxx
|
||||
**TypeScript Version:** 3.3.0-dev.201xxxxx
|
||||
|
||||
<!-- Search terms you tried before logging this (so others can find this issue more easily) -->
|
||||
**Search Terms:**
|
||||
|
||||
@@ -32,8 +32,10 @@ What shortcomings exist with current approaches?
|
||||
## Checklist
|
||||
|
||||
My suggestion meets these guidelines:
|
||||
* [ ] This wouldn't be a breaking change in existing TypeScript / JavaScript code
|
||||
|
||||
* [ ] This wouldn't be a breaking change in existing TypeScript/JavaScript code
|
||||
* [ ] This wouldn't change the runtime behavior of existing JavaScript code
|
||||
* [ ] This could be implemented without emitting different JS based on the types of the expressions
|
||||
* [ ] This isn't a runtime feature (e.g. new expression-level syntax)
|
||||
* [ ] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
|
||||
* [ ] This feature would agree with the rest of [TypeScript's Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals).
|
||||
|
||||
|
||||
+3
-1
@@ -74,4 +74,6 @@ tests/cases/user/*/**/*.d.ts
|
||||
!tests/cases/user/bignumber.js/
|
||||
!tests/cases/user/discord.js/
|
||||
tests/baselines/reference/dt
|
||||
.failed-tests
|
||||
.failed-tests
|
||||
TEST-results.xml
|
||||
package-lock.json
|
||||
+3
-6
@@ -1,8 +1,8 @@
|
||||
language: node_js
|
||||
|
||||
node_js:
|
||||
- 'stable'
|
||||
- '8'
|
||||
- 'node'
|
||||
- '10'
|
||||
- '6'
|
||||
|
||||
sudo: false
|
||||
@@ -16,10 +16,7 @@ matrix:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- release-2.7
|
||||
- release-2.8
|
||||
- release-2.9
|
||||
- release-3.0
|
||||
- /^release-.*/
|
||||
|
||||
install:
|
||||
- npm uninstall typescript --no-save
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
||||
+20
-13
@@ -72,7 +72,7 @@ Your pull request should:
|
||||
* Requests need not be a single commit, but should be a linear sequence of commits (i.e. no merge commits in your PR)
|
||||
* It is desirable, but not necessary, for the tests to pass at each commit
|
||||
* Have clear commit messages
|
||||
* e.g. "Refactor feature", "Fix issue", "Add tests for issue"
|
||||
* e.g. "Minor refactor in goToTypeDefinition", "Fix iterated type in for-await-of", "Add test for preserveWatchOutput on command line"
|
||||
* Include adequate tests
|
||||
* At least one test should fail in the absence of your non-test code changes. If your PR does not match this criteria, please specify why
|
||||
* Tests should include reasonable permutations of the target fix/change
|
||||
@@ -82,19 +82,26 @@ Your pull request should:
|
||||
* To avoid line ending issues, set `autocrlf = input` and `whitespace = cr-at-eol` in your git configuration
|
||||
|
||||
## Contributing `lib.d.ts` fixes
|
||||
|
||||
The library sources are in: [src/lib](https://github.com/Microsoft/TypeScript/tree/master/src/lib)
|
||||
|
||||
Library files in `built/local/` are updated by running
|
||||
```Shell
|
||||
There are three relevant locations to be aware of when it comes to TypeScript's library declaration files:
|
||||
|
||||
* `src/lib`: the location of the sources themselves.
|
||||
* `lib`: the location of the last-known-good (LKG) versions of the files which are updated periodically.
|
||||
* `built/local`: the build output location, including where `src/lib` files will be copied to.
|
||||
|
||||
Any changes should be made to [src/lib](https://github.com/Microsoft/TypeScript/tree/master/src/lib). **Most** of these files can be updated by hand, with the exception of any generated files (see below).
|
||||
|
||||
Library files in `built/local/` are updated automatically by running the standard build task:
|
||||
|
||||
```sh
|
||||
jake
|
||||
```
|
||||
|
||||
The files in `lib/` are used to bootstrap compilation and usually do not need to be updated.
|
||||
The files in `lib/` are used to bootstrap compilation and usually **should not** be updated unless publishing a new version or updating the LKG.
|
||||
|
||||
#### `src/lib/dom.generated.d.ts` and `src/lib/webworker.generated.d.ts`
|
||||
### Modifying generated library files
|
||||
|
||||
These two files represent the DOM typings and are auto-generated. To make any modifications to them, please submit a PR to https://github.com/Microsoft/TSJS-lib-generator
|
||||
The files `src/lib/dom.generated.d.ts` and `src/lib/webworker.generated.d.ts` both represent type declarations for the DOM and are auto-generated. To make any modifications to them, you will have to direct changes to https://github.com/Microsoft/TSJS-lib-generator
|
||||
|
||||
## Running the Tests
|
||||
|
||||
@@ -104,7 +111,7 @@ To run all tests, invoke the `runtests-parallel` target using jake:
|
||||
jake runtests-parallel
|
||||
```
|
||||
|
||||
This run will all tests; to run only a specific subset of tests, use:
|
||||
This will run all tests; to run only a specific subset of tests, use:
|
||||
|
||||
```Shell
|
||||
jake runtests tests=<regex>
|
||||
@@ -137,10 +144,10 @@ You can specify which browser to use for debugging. Currently Chrome and IE are
|
||||
jake runtests-browser tests=2dArrays browser=chrome
|
||||
```
|
||||
|
||||
You can debug with VS Code or Node instead with `jake runtests debug=true`:
|
||||
You can debug with VS Code or Node instead with `jake runtests inspect=true`:
|
||||
|
||||
```Shell
|
||||
jake runtests tests=2dArrays debug=true
|
||||
jake runtests tests=2dArrays inspect=true
|
||||
```
|
||||
|
||||
## Adding a Test
|
||||
@@ -153,7 +160,7 @@ The supported names and values are the same as those supported in the compiler i
|
||||
They are useful for tests relating to modules.
|
||||
See below for examples.
|
||||
|
||||
**Note** that if you have a test corresponding to a specific spec compliance item, you can place it in `tests\cases\conformance` in an appropriately-named subfolder.
|
||||
**Note** that if you have a test corresponding to a specific spec compliance item, you can place it in `tests\cases\conformance` in an appropriately-named subfolder.
|
||||
**Note** that filenames here must be distinct from all other compiler testcase names, so you may have to work a bit to find a unique name if it's something common.
|
||||
|
||||
### Tests for multiple files
|
||||
@@ -194,6 +201,6 @@ to establish the new baselines as the desired behavior. This will change the fil
|
||||
## Localization
|
||||
|
||||
All strings the user may see are stored in [`diagnosticMessages.json`](./src/compiler/diagnosticMessages.json).
|
||||
If you make changes to it, run `jake generate-diagnostics` to push them to the `Diagnostic` interface in [`diagnosticInformationMap.generated.ts`](./src/compiler/diagnosticInformationMap.generated.ts).
|
||||
If you make changes to it, run `jake generate-diagnostics` to push them to the `Diagnostic` interface in `diagnosticInformationMap.generated.ts`.
|
||||
|
||||
See [coding guidelines on diagnostic messages](https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines#diagnostic-messages).
|
||||
|
||||
+59
-36
@@ -24,10 +24,9 @@ const baselineAccept = require("./scripts/build/baselineAccept");
|
||||
const cmdLineOptions = require("./scripts/build/options");
|
||||
const exec = require("./scripts/build/exec");
|
||||
const browserify = require("./scripts/build/browserify");
|
||||
const debounce = require("./scripts/build/debounce");
|
||||
const prepend = require("./scripts/build/prepend");
|
||||
const { removeSourceMaps } = require("./scripts/build/sourcemaps");
|
||||
const { CancelSource, CancelError } = require("./scripts/build/cancellation");
|
||||
const { CancellationTokenSource, CancelError, delay, Semaphore } = require("prex");
|
||||
const { libraryTargets, generateLibs } = require("./scripts/build/lib");
|
||||
const { runConsoleTests, cleanTestDirs, writeTestConfigFile, refBaseline, localBaseline, refRwcBaseline, localRwcBaseline } = require("./scripts/build/tests");
|
||||
|
||||
@@ -118,7 +117,8 @@ const generatedLCGFile = "built/local/enu/diagnosticMessages.generated.json.lcg"
|
||||
* 2. 'src\compiler\diagnosticMessages.generated.json' => 'built\local\ENU\diagnosticMessages.generated.json.lcg'
|
||||
* generate the lcg file (source of messages to localize) from the diagnosticMessages.generated.json
|
||||
*/
|
||||
const localizationTargets = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"]
|
||||
const localizationTargets = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-br", "ru", "tr", "zh-cn", "zh-tw"]
|
||||
.map(f => f.toLowerCase())
|
||||
.map(f => `built/local/${f}/diagnosticMessages.generated.json`)
|
||||
.concat(generatedLCGFile);
|
||||
|
||||
@@ -534,57 +534,80 @@ gulp.task(
|
||||
["watch-diagnostics", "watch-lib"].concat(useCompilerDeps),
|
||||
() => project.watch(tsserverProject, { typescript: useCompiler }));
|
||||
|
||||
gulp.task(
|
||||
"watch-local",
|
||||
/*help*/ false,
|
||||
["watch-lib", "watch-tsc", "watch-services", "watch-server"]);
|
||||
|
||||
gulp.task(
|
||||
"watch-runner",
|
||||
/*help*/ false,
|
||||
useCompilerDeps,
|
||||
() => project.watch(testRunnerProject, { typescript: useCompiler }));
|
||||
|
||||
const watchPatterns = [
|
||||
runJs,
|
||||
typescriptDts,
|
||||
tsserverlibraryDts
|
||||
];
|
||||
gulp.task(
|
||||
"watch-local",
|
||||
"Watches for changes to projects in src/ (but does not execute tests).",
|
||||
["watch-lib", "watch-tsc", "watch-services", "watch-server", "watch-runner", "watch-lssl"]);
|
||||
|
||||
gulp.task(
|
||||
"watch",
|
||||
"Watches for changes to the build inputs for built/local/run.js, then executes runtests-parallel.",
|
||||
"Watches for changes to the build inputs for built/local/run.js, then runs tests.",
|
||||
["build-rules", "watch-runner", "watch-services", "watch-lssl"],
|
||||
() => {
|
||||
/** @type {CancelSource | undefined} */
|
||||
let runTestsSource;
|
||||
const sem = new Semaphore(1);
|
||||
|
||||
const fn = debounce(() => {
|
||||
runTests().catch(error => {
|
||||
if (error instanceof CancelError) {
|
||||
log.warn("Operation was canceled");
|
||||
}
|
||||
else {
|
||||
log.error(error);
|
||||
}
|
||||
});
|
||||
}, /*timeout*/ 100, { max: 500 });
|
||||
|
||||
gulp.watch(watchPatterns, () => project.wait().then(fn));
|
||||
gulp.watch([runJs, typescriptDts, tsserverlibraryDts], () => {
|
||||
runTests();
|
||||
});
|
||||
|
||||
// NOTE: gulp.watch is far too slow when watching tests/cases/**/* as it first enumerates *every* file
|
||||
const testFilePattern = /(\.ts|[\\/]tsconfig\.json)$/;
|
||||
fs.watch("tests/cases", { recursive: true }, (_, file) => {
|
||||
if (testFilePattern.test(file)) project.wait().then(fn);
|
||||
if (testFilePattern.test(file)) runTests();
|
||||
});
|
||||
|
||||
function runTests() {
|
||||
if (runTestsSource) runTestsSource.cancel();
|
||||
runTestsSource = new CancelSource();
|
||||
return cmdLineOptions.tests || cmdLineOptions.failed
|
||||
? runConsoleTests(runJs, "mocha-fivemat-progress-reporter", /*runInParallel*/ false, /*watchMode*/ true, runTestsSource.token)
|
||||
: runConsoleTests(runJs, "min", /*runInParallel*/ true, /*watchMode*/ true, runTestsSource.token);
|
||||
}
|
||||
async function runTests() {
|
||||
try {
|
||||
// Ensure only one instance of the test runner is running at any given time.
|
||||
if (sem.count > 0) {
|
||||
await sem.wait();
|
||||
try {
|
||||
// Wait for any concurrent recompilations to complete...
|
||||
try {
|
||||
await delay(100);
|
||||
while (project.hasRemainingWork()) {
|
||||
await project.waitForWorkToComplete();
|
||||
await delay(500);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
if (e instanceof CancelError) return;
|
||||
throw e;
|
||||
}
|
||||
|
||||
// cancel any pending or active test run if a new recompilation is triggered
|
||||
const source = new CancellationTokenSource();
|
||||
project.waitForWorkToStart().then(() => {
|
||||
source.cancel();
|
||||
});
|
||||
|
||||
if (cmdLineOptions.tests || cmdLineOptions.failed) {
|
||||
await runConsoleTests(runJs, "mocha-fivemat-progress-reporter", /*runInParallel*/ false, /*watchMode*/ true, source.token);
|
||||
}
|
||||
else {
|
||||
await runConsoleTests(runJs, "min", /*runInParallel*/ true, /*watchMode*/ true, source.token);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
sem.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
if (e instanceof CancelError) {
|
||||
log.warn("Operation was canceled");
|
||||
}
|
||||
else {
|
||||
log.error(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
gulp.task("clean-built", /*help*/ false, [`clean:${diagnosticInformationMapTs}`], () => del(["built"]));
|
||||
|
||||
+2
-18
@@ -24,8 +24,6 @@ else if (process.env.PATH !== undefined) {
|
||||
|
||||
const host = process.env.TYPESCRIPT_HOST || process.env.host || "node";
|
||||
|
||||
const locales = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"];
|
||||
|
||||
const defaultTestTimeout = 40000;
|
||||
|
||||
let useDebugMode = true;
|
||||
@@ -147,14 +145,14 @@ task(TaskNames.local, [
|
||||
task("default", [TaskNames.local]);
|
||||
|
||||
const RunTestsPrereqs = [TaskNames.lib, Paths.servicesDefinitionFile, Paths.typescriptDefinitionFile, Paths.tsserverLibraryDefinitionFile];
|
||||
desc("Runs all the tests in parallel using the built run.js file. Optional arguments are: t[ests]=category1|category2|... d[ebug]=true.");
|
||||
desc("Runs all the tests in parallel using the built run.js file. Optional arguments are: t[ests]=category1|category2|... i[nspect]=true.");
|
||||
task(TaskNames.runtestsParallel, RunTestsPrereqs, function () {
|
||||
tsbuild([ConfigFileFor.runjs], true, () => {
|
||||
runConsoleTests("min", /*parallel*/ true);
|
||||
});
|
||||
}, { async: true });
|
||||
|
||||
desc("Runs all the tests in parallel using the built run.js file. Optional arguments are: t[ests]=category1|category2|... d[ebug]=true.");
|
||||
desc("Runs all the tests in parallel using the built run.js file. Optional arguments are: t[ests]=category1|category2|... i[nspect]=true.");
|
||||
task(TaskNames.runtests, RunTestsPrereqs, function () {
|
||||
tsbuild([ConfigFileFor.runjs], true, () => {
|
||||
runConsoleTests('mocha-fivemat-progress-reporter', /*runInParallel*/ false);
|
||||
@@ -520,7 +518,6 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
}
|
||||
|
||||
let testTimeout = process.env.timeout || defaultTestTimeout;
|
||||
const debug = process.env.debug || process.env["debug-brk"] || process.env.d;
|
||||
const inspect = process.env.inspect || process.env["inspect-brk"] || process.env.i;
|
||||
const runners = process.env.runners || process.env.runner || process.env.ru;
|
||||
const tests = process.env.test || process.env.tests || process.env.t;
|
||||
@@ -710,19 +707,6 @@ const Travis = {
|
||||
}
|
||||
};
|
||||
|
||||
function buildLocalizedTargets() {
|
||||
/**
|
||||
* The localization target produces the two following transformations:
|
||||
* 1. 'src\loc\lcl\<locale>\diagnosticMessages.generated.json.lcl' => 'built\local\<locale>\diagnosticMessages.generated.json'
|
||||
* convert localized resources into a .json file the compiler can understand
|
||||
* 2. 'src\compiler\diagnosticMessages.generated.json' => 'built\local\ENU\diagnosticMessages.generated.json.lcg'
|
||||
* generate the lcg file (source of messages to localize) from the diagnosticMessages.generated.json
|
||||
*/
|
||||
const localizationTargets = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-br", "ru", "tr", "zh-cn", "zh-tw"]
|
||||
.map(f => path.join(Paths.builtLocal,f))
|
||||
.concat(path.dirname(Paths.generatedLCGFile));
|
||||
}
|
||||
|
||||
function toNs(diff) {
|
||||
return diff[0] * 1e9 + diff[1];
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
[](https://gitter.im/Microsoft/TypeScript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
[TypeScript](https://www.typescriptlang.org/) is a language for application-scale JavaScript. TypeScript adds optional types, classes, and modules to JavaScript. TypeScript supports tools for large-scale JavaScript applications for any browser, for any host, on any OS. TypeScript compiles to readable, standards-based JavaScript. Try it out at the [playground](https://www.typescriptlang.org/play/), and stay up to date via [our blog](https://blogs.msdn.microsoft.com/typescript) and [Twitter account](https://twitter.com/typescriptlang).
|
||||
[TypeScript](https://www.typescriptlang.org/) is a language for application-scale JavaScript. TypeScript adds optional types to JavaScript that support tools for large-scale JavaScript applications for any browser, for any host, on any OS. TypeScript compiles to readable, standards-based JavaScript. Try it out at the [playground](https://www.typescriptlang.org/play/), and stay up to date via [our blog](https://blogs.msdn.microsoft.com/typescript) and [Twitter account](https://twitter.com/typescriptlang).
|
||||
|
||||
## Installing
|
||||
|
||||
@@ -29,7 +29,7 @@ There are many ways to [contribute](https://github.com/Microsoft/TypeScript/blob
|
||||
* [Submit bugs](https://github.com/Microsoft/TypeScript/issues) and help us verify fixes as they are checked in.
|
||||
* Review the [source code changes](https://github.com/Microsoft/TypeScript/pulls).
|
||||
* Engage with other TypeScript users and developers on [StackOverflow](https://stackoverflow.com/questions/tagged/typescript).
|
||||
* Join the [#typescript](https://twitter.com/#!/search/realtime/%23typescript) discussion on Twitter.
|
||||
* Join the [#typescript](https://twitter.com/search?q=%23TypeScript) discussion on Twitter.
|
||||
* [Contribute bug fixes](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md).
|
||||
* Read the language specification ([docx](https://github.com/Microsoft/TypeScript/blob/master/doc/TypeScript%20Language%20Specification.docx?raw=true),
|
||||
[pdf](https://github.com/Microsoft/TypeScript/blob/master/doc/TypeScript%20Language%20Specification.pdf?raw=true), [md](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md)).
|
||||
@@ -61,7 +61,7 @@ Change to the TypeScript directory:
|
||||
cd TypeScript
|
||||
```
|
||||
|
||||
Install Jake tools and dev dependencies:
|
||||
Install [Jake](http://jakejs.com/) tools and dev dependencies:
|
||||
|
||||
```bash
|
||||
npm install -g jake
|
||||
|
||||
@@ -164,5 +164,30 @@ For purposes of this definition, the normative portions of the Specification sha
|
||||
I am encouraged to provide a contact from which licensing information can be obtained and other relevant licensing information. Any such information will be made publicly available.
|
||||
10.8. You or Your. “You,” “you,” or “your” means any person or entity who exercises copyright or patent rights granted under this Agreement, and any person that person or entity controls.
|
||||
|
||||
-------------------------------------------------------------------------------------
|
||||
|
||||
------------------- WebGL -----------------------------
|
||||
Copyright (c) 2018 The Khronos Group Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and/or associated documentation files (the
|
||||
"Materials"), to deal in the Materials without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
permit persons to whom the Materials are furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Materials.
|
||||
|
||||
THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
------------------------------------------------------
|
||||
|
||||
------------- End of ThirdPartyNotices ------------------------------------------- */
|
||||
|
||||
|
||||
+1
-1
@@ -286,7 +286,7 @@ function f(s) {
|
||||
}
|
||||
```
|
||||
|
||||
In the JavaScript output, all type annotations have been erased. In general, TypeScript erases all type information before emiting JavaScript.
|
||||
In the JavaScript output, all type annotations have been erased. In general, TypeScript erases all type information before emitting JavaScript.
|
||||
|
||||
## <a name="1.1"/>1.1 Ambient Declarations
|
||||
|
||||
|
||||
@@ -49,8 +49,8 @@
|
||||
"A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged_2434": "Eine Namespacedeklaration darf nicht vor der Klasse oder Funktion positioniert werden, mit der sie zusammengeführt wird.",
|
||||
"A_namespace_declaration_is_only_allowed_in_a_namespace_or_module_1235": "Eine Namespacedeklaration ist nur in einem Namespace oder Modul zulässig.",
|
||||
"A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_7038": "Ein Import im Namespacestil kann nicht aufgerufen oder erstellt werden und verursacht zur Laufzeit einen Fehler.",
|
||||
"A_non_dry_build_would_build_project_0_6357": "Bei einem Build mit dem Flag \"-dry\" würde das Projekt \"{0}\" erstellt.",
|
||||
"A_non_dry_build_would_delete_the_following_files_Colon_0_6356": "Bei einem Build mit dem Flag \"-dry\" würden die folgenden Dateien gelöscht: {0}",
|
||||
"A_non_dry_build_would_build_project_0_6357": "Bei einem Build ohne das Flag \"-dry\" würde das Projekt \"{0}\" erstellt.",
|
||||
"A_non_dry_build_would_delete_the_following_files_Colon_0_6356": "Bei einem Build ohne das Flag \"-dry\" würden die folgenden Dateien gelöscht: {0}",
|
||||
"A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation_2371": "Ein Parameterinitialisierer ist nur in einer Funktions- oder Konstruktorimplementierung zulässig.",
|
||||
"A_parameter_property_cannot_be_declared_using_a_rest_parameter_1317": "Eine Parametereigenschaft darf nicht mithilfe eines rest-Parameters deklariert werden.",
|
||||
"A_parameter_property_is_only_allowed_in_a_constructor_implementation_2369": "Eine Parametereigenschaft ist nur in einer Konstruktorimplementierung zulässig.",
|
||||
@@ -938,7 +938,7 @@
|
||||
"Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_con_1322": "Der Typ iterierter Elemente eines \"yield*\"-Operanden muss entweder eine gültige Zusage sein oder darf keinen aufrufbaren \"then\"-Member enthalten.",
|
||||
"Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_cal_1321": "Der Typ eines \"yield\"-Operanden in einem asynchronen Generator muss entweder eine gültige Zusage sein oder darf keinen aufrufbaren \"then\"-Member enthalten.",
|
||||
"Type_parameter_0_has_a_circular_constraint_2313": "Der Typparameter \"{0}\" weist eine zirkuläre Einschränkung auf.",
|
||||
"Type_parameter_0_has_a_circular_default_2716": "Der Typparameter \"{0}\" weist einen zirkulären Standard auf.",
|
||||
"Type_parameter_0_has_a_circular_default_2716": "Der Typparameter \"{0}\" besitzt einen zirkulären Standardwert.",
|
||||
"Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008": "Der Typparameter \"{0}\" der Aufrufsignatur aus der exportierten Schnittstelle besitzt oder verwendet den privaten Namen \"{1}\".",
|
||||
"Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4006": "Der Typparameter \"{0}\" der Konstruktorsignatur aus der exportierten Schnittstelle besitzt oder verwendet den privaten Namen \"{1}\".",
|
||||
"Type_parameter_0_of_exported_class_has_or_is_using_private_name_1_4002": "Der Typparameter \"{0}\" der exportierten Klasse besitzt oder verwendet den privaten Namen \"{1}\".",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -328,7 +328,7 @@
|
||||
"Do_not_emit_outputs_if_any_errors_were_reported_6008": "No emitir salidas si se informa de algún error.",
|
||||
"Do_not_emit_use_strict_directives_in_module_output_6112": "No emitir directivas 'use strict' en la salida del módulo.",
|
||||
"Do_not_erase_const_enum_declarations_in_generated_code_6007": "No borrar las declaraciones de enumeración const en el código generado.",
|
||||
"Do_not_generate_custom_helper_functions_like_extends_in_compiled_output_6157": "No generar funciones auxiliares personalizadas como \"__extends\" en la salida compilada.",
|
||||
"Do_not_generate_custom_helper_functions_like_extends_in_compiled_output_6157": "No generar funciones del asistente personalizadas como \"__extends\" en la salida compilada.",
|
||||
"Do_not_include_the_default_library_file_lib_d_ts_6158": "No incluir el archivo de biblioteca predeterminado (lib.d.ts).",
|
||||
"Do_not_report_errors_on_unreachable_code_6077": "No notificar los errores del código inaccesible.",
|
||||
"Do_not_report_errors_on_unused_labels_6074": "No notificar los errores de las etiquetas no usadas.",
|
||||
@@ -477,7 +477,7 @@
|
||||
"Import_declaration_0_is_using_private_name_1_4000": "La declaración de importación '{0}' usa el nombre privado '{1}'.",
|
||||
"Import_declaration_conflicts_with_local_declaration_of_0_2440": "La declaración de importación está en conflicto con la declaración local de \"{0}\".",
|
||||
"Import_declarations_in_a_namespace_cannot_reference_a_module_1147": "Las declaraciones de importación de un espacio de nombres no pueden hacer referencia a un módulo.",
|
||||
"Import_emit_helpers_from_tslib_6139": "Importe elementos auxiliares de emisión de \"tslib\".",
|
||||
"Import_emit_helpers_from_tslib_6139": "Importe asistentes de emisión de \"tslib\".",
|
||||
"Import_may_be_converted_to_a_default_import_80003": "La importación puede convertirse a una importación predeterminada.",
|
||||
"Import_name_cannot_be_0_2438": "El nombre de importación no puede ser \"{0}\".",
|
||||
"Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relati_2439": "La declaración de importación o exportación de una declaración de módulo de ambiente no puede hacer referencia al módulo a través de su nombre relativo.",
|
||||
@@ -892,8 +892,8 @@
|
||||
"The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer_1190": "La declaración de variable de una instrucción \"for...of\" no puede tener un inicializador.",
|
||||
"The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any_2410": "No se admite la instrucción 'with'. Todos los símbolos de un bloque 'with' tendrán el tipo 'any'.",
|
||||
"This_constructor_function_may_be_converted_to_a_class_declaration_80002": "Esta función de constructor puede convertirse en una declaración de clase.",
|
||||
"This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found_2354": "Esta sintaxis requiere una aplicación auxiliar importada, pero no se puede encontrar el módulo \"{0}\".",
|
||||
"This_syntax_requires_an_imported_helper_named_1_but_module_0_has_no_exported_member_1_2343": "Esta sintaxis requiere una aplicación auxiliar importada denominada \"{1}\", pero el módulo \"{0}\" no tiene el miembro exportado \"{1}\".",
|
||||
"This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found_2354": "Esta sintaxis requiere un asistente importado, pero no se puede encontrar el módulo \"{0}\".",
|
||||
"This_syntax_requires_an_imported_helper_named_1_but_module_0_has_no_exported_member_1_2343": "Esta sintaxis requiere un asistente importado denominado \"{1}\", pero el módulo \"{0}\" no tiene el miembro exportado \"{1}\".",
|
||||
"Trailing_comma_not_allowed_1009": "No se permite la coma final.",
|
||||
"Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule_6153": "Transpilar cada archivo como un módulo aparte (parecido a \"ts.transpileModule\").",
|
||||
"Try_npm_install_types_Slash_0_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_mod_7035": "Pruebe \"npm install @types/{0}\" si existe o agregue un nuevo archivo de declaración (.d.ts) que incluya \"declare module '{0}';\"",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"A_0_modifier_cannot_be_used_with_an_interface_declaration_1045": "'{0}' 한정자는 인터페이스 선언에서 사용할 수 없습니다.",
|
||||
"A_0_parameter_must_be_the_first_parameter_2680": "'{0}' 매개 변수는 첫 번째 매개 변수여야 합니다.",
|
||||
"A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature_2463": "바인딩 패턴 매개 변수는 구현 서명에서 선택 사항이 될 수 없습니다.",
|
||||
"A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement_1105": "'break' 문은 이 문을 둘러싼 반복 문 또는 switch 문 내에서만 사용할 수 있습니다.",
|
||||
"A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement_1105": "'break' 문은 이 문을 둘러싼 반복문 또는 switch 문 내에서만 사용할 수 있습니다.",
|
||||
"A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement_1116": "'break' 문은 이 문을 둘러싼 문의 레이블로만 이동할 수 있습니다.",
|
||||
"A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments_2500": "클래스는 선택적 형식 인수가 포함된 식별자/정규화된 이름만 구현할 수 있습니다.",
|
||||
"A_class_declaration_without_the_default_modifier_must_have_a_name_1211": "'default' 한정자를 사용하지 않는 클래스 선언에는 이름이 있어야 합니다.",
|
||||
@@ -23,8 +23,8 @@
|
||||
"A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_1254": "앰비언트 컨텍스트의 'const' 이니셜라이저는 문자열 또는 숫자 리터럴이어야 합니다.",
|
||||
"A_constructor_cannot_contain_a_super_call_when_its_class_extends_null_17005": "생성자는 해당 클래스가 'null'을 확장하는 경우 'super' 호출을 포함할 수 없습니다.",
|
||||
"A_constructor_cannot_have_a_this_parameter_2681": "생성자에는 'this' 매개 변수를 사용할 수 없습니다.",
|
||||
"A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement_1104": "'continue' 문은 이 문을 둘러싼 반복 문 내에서만 사용할 수 있습니다.",
|
||||
"A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement_1115": "'continue' 문은 이 문을 둘러싼 반복 문의 레이블로만 이동할 수 있습니다.",
|
||||
"A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement_1104": "'continue' 문은 이 문을 둘러싼 반복문 내에서만 사용할 수 있습니다.",
|
||||
"A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement_1115": "'continue' 문은 이 문을 둘러싼 반복문의 레이블로만 이동할 수 있습니다.",
|
||||
"A_declare_modifier_cannot_be_used_in_an_already_ambient_context_1038": "'declare' 한정자는 이미 존재하는 앰비언트 컨텍스트에서 사용할 수 없습니다.",
|
||||
"A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file_1046": "'declare' 한정자는 .d.ts 파일의 최상위 선언에 필요합니다.",
|
||||
"A_decorator_can_only_decorate_a_method_implementation_not_an_overload_1249": "데코레이터는 오버로드가 아니라 메서드 구현만 데코레이팅할 수 있습니다.",
|
||||
@@ -68,7 +68,7 @@
|
||||
"A_rest_parameter_cannot_have_an_initializer_1048": "rest 매개 변수에는 이니셜라이저를 사용할 수 없습니다.",
|
||||
"A_rest_parameter_must_be_last_in_a_parameter_list_1014": "rest 매개 변수는 매개 변수 목록 마지막에 있어야 합니다.",
|
||||
"A_rest_parameter_must_be_of_an_array_type_2370": "rest 매개 변수는 배열 형식이어야 합니다.",
|
||||
"A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma_1013": "rest 매개 변수 또는 바인딩 패턴에 후행 쉼표를 사용할 수 없습니다.",
|
||||
"A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma_1013": "rest 매개 변수 또는 바인딩 패턴에 후행 쉼표가 없을 수 있습니다.",
|
||||
"A_return_statement_can_only_be_used_within_a_function_body_1108": "'return' 문은 함수 본문 내에서만 사용할 수 있습니다.",
|
||||
"A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl_6167": "가져오기를 'baseUrl'에 상대적인 조회 위치로 다시 매핑하는 일련의 항목입니다.",
|
||||
"A_set_accessor_cannot_have_a_return_type_annotation_1095": "'set' 접근자에는 반환 형식 주석을 사용할 수 없습니다.",
|
||||
@@ -232,7 +232,7 @@
|
||||
"Cannot_invoke_an_object_which_is_possibly_null_2721": "'null'일 수 있는 개체를 호출할 수 없습니다.",
|
||||
"Cannot_invoke_an_object_which_is_possibly_null_or_undefined_2723": "'null'이거나 '정의되지 않음'일 수 있는 개체를 호출할 수 없습니다.",
|
||||
"Cannot_invoke_an_object_which_is_possibly_undefined_2722": "'정의되지 않음'일 수 있는 개체를 호출할 수 없습니다.",
|
||||
"Cannot_prepend_project_0_because_it_does_not_have_outFile_set_6308": "'outFile' 집합이 없기 때문에 '{0}' 프로젝트를 추가할 수 없습니다.",
|
||||
"Cannot_prepend_project_0_because_it_does_not_have_outFile_set_6308": "'{0}' 프로젝트는 'outFile'이 설정되어 있지 않기 때문에 앞에 추가할 수 없습니다.",
|
||||
"Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided_1205": "'--isolatedModules' 플래그가 제공된 경우 형식을 다시 내보낼 수 없습니다.",
|
||||
"Cannot_read_file_0_Colon_1_5012": "파일 '{0}'을(를) 읽을 수 없습니다. {1}.",
|
||||
"Cannot_redeclare_block_scoped_variable_0_2451": "블록 범위 변수 '{0}'을(를) 다시 선언할 수 없습니다.",
|
||||
@@ -274,7 +274,7 @@
|
||||
"Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json_6020": "구성 파일에 대한 경로 또는 'tsconfig.json'이 포함된 폴더에 대한 경로를 고려하여 프로젝트를 컴파일합니다.",
|
||||
"Compiler_option_0_expects_an_argument_6044": "컴파일러 옵션 '{0}'에는 인수가 필요합니다.",
|
||||
"Compiler_option_0_requires_a_value_of_type_1_5024": "컴파일러 옵션 '{0}'에 {1} 형식의 값이 필요합니다.",
|
||||
"Composite_projects_may_not_disable_declaration_emit_6304": "복합 프로젝트는 선언 내보내기를 사용하지 않도록 설정할 수 없습니다.",
|
||||
"Composite_projects_may_not_disable_declaration_emit_6304": "복합 프로젝트는 선언 내보내기를 비활성화할 수 없습니다.",
|
||||
"Computed_property_names_are_not_allowed_in_enums_1164": "컴퓨팅된 속성 이름은 열거형에 사용할 수 없습니다.",
|
||||
"Computed_values_are_not_permitted_in_an_enum_with_string_valued_members_2553": "계산된 값은 문자열 값 멤버가 포함된 열거형에서 허용되지 않습니다.",
|
||||
"Concatenate_and_emit_output_to_single_file_6001": "출력을 연결하고 단일 파일로 내보냅니다.",
|
||||
@@ -445,7 +445,7 @@
|
||||
"Function_overload_must_be_static_2387": "함수 오버로드는 정적이어야 합니다.",
|
||||
"Function_overload_must_not_be_static_2388": "함수 오버로드는 정적이 아니어야 합니다.",
|
||||
"Generate_get_and_set_accessors_95046": "'get' 및 'set' 접근자 생성",
|
||||
"Generates_a_sourcemap_for_each_corresponding_d_ts_file_6000": "해당하는 각 '.d.ts' 파일의 sourcemap을 생성합니다.",
|
||||
"Generates_a_sourcemap_for_each_corresponding_d_ts_file_6000": "해당하는 각 '.d.ts' 파일에 sourcemap을 생성합니다.",
|
||||
"Generates_corresponding_d_ts_file_6002": "해당 '.d.ts' 파일을 생성합니다.",
|
||||
"Generates_corresponding_map_file_6043": "해당 '.map' 파일을 생성합니다.",
|
||||
"Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_typ_7025": "생성기는 값을 생성하지 않으므로 암시적으로 '{0}' 형식입니다. 반환 형식을 제공하세요.",
|
||||
@@ -677,13 +677,13 @@
|
||||
"Print_names_of_generated_files_part_of_the_compilation_6154": "컴파일의 일부인 생성된 파일의 이름을 인쇄합니다.",
|
||||
"Print_the_compiler_s_version_6019": "컴파일러 버전을 인쇄합니다.",
|
||||
"Print_this_message_6017": "이 메시지를 출력합니다.",
|
||||
"Project_0_can_t_be_built_because_its_dependency_1_has_errors_6363": "'{1}' 종속성에 오류가 있기 때문에 '{0}' 프로젝트를 빌드할 수 없습니다.",
|
||||
"Project_0_can_t_be_built_because_its_dependency_1_has_errors_6363": "'{0}' 프로젝트는 '{1}' 종속성에 오류가 있기 때문에 빌드할 수 없습니다.",
|
||||
"Project_0_is_out_of_date_because_its_dependency_1_is_out_of_date_6353": "'{1}' 종속성이 최신 상태가 아니기 때문에 '{0}' 프로젝트가 최신 상태가 아닙니다.",
|
||||
"Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2_6350": "가장 오래된 출력 '{1}'이(가) 최신 입력 '{2}'보다 오래되었기 때문에 '{0}' 프로젝트가 최신 상태가 아닙니다.",
|
||||
"Project_0_is_out_of_date_because_output_file_1_does_not_exist_6352": "'{1}' 출력 파일이 존재하지 않기 때문에 '{0}' 프로젝트가 최신 상태가 아닙니다.",
|
||||
"Project_0_is_up_to_date_6361": "'{0}' 프로젝트가 최신 상태입니다.",
|
||||
"Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2_6351": "최신 입력 '{1}'이(가) 가장 오래된 출력 '{2}'보다 오래되었기 때문에 '{0}' 프로젝트가 최신 상태입니다.",
|
||||
"Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies_6354": "종속성의 .d.ts 파일이 있기 때문에 '{0}' 프로젝트가 최신 상태입니다.",
|
||||
"Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies_6354": "'{0}' 프로젝트는 종속성에 .d.ts 파일이 있는 최신 상태입니다.",
|
||||
"Project_references_may_not_form_a_circular_graph_Cycle_detected_Colon_0_6202": "프로젝트 참조는 순환 그래프를 형성할 수 없습니다. 순환이 발견되었습니다. {0}",
|
||||
"Projects_in_this_build_Colon_0_6355": "이 빌드의 프로젝트: {0}",
|
||||
"Projects_to_reference_6300": "참조할 프로젝트",
|
||||
@@ -803,7 +803,7 @@
|
||||
"Show_what_would_be_built_or_deleted_if_specified_with_clean_6367": "빌드될 항목 표시(또는 '--clean'으로 지정된 경우 삭제될 항목 표시)",
|
||||
"Signature_0_must_be_a_type_predicate_1224": "'{0}' 시그니처는 형식 조건자여야 합니다.",
|
||||
"Skip_type_checking_of_declaration_files_6012": "선언 파일 형식 검사를 건너뜁니다.",
|
||||
"Skipping_build_of_project_0_because_its_dependency_1_has_errors_6362": "'{1}' 종속성에 오류가 있기 때문에 '{0}' 프로젝트 빌드를 건너뜁니다.",
|
||||
"Skipping_build_of_project_0_because_its_dependency_1_has_errors_6362": "'{0}' 프로젝트의 빌드는 '{1}' 종속성에 오류가 있기 때문에 건너뜁니다.",
|
||||
"Skipping_clean_because_not_all_projects_could_be_located_6371": "일부 프로젝트를 찾을 수 없으므로 정리를 건너뛰는 중입니다.",
|
||||
"Source_Map_Options_6175": "소스 맵 옵션",
|
||||
"Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature_2382": "특수화된 오버로드 시그니처는 특수화되지 않은 서명에 할당할 수 없습니다.",
|
||||
@@ -1039,7 +1039,7 @@
|
||||
"const_declarations_must_be_initialized_1155": "'const' 선언은 초기화해야 합니다.",
|
||||
"const_enum_member_initializer_was_evaluated_to_a_non_finite_value_2477": "'const' 열거형 멤버 이니셜라이저가 무한 값에 대해 평가되었습니다.",
|
||||
"const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN_2478": "'const' 열거형 멤버 이니셜라이저가 허용되지 않은 'NaN' 값에 대해 평가되었습니다.",
|
||||
"const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_im_2475": "'const' 열거형은 속성 또는 인덱스 액세스 식 또는 내보내기 할당 또는 가져오기 선언의 오른쪽 또는 형식 쿼리에서만 사용할 수 있습니다.",
|
||||
"const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_im_2475": "'const' 열거형은 속성이나 인덱스 액세스 식, 또는 내보내기 할당이나 가져오기 선언의 오른쪽, 또는 형식 쿼리에서만 사용할 수 있습니다.",
|
||||
"delete_cannot_be_called_on_an_identifier_in_strict_mode_1102": "strict 모드에서는 식별자에 대해 'delete'를 호출할 수 없습니다.",
|
||||
"delete_this_Project_0_is_up_to_date_because_it_was_previously_built_6360": "이 항목 삭제 - '{0}' 프로젝트는 이전에 빌드되었기 때문에 최신 상태입니다.",
|
||||
"enum_declarations_can_only_be_used_in_a_ts_file_8015": "'enum 선언'은 .ts 파일에서만 사용할 수 있습니다.",
|
||||
|
||||
Vendored
+3583
-2898
File diff suppressed because it is too large
Load Diff
Vendored
+32
-4
@@ -51,10 +51,13 @@ interface DOMStringList {
|
||||
|
||||
interface DOMTokenList {
|
||||
[Symbol.iterator](): IterableIterator<string>;
|
||||
entries(): IterableIterator<[number, string]>;
|
||||
keys(): IterableIterator<number>;
|
||||
values(): IterableIterator<string>;
|
||||
}
|
||||
|
||||
interface DataTransferItemList {
|
||||
[Symbol.iterator](): IterableIterator<File>;
|
||||
[Symbol.iterator](): IterableIterator<DataTransferItem>;
|
||||
}
|
||||
|
||||
interface FileList {
|
||||
@@ -87,9 +90,10 @@ interface HTMLCollectionBase {
|
||||
|
||||
interface HTMLCollectionOf<T extends Element> {
|
||||
[Symbol.iterator](): IterableIterator<T>;
|
||||
entries(): IterableIterator<[number, T]>;
|
||||
keys(): IterableIterator<number>;
|
||||
values(): IterableIterator<T>;
|
||||
}
|
||||
|
||||
interface HTMLFormElement {
|
||||
[Symbol.iterator](): IterableIterator<Element>;
|
||||
}
|
||||
|
||||
interface HTMLSelectElement {
|
||||
@@ -167,10 +171,34 @@ interface PluginArray {
|
||||
interface RTCStatsReport extends ReadonlyMap<string, any> {
|
||||
}
|
||||
|
||||
interface SVGLengthList {
|
||||
[Symbol.iterator](): IterableIterator<SVGLength>;
|
||||
}
|
||||
|
||||
interface SVGNumberList {
|
||||
[Symbol.iterator](): IterableIterator<SVGNumber>;
|
||||
}
|
||||
|
||||
interface SVGStringList {
|
||||
[Symbol.iterator](): IterableIterator<string>;
|
||||
}
|
||||
|
||||
interface SourceBufferList {
|
||||
[Symbol.iterator](): IterableIterator<SourceBuffer>;
|
||||
}
|
||||
|
||||
interface SpeechGrammarList {
|
||||
[Symbol.iterator](): IterableIterator<SpeechGrammar>;
|
||||
}
|
||||
|
||||
interface SpeechRecognitionResult {
|
||||
[Symbol.iterator](): IterableIterator<SpeechRecognitionAlternative>;
|
||||
}
|
||||
|
||||
interface SpeechRecognitionResultList {
|
||||
[Symbol.iterator](): IterableIterator<SpeechRecognitionResult>;
|
||||
}
|
||||
|
||||
interface StyleSheetList {
|
||||
[Symbol.iterator](): IterableIterator<StyleSheet>;
|
||||
}
|
||||
|
||||
Vendored
+2
-1
@@ -29,7 +29,8 @@ interface Map<K, V> {
|
||||
}
|
||||
|
||||
interface MapConstructor {
|
||||
new <K = any, V = any>(entries?: ReadonlyArray<[K, V]> | null): Map<K, V>;
|
||||
new(): Map<any, any>;
|
||||
new<K, V>(entries?: ReadonlyArray<[K, V]> | null): Map<K, V>;
|
||||
readonly prototype: Map<any, any>;
|
||||
}
|
||||
declare var Map: MapConstructor;
|
||||
|
||||
Vendored
+1
-1
@@ -155,7 +155,7 @@ interface MapConstructor {
|
||||
interface WeakMap<K extends object, V> { }
|
||||
|
||||
interface WeakMapConstructor {
|
||||
new <K extends object = object, V = any>(iterable: Iterable<[K, V]>): WeakMap<K, V>;
|
||||
new <K extends object, V>(iterable: Iterable<[K, V]>): WeakMap<K, V>;
|
||||
}
|
||||
|
||||
interface Set<T> {
|
||||
|
||||
Vendored
+2
-2
@@ -27,7 +27,7 @@ interface PromiseConstructor {
|
||||
/**
|
||||
* Creates a new Promise.
|
||||
* @param executor A callback used to initialize the promise. This callback is passed two arguments:
|
||||
* a resolve callback used resolve the promise with a value or the result of another promise,
|
||||
* a resolve callback used to resolve the promise with a value or the result of another promise,
|
||||
* and a reject callback used to reject the promise with a provided reason or error.
|
||||
*/
|
||||
new <T>(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void): Promise<T>;
|
||||
@@ -213,4 +213,4 @@ interface PromiseConstructor {
|
||||
resolve(): Promise<void>;
|
||||
}
|
||||
|
||||
declare var Promise: PromiseConstructor;
|
||||
declare var Promise: PromiseConstructor;
|
||||
|
||||
Vendored
+11
-11
@@ -83,7 +83,7 @@ interface SymbolConstructor {
|
||||
}
|
||||
|
||||
interface Symbol {
|
||||
readonly [Symbol.toStringTag]: "Symbol";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface Array<T> {
|
||||
@@ -127,23 +127,23 @@ interface Date {
|
||||
}
|
||||
|
||||
interface Map<K, V> {
|
||||
readonly [Symbol.toStringTag]: "Map";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface WeakMap<K extends object, V> {
|
||||
readonly [Symbol.toStringTag]: "WeakMap";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface Set<T> {
|
||||
readonly [Symbol.toStringTag]: "Set";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface WeakSet<T extends object> {
|
||||
readonly [Symbol.toStringTag]: "WeakSet";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface JSON {
|
||||
readonly [Symbol.toStringTag]: "JSON";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface Function {
|
||||
@@ -158,15 +158,15 @@ interface Function {
|
||||
}
|
||||
|
||||
interface GeneratorFunction {
|
||||
readonly [Symbol.toStringTag]: "GeneratorFunction";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface Math {
|
||||
readonly [Symbol.toStringTag]: "Math";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface Promise<T> {
|
||||
readonly [Symbol.toStringTag]: "Promise";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface PromiseConstructor {
|
||||
@@ -261,11 +261,11 @@ interface String {
|
||||
}
|
||||
|
||||
interface ArrayBuffer {
|
||||
readonly [Symbol.toStringTag]: "ArrayBuffer";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface DataView {
|
||||
readonly [Symbol.toStringTag]: "DataView";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface Int8Array {
|
||||
|
||||
Vendored
+75
-5
@@ -315,6 +315,66 @@ interface FunctionConstructor {
|
||||
|
||||
declare const Function: FunctionConstructor;
|
||||
|
||||
interface CallableFunction extends Function {
|
||||
/**
|
||||
* Calls the function with the specified object as the this value and the elements of specified array as the arguments.
|
||||
* @param thisArg The object to be used as the this object.
|
||||
* @param args An array of argument values to be passed to the function.
|
||||
*/
|
||||
apply<T, R>(this: (this: T) => R, thisArg: T): R;
|
||||
apply<T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, args: A): R;
|
||||
|
||||
/**
|
||||
* Calls the function with the specified object as the this value and the specified rest arguments as the arguments.
|
||||
* @param thisArg The object to be used as the this object.
|
||||
* @param args Argument values to be passed to the function.
|
||||
*/
|
||||
call<T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A): R;
|
||||
|
||||
/**
|
||||
* For a given function, creates a bound function that has the same body as the original function.
|
||||
* The this object of the bound function is associated with the specified object, and has the specified initial parameters.
|
||||
* @param thisArg The object to be used as the this object.
|
||||
* @param args Arguments to bind to the parameters of the function.
|
||||
*/
|
||||
bind<T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T): (...args: A) => R;
|
||||
bind<T, A0, A extends any[], R>(this: (this: T, arg0: A0, ...args: A) => R, thisArg: T, arg0: A0): (...args: A) => R;
|
||||
bind<T, A0, A1, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1): (...args: A) => R;
|
||||
bind<T, A0, A1, A2, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, arg2: A2, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1, arg2: A2): (...args: A) => R;
|
||||
bind<T, A0, A1, A2, A3, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3): (...args: A) => R;
|
||||
bind<T, AX, R>(this: (this: T, ...args: AX[]) => R, thisArg: T, ...args: AX[]): (...args: AX[]) => R;
|
||||
}
|
||||
|
||||
interface NewableFunction extends Function {
|
||||
/**
|
||||
* Calls the function with the specified object as the this value and the elements of specified array as the arguments.
|
||||
* @param thisArg The object to be used as the this object.
|
||||
* @param args An array of argument values to be passed to the function.
|
||||
*/
|
||||
apply<T>(this: new () => T, thisArg: T): void;
|
||||
apply<T, A extends any[]>(this: new (...args: A) => T, thisArg: T, args: A): void;
|
||||
|
||||
/**
|
||||
* Calls the function with the specified object as the this value and the specified rest arguments as the arguments.
|
||||
* @param thisArg The object to be used as the this object.
|
||||
* @param args Argument values to be passed to the function.
|
||||
*/
|
||||
call<T, A extends any[]>(this: new (...args: A) => T, thisArg: T, ...args: A): void;
|
||||
|
||||
/**
|
||||
* For a given function, creates a bound function that has the same body as the original function.
|
||||
* The this object of the bound function is associated with the specified object, and has the specified initial parameters.
|
||||
* @param thisArg The object to be used as the this object.
|
||||
* @param args Arguments to bind to the parameters of the function.
|
||||
*/
|
||||
bind<A extends any[], R>(this: new (...args: A) => R, thisArg: any): new (...args: A) => R;
|
||||
bind<A0, A extends any[], R>(this: new (arg0: A0, ...args: A) => R, thisArg: any, arg0: A0): new (...args: A) => R;
|
||||
bind<A0, A1, A extends any[], R>(this: new (arg0: A0, arg1: A1, ...args: A) => R, thisArg: any, arg0: A0, arg1: A1): new (...args: A) => R;
|
||||
bind<A0, A1, A2, A extends any[], R>(this: new (arg0: A0, arg1: A1, arg2: A2, ...args: A) => R, thisArg: any, arg0: A0, arg1: A1, arg2: A2): new (...args: A) => R;
|
||||
bind<A0, A1, A2, A3, A extends any[], R>(this: new (arg0: A0, arg1: A1, arg2: A2, arg3: A3, ...args: A) => R, thisArg: any, arg0: A0, arg1: A1, arg2: A2, arg3: A3): new (...args: A) => R;
|
||||
bind<AX, R>(this: new (...args: AX[]) => R, thisArg: any, ...args: AX[]): new (...args: AX[]) => R;
|
||||
}
|
||||
|
||||
interface IArguments {
|
||||
[index: number]: any;
|
||||
length: number;
|
||||
@@ -1145,15 +1205,15 @@ interface Array<T> {
|
||||
* Returns a string representation of an array. The elements are converted to string using their toLocalString methods.
|
||||
*/
|
||||
toLocaleString(): string;
|
||||
/**
|
||||
* Removes the last element from an array and returns it.
|
||||
*/
|
||||
pop(): T | undefined;
|
||||
/**
|
||||
* Appends new elements to an array, and returns the new length of the array.
|
||||
* @param items New elements of the Array.
|
||||
*/
|
||||
push(...items: T[]): number;
|
||||
/**
|
||||
* Removes the last element from an array and returns it.
|
||||
*/
|
||||
pop(): T | undefined;
|
||||
/**
|
||||
* Combines two or more arrays.
|
||||
* @param items Additional items to add to the end of array1.
|
||||
@@ -1370,7 +1430,7 @@ type Readonly<T> = {
|
||||
};
|
||||
|
||||
/**
|
||||
* From T pick a set of properties K
|
||||
* From T, pick a set of properties whose keys are in the union K
|
||||
*/
|
||||
type Pick<T, K extends keyof T> = {
|
||||
[P in K]: T[P];
|
||||
@@ -1398,6 +1458,16 @@ type Extract<T, U> = T extends U ? T : never;
|
||||
*/
|
||||
type NonNullable<T> = T extends null | undefined ? never : T;
|
||||
|
||||
/**
|
||||
* Obtain the parameters of a function type in a tuple
|
||||
*/
|
||||
type Parameters<T extends (...args: any[]) => any> = T extends (...args: infer P) => any ? P : never;
|
||||
|
||||
/**
|
||||
* Obtain the parameters of a constructor function type in a tuple
|
||||
*/
|
||||
type ConstructorParameters<T extends new (...args: any[]) => any> = T extends new (...args: infer P) => any ? P : never;
|
||||
|
||||
/**
|
||||
* Obtain the return type of a function type
|
||||
*/
|
||||
|
||||
Vendored
+2
-2
@@ -31,7 +31,7 @@ interface ReadonlyArray<T> {
|
||||
* thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
flatMap<U, This = undefined> (
|
||||
callback: (this: This, value: T, index: number, array: T[]) => U|U[],
|
||||
callback: (this: This, value: T, index: number, array: T[]) => U|ReadonlyArray<U>,
|
||||
thisArg?: This
|
||||
): U[]
|
||||
|
||||
@@ -145,7 +145,7 @@ interface Array<T> {
|
||||
* thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
flatMap<U, This = undefined> (
|
||||
callback: (this: This, value: T, index: number, array: T[]) => U|U[],
|
||||
callback: (this: This, value: T, index: number, array: T[]) => U|ReadonlyArray<U>,
|
||||
thisArg?: This
|
||||
): U[]
|
||||
|
||||
|
||||
Vendored
+629
@@ -0,0 +1,629 @@
|
||||
/*! *****************************************************************************
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of the
|
||||
License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
||||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
||||
MERCHANTABLITY OR NON-INFRINGEMENT.
|
||||
|
||||
See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
interface BigInt {
|
||||
/**
|
||||
* Returns a string representation of an object.
|
||||
* @param radix Specifies a radix for converting numeric values to strings.
|
||||
*/
|
||||
toString(radix?: number): string;
|
||||
|
||||
/** Returns a string representation appropriate to the host environment's current locale. */
|
||||
toLocaleString(): string;
|
||||
|
||||
/** Returns the primitive value of the specified object. */
|
||||
valueOf(): bigint;
|
||||
|
||||
readonly [Symbol.toStringTag]: "BigInt";
|
||||
}
|
||||
|
||||
interface BigIntConstructor {
|
||||
(value?: any): bigint;
|
||||
readonly prototype: BigInt;
|
||||
|
||||
/**
|
||||
* Interprets the low bits of a BigInt as a 2's-complement signed integer.
|
||||
* All higher bits are discarded.
|
||||
* @param bits The number of low bits to use
|
||||
* @param int The BigInt whose bits to extract
|
||||
*/
|
||||
asIntN(bits: number, int: bigint): bigint;
|
||||
/**
|
||||
* Interprets the low bits of a BigInt as an unsigned integer.
|
||||
* All higher bits are discarded.
|
||||
* @param bits The number of low bits to use
|
||||
* @param int The BigInt whose bits to extract
|
||||
*/
|
||||
asUintN(bits: number, int: bigint): bigint;
|
||||
}
|
||||
|
||||
declare const BigInt: BigIntConstructor;
|
||||
|
||||
/**
|
||||
* A typed array of 64-bit signed integer values. The contents are initialized to 0. If the
|
||||
* requested number of bytes could not be allocated, an exception is raised.
|
||||
*/
|
||||
interface BigInt64Array {
|
||||
/** The size in bytes of each element in the array. */
|
||||
readonly BYTES_PER_ELEMENT: number;
|
||||
|
||||
/** The ArrayBuffer instance referenced by the array. */
|
||||
readonly buffer: ArrayBufferLike;
|
||||
|
||||
/** The length in bytes of the array. */
|
||||
readonly byteLength: number;
|
||||
|
||||
/** The offset in bytes of the array. */
|
||||
readonly byteOffset: number;
|
||||
|
||||
/**
|
||||
* Returns the this object after copying a section of the array identified by start and end
|
||||
* to the same array starting at position target
|
||||
* @param target If target is negative, it is treated as length+target where length is the
|
||||
* length of the array.
|
||||
* @param start If start is negative, it is treated as length+start. If end is negative, it
|
||||
* is treated as length+end.
|
||||
* @param end If not specified, length of the this object is used as its default value.
|
||||
*/
|
||||
copyWithin(target: number, start: number, end?: number): this;
|
||||
|
||||
/** Yields index, value pairs for every entry in the array. */
|
||||
entries(): IterableIterator<[number, bigint]>;
|
||||
|
||||
/**
|
||||
* Determines whether all the members of an array satisfy the specified test.
|
||||
* @param callbackfn A function that accepts up to three arguments. The every method calls
|
||||
* the callbackfn function for each element in the array until the callbackfn returns false,
|
||||
* or until the end of the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
every(callbackfn: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): boolean;
|
||||
|
||||
/**
|
||||
* Returns the this object after filling the section identified by start and end with value
|
||||
* @param value value to fill array section with
|
||||
* @param start index to start filling the array at. If start is negative, it is treated as
|
||||
* length+start where length is the length of the array.
|
||||
* @param end index to stop filling the array at. If end is negative, it is treated as
|
||||
* length+end.
|
||||
*/
|
||||
fill(value: bigint, start?: number, end?: number): this;
|
||||
|
||||
/**
|
||||
* Returns the elements of an array that meet the condition specified in a callback function.
|
||||
* @param callbackfn A function that accepts up to three arguments. The filter method calls
|
||||
* the callbackfn function one time for each element in the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
filter(callbackfn: (value: bigint, index: number, array: BigInt64Array) => any, thisArg?: any): BigInt64Array;
|
||||
|
||||
/**
|
||||
* Returns the value of the first element in the array where predicate is true, and undefined
|
||||
* otherwise.
|
||||
* @param predicate find calls predicate once for each element of the array, in ascending
|
||||
* order, until it finds one where predicate returns true. If such an element is found, find
|
||||
* immediately returns that element value. Otherwise, find returns undefined.
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
find(predicate: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): bigint | undefined;
|
||||
|
||||
/**
|
||||
* Returns the index of the first element in the array where predicate is true, and -1
|
||||
* otherwise.
|
||||
* @param predicate find calls predicate once for each element of the array, in ascending
|
||||
* order, until it finds one where predicate returns true. If such an element is found,
|
||||
* findIndex immediately returns that element index. Otherwise, findIndex returns -1.
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
findIndex(predicate: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): number;
|
||||
|
||||
/**
|
||||
* Performs the specified action for each element in an array.
|
||||
* @param callbackfn A function that accepts up to three arguments. forEach calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
forEach(callbackfn: (value: bigint, index: number, array: BigInt64Array) => void, thisArg?: any): void;
|
||||
|
||||
/**
|
||||
* Determines whether an array includes a certain element, returning true or false as appropriate.
|
||||
* @param searchElement The element to search for.
|
||||
* @param fromIndex The position in this array at which to begin searching for searchElement.
|
||||
*/
|
||||
includes(searchElement: bigint, fromIndex?: number): boolean;
|
||||
|
||||
/**
|
||||
* Returns the index of the first occurrence of a value in an array.
|
||||
* @param searchElement The value to locate in the array.
|
||||
* @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
|
||||
* search starts at index 0.
|
||||
*/
|
||||
indexOf(searchElement: bigint, fromIndex?: number): number;
|
||||
|
||||
/**
|
||||
* Adds all the elements of an array separated by the specified separator string.
|
||||
* @param separator A string used to separate one element of an array from the next in the
|
||||
* resulting String. If omitted, the array elements are separated with a comma.
|
||||
*/
|
||||
join(separator?: string): string;
|
||||
|
||||
/** Yields each index in the array. */
|
||||
keys(): IterableIterator<number>;
|
||||
|
||||
/**
|
||||
* Returns the index of the last occurrence of a value in an array.
|
||||
* @param searchElement The value to locate in the array.
|
||||
* @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
|
||||
* search starts at index 0.
|
||||
*/
|
||||
lastIndexOf(searchElement: bigint, fromIndex?: number): number;
|
||||
|
||||
/** The length of the array. */
|
||||
readonly length: number;
|
||||
|
||||
/**
|
||||
* Calls a defined callback function on each element of an array, and returns an array that
|
||||
* contains the results.
|
||||
* @param callbackfn A function that accepts up to three arguments. The map method calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
map(callbackfn: (value: bigint, index: number, array: BigInt64Array) => bigint, thisArg?: any): BigInt64Array;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array. The return value of
|
||||
* the callback function is the accumulated result, and is provided as an argument in the next
|
||||
* call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduce method calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an argument
|
||||
* instead of an array value.
|
||||
*/
|
||||
reduce(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigInt64Array) => bigint): bigint;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array. The return value of
|
||||
* the callback function is the accumulated result, and is provided as an argument in the next
|
||||
* call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduce method calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an argument
|
||||
* instead of an array value.
|
||||
*/
|
||||
reduce<U>(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigInt64Array) => U, initialValue: U): U;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array, in descending order.
|
||||
* The return value of the callback function is the accumulated result, and is provided as an
|
||||
* argument in the next call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduceRight method calls
|
||||
* the callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an
|
||||
* argument instead of an array value.
|
||||
*/
|
||||
reduceRight(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigInt64Array) => bigint): bigint;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array, in descending order.
|
||||
* The return value of the callback function is the accumulated result, and is provided as an
|
||||
* argument in the next call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduceRight method calls
|
||||
* the callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an argument
|
||||
* instead of an array value.
|
||||
*/
|
||||
reduceRight<U>(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigInt64Array) => U, initialValue: U): U;
|
||||
|
||||
/** Reverses the elements in the array. */
|
||||
reverse(): this;
|
||||
|
||||
/**
|
||||
* Sets a value or an array of values.
|
||||
* @param array A typed or untyped array of values to set.
|
||||
* @param offset The index in the current array at which the values are to be written.
|
||||
*/
|
||||
set(array: ArrayLike<bigint>, offset?: number): void;
|
||||
|
||||
/**
|
||||
* Returns a section of an array.
|
||||
* @param start The beginning of the specified portion of the array.
|
||||
* @param end The end of the specified portion of the array.
|
||||
*/
|
||||
slice(start?: number, end?: number): BigInt64Array;
|
||||
|
||||
/**
|
||||
* Determines whether the specified callback function returns true for any element of an array.
|
||||
* @param callbackfn A function that accepts up to three arguments. The some method calls the
|
||||
* callbackfn function for each element in the array until the callbackfn returns true, or until
|
||||
* the end of the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
some(callbackfn: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): boolean;
|
||||
|
||||
/**
|
||||
* Sorts the array.
|
||||
* @param compareFn The function used to determine the order of the elements. If omitted, the elements are sorted in ascending order.
|
||||
*/
|
||||
sort(compareFn?: (a: bigint, b: bigint) => number | bigint): this;
|
||||
|
||||
/**
|
||||
* Gets a new BigInt64Array view of the ArrayBuffer store for this array, referencing the elements
|
||||
* at begin, inclusive, up to end, exclusive.
|
||||
* @param begin The index of the beginning of the array.
|
||||
* @param end The index of the end of the array.
|
||||
*/
|
||||
subarray(begin: number, end?: number): BigInt64Array;
|
||||
|
||||
/** Converts the array to a string by using the current locale. */
|
||||
toLocaleString(): string;
|
||||
|
||||
/** Returns a string representation of the array. */
|
||||
toString(): string;
|
||||
|
||||
/** Yields each value in the array. */
|
||||
values(): IterableIterator<bigint>;
|
||||
|
||||
[Symbol.iterator](): IterableIterator<bigint>;
|
||||
|
||||
readonly [Symbol.toStringTag]: "BigInt64Array";
|
||||
|
||||
[index: number]: bigint;
|
||||
}
|
||||
|
||||
interface BigInt64ArrayConstructor {
|
||||
readonly prototype: BigInt64Array;
|
||||
new(length?: number): BigInt64Array;
|
||||
new(array: Iterable<bigint>): BigInt64Array;
|
||||
new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): BigInt64Array;
|
||||
|
||||
/** The size in bytes of each element in the array. */
|
||||
readonly BYTES_PER_ELEMENT: number;
|
||||
|
||||
/**
|
||||
* Returns a new array from a set of elements.
|
||||
* @param items A set of elements to include in the new array object.
|
||||
*/
|
||||
of(...items: bigint[]): BigInt64Array;
|
||||
|
||||
/**
|
||||
* Creates an array from an array-like or iterable object.
|
||||
* @param arrayLike An array-like or iterable object to convert to an array.
|
||||
* @param mapfn A mapping function to call on every element of the array.
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from(arrayLike: ArrayLike<bigint>): BigInt64Array;
|
||||
from<U>(arrayLike: ArrayLike<U>, mapfn: (v: U, k: number) => bigint, thisArg?: any): BigInt64Array;
|
||||
}
|
||||
|
||||
declare const BigInt64Array: BigInt64ArrayConstructor;
|
||||
|
||||
/**
|
||||
* A typed array of 64-bit unsigned integer values. The contents are initialized to 0. If the
|
||||
* requested number of bytes could not be allocated, an exception is raised.
|
||||
*/
|
||||
interface BigUint64Array {
|
||||
/** The size in bytes of each element in the array. */
|
||||
readonly BYTES_PER_ELEMENT: number;
|
||||
|
||||
/** The ArrayBuffer instance referenced by the array. */
|
||||
readonly buffer: ArrayBufferLike;
|
||||
|
||||
/** The length in bytes of the array. */
|
||||
readonly byteLength: number;
|
||||
|
||||
/** The offset in bytes of the array. */
|
||||
readonly byteOffset: number;
|
||||
|
||||
/**
|
||||
* Returns the this object after copying a section of the array identified by start and end
|
||||
* to the same array starting at position target
|
||||
* @param target If target is negative, it is treated as length+target where length is the
|
||||
* length of the array.
|
||||
* @param start If start is negative, it is treated as length+start. If end is negative, it
|
||||
* is treated as length+end.
|
||||
* @param end If not specified, length of the this object is used as its default value.
|
||||
*/
|
||||
copyWithin(target: number, start: number, end?: number): this;
|
||||
|
||||
/** Yields index, value pairs for every entry in the array. */
|
||||
entries(): IterableIterator<[number, bigint]>;
|
||||
|
||||
/**
|
||||
* Determines whether all the members of an array satisfy the specified test.
|
||||
* @param callbackfn A function that accepts up to three arguments. The every method calls
|
||||
* the callbackfn function for each element in the array until the callbackfn returns false,
|
||||
* or until the end of the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
every(callbackfn: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): boolean;
|
||||
|
||||
/**
|
||||
* Returns the this object after filling the section identified by start and end with value
|
||||
* @param value value to fill array section with
|
||||
* @param start index to start filling the array at. If start is negative, it is treated as
|
||||
* length+start where length is the length of the array.
|
||||
* @param end index to stop filling the array at. If end is negative, it is treated as
|
||||
* length+end.
|
||||
*/
|
||||
fill(value: bigint, start?: number, end?: number): this;
|
||||
|
||||
/**
|
||||
* Returns the elements of an array that meet the condition specified in a callback function.
|
||||
* @param callbackfn A function that accepts up to three arguments. The filter method calls
|
||||
* the callbackfn function one time for each element in the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
filter(callbackfn: (value: bigint, index: number, array: BigUint64Array) => any, thisArg?: any): BigUint64Array;
|
||||
|
||||
/**
|
||||
* Returns the value of the first element in the array where predicate is true, and undefined
|
||||
* otherwise.
|
||||
* @param predicate find calls predicate once for each element of the array, in ascending
|
||||
* order, until it finds one where predicate returns true. If such an element is found, find
|
||||
* immediately returns that element value. Otherwise, find returns undefined.
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
find(predicate: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): bigint | undefined;
|
||||
|
||||
/**
|
||||
* Returns the index of the first element in the array where predicate is true, and -1
|
||||
* otherwise.
|
||||
* @param predicate find calls predicate once for each element of the array, in ascending
|
||||
* order, until it finds one where predicate returns true. If such an element is found,
|
||||
* findIndex immediately returns that element index. Otherwise, findIndex returns -1.
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
findIndex(predicate: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): number;
|
||||
|
||||
/**
|
||||
* Performs the specified action for each element in an array.
|
||||
* @param callbackfn A function that accepts up to three arguments. forEach calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
forEach(callbackfn: (value: bigint, index: number, array: BigUint64Array) => void, thisArg?: any): void;
|
||||
|
||||
/**
|
||||
* Determines whether an array includes a certain element, returning true or false as appropriate.
|
||||
* @param searchElement The element to search for.
|
||||
* @param fromIndex The position in this array at which to begin searching for searchElement.
|
||||
*/
|
||||
includes(searchElement: bigint, fromIndex?: number): boolean;
|
||||
|
||||
/**
|
||||
* Returns the index of the first occurrence of a value in an array.
|
||||
* @param searchElement The value to locate in the array.
|
||||
* @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
|
||||
* search starts at index 0.
|
||||
*/
|
||||
indexOf(searchElement: bigint, fromIndex?: number): number;
|
||||
|
||||
/**
|
||||
* Adds all the elements of an array separated by the specified separator string.
|
||||
* @param separator A string used to separate one element of an array from the next in the
|
||||
* resulting String. If omitted, the array elements are separated with a comma.
|
||||
*/
|
||||
join(separator?: string): string;
|
||||
|
||||
/** Yields each index in the array. */
|
||||
keys(): IterableIterator<number>;
|
||||
|
||||
/**
|
||||
* Returns the index of the last occurrence of a value in an array.
|
||||
* @param searchElement The value to locate in the array.
|
||||
* @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
|
||||
* search starts at index 0.
|
||||
*/
|
||||
lastIndexOf(searchElement: bigint, fromIndex?: number): number;
|
||||
|
||||
/** The length of the array. */
|
||||
readonly length: number;
|
||||
|
||||
/**
|
||||
* Calls a defined callback function on each element of an array, and returns an array that
|
||||
* contains the results.
|
||||
* @param callbackfn A function that accepts up to three arguments. The map method calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
map(callbackfn: (value: bigint, index: number, array: BigUint64Array) => bigint, thisArg?: any): BigUint64Array;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array. The return value of
|
||||
* the callback function is the accumulated result, and is provided as an argument in the next
|
||||
* call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduce method calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an argument
|
||||
* instead of an array value.
|
||||
*/
|
||||
reduce(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigUint64Array) => bigint): bigint;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array. The return value of
|
||||
* the callback function is the accumulated result, and is provided as an argument in the next
|
||||
* call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduce method calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an argument
|
||||
* instead of an array value.
|
||||
*/
|
||||
reduce<U>(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigUint64Array) => U, initialValue: U): U;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array, in descending order.
|
||||
* The return value of the callback function is the accumulated result, and is provided as an
|
||||
* argument in the next call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduceRight method calls
|
||||
* the callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an
|
||||
* argument instead of an array value.
|
||||
*/
|
||||
reduceRight(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigUint64Array) => bigint): bigint;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array, in descending order.
|
||||
* The return value of the callback function is the accumulated result, and is provided as an
|
||||
* argument in the next call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduceRight method calls
|
||||
* the callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an argument
|
||||
* instead of an array value.
|
||||
*/
|
||||
reduceRight<U>(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigUint64Array) => U, initialValue: U): U;
|
||||
|
||||
/** Reverses the elements in the array. */
|
||||
reverse(): this;
|
||||
|
||||
/**
|
||||
* Sets a value or an array of values.
|
||||
* @param array A typed or untyped array of values to set.
|
||||
* @param offset The index in the current array at which the values are to be written.
|
||||
*/
|
||||
set(array: ArrayLike<bigint>, offset?: number): void;
|
||||
|
||||
/**
|
||||
* Returns a section of an array.
|
||||
* @param start The beginning of the specified portion of the array.
|
||||
* @param end The end of the specified portion of the array.
|
||||
*/
|
||||
slice(start?: number, end?: number): BigUint64Array;
|
||||
|
||||
/**
|
||||
* Determines whether the specified callback function returns true for any element of an array.
|
||||
* @param callbackfn A function that accepts up to three arguments. The some method calls the
|
||||
* callbackfn function for each element in the array until the callbackfn returns true, or until
|
||||
* the end of the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
some(callbackfn: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): boolean;
|
||||
|
||||
/**
|
||||
* Sorts the array.
|
||||
* @param compareFn The function used to determine the order of the elements. If omitted, the elements are sorted in ascending order.
|
||||
*/
|
||||
sort(compareFn?: (a: bigint, b: bigint) => number | bigint): this;
|
||||
|
||||
/**
|
||||
* Gets a new BigUint64Array view of the ArrayBuffer store for this array, referencing the elements
|
||||
* at begin, inclusive, up to end, exclusive.
|
||||
* @param begin The index of the beginning of the array.
|
||||
* @param end The index of the end of the array.
|
||||
*/
|
||||
subarray(begin: number, end?: number): BigUint64Array;
|
||||
|
||||
/** Converts the array to a string by using the current locale. */
|
||||
toLocaleString(): string;
|
||||
|
||||
/** Returns a string representation of the array. */
|
||||
toString(): string;
|
||||
|
||||
/** Yields each value in the array. */
|
||||
values(): IterableIterator<bigint>;
|
||||
|
||||
[Symbol.iterator](): IterableIterator<bigint>;
|
||||
|
||||
readonly [Symbol.toStringTag]: "BigUint64Array";
|
||||
|
||||
[index: number]: bigint;
|
||||
}
|
||||
|
||||
interface BigUint64ArrayConstructor {
|
||||
readonly prototype: BigUint64Array;
|
||||
new(length?: number): BigUint64Array;
|
||||
new(array: Iterable<bigint>): BigUint64Array;
|
||||
new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): BigUint64Array;
|
||||
|
||||
/** The size in bytes of each element in the array. */
|
||||
readonly BYTES_PER_ELEMENT: number;
|
||||
|
||||
/**
|
||||
* Returns a new array from a set of elements.
|
||||
* @param items A set of elements to include in the new array object.
|
||||
*/
|
||||
of(...items: bigint[]): BigUint64Array;
|
||||
|
||||
/**
|
||||
* Creates an array from an array-like or iterable object.
|
||||
* @param arrayLike An array-like or iterable object to convert to an array.
|
||||
* @param mapfn A mapping function to call on every element of the array.
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from(arrayLike: ArrayLike<bigint>): BigUint64Array;
|
||||
from<U>(arrayLike: ArrayLike<U>, mapfn: (v: U, k: number) => bigint, thisArg?: any): BigUint64Array;
|
||||
}
|
||||
|
||||
declare const BigUint64Array: BigUint64ArrayConstructor;
|
||||
|
||||
interface DataView {
|
||||
/**
|
||||
* Gets the BigInt64 value at the specified byte offset from the start of the view. There is
|
||||
* no alignment constraint; multi-byte values may be fetched from any offset.
|
||||
* @param byteOffset The place in the buffer at which the value should be retrieved.
|
||||
*/
|
||||
getBigInt64(byteOffset: number, littleEndian?: boolean): bigint;
|
||||
|
||||
/**
|
||||
* Gets the BigUint64 value at the specified byte offset from the start of the view. There is
|
||||
* no alignment constraint; multi-byte values may be fetched from any offset.
|
||||
* @param byteOffset The place in the buffer at which the value should be retrieved.
|
||||
*/
|
||||
getBigUint64(byteOffset: number, littleEndian?: boolean): bigint;
|
||||
|
||||
/**
|
||||
* Stores a BigInt64 value at the specified byte offset from the start of the view.
|
||||
* @param byteOffset The place in the buffer at which the value should be set.
|
||||
* @param value The value to set.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be written,
|
||||
* otherwise a little-endian value should be written.
|
||||
*/
|
||||
setBigInt64(byteOffset: number, value: bigint, littleEndian?: boolean): void;
|
||||
|
||||
/**
|
||||
* Stores a BigUint64 value at the specified byte offset from the start of the view.
|
||||
* @param byteOffset The place in the buffer at which the value should be set.
|
||||
* @param value The value to set.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be written,
|
||||
* otherwise a little-endian value should be written.
|
||||
*/
|
||||
setBigUint64(byteOffset: number, value: bigint, littleEndian?: boolean): void;
|
||||
}
|
||||
Vendored
+1
@@ -21,5 +21,6 @@ and limitations under the License.
|
||||
/// <reference lib="es2018" />
|
||||
/// <reference lib="esnext.asynciterable" />
|
||||
/// <reference lib="esnext.array" />
|
||||
/// <reference lib="esnext.bigint" />
|
||||
/// <reference lib="esnext.symbol" />
|
||||
/// <reference lib="esnext.intl" />
|
||||
|
||||
Vendored
+1763
-94
File diff suppressed because it is too large
Load Diff
Vendored
+93
-9
@@ -61,7 +61,8 @@ declare namespace ts.server.protocol {
|
||||
GetApplicableRefactors = "getApplicableRefactors",
|
||||
GetEditsForRefactor = "getEditsForRefactor",
|
||||
OrganizeImports = "organizeImports",
|
||||
GetEditsForFileRename = "getEditsForFileRename"
|
||||
GetEditsForFileRename = "getEditsForFileRename",
|
||||
ConfigurePlugin = "configurePlugin"
|
||||
}
|
||||
/**
|
||||
* A TypeScript Server message
|
||||
@@ -136,6 +137,10 @@ declare namespace ts.server.protocol {
|
||||
* Contains message body if success === true.
|
||||
*/
|
||||
body?: any;
|
||||
/**
|
||||
* Contains extra information that plugin can include to be passed on
|
||||
*/
|
||||
metadata?: unknown;
|
||||
}
|
||||
/**
|
||||
* Arguments for FileRequest messages.
|
||||
@@ -519,7 +524,7 @@ declare namespace ts.server.protocol {
|
||||
/**
|
||||
* Errorcodes we want to get the fixes for.
|
||||
*/
|
||||
errorCodes?: ReadonlyArray<number>;
|
||||
errorCodes: ReadonlyArray<number>;
|
||||
}
|
||||
interface GetCombinedCodeFixRequestArgs {
|
||||
scope: GetCombinedCodeFixScope;
|
||||
@@ -591,6 +596,12 @@ declare namespace ts.server.protocol {
|
||||
interface DefinitionRequest extends FileLocationRequest {
|
||||
command: CommandTypes.Definition;
|
||||
}
|
||||
interface DefinitionAndBoundSpanRequest extends FileLocationRequest {
|
||||
readonly command: CommandTypes.DefinitionAndBoundSpan;
|
||||
}
|
||||
interface DefinitionAndBoundSpanResponse extends Response {
|
||||
readonly body: DefinitionInfoAndBoundSpan;
|
||||
}
|
||||
/**
|
||||
* Go to type request; value of command field is
|
||||
* "typeDefinition". Return response giving the file locations that
|
||||
@@ -775,7 +786,7 @@ declare namespace ts.server.protocol {
|
||||
/**
|
||||
* The file locations referencing the symbol.
|
||||
*/
|
||||
refs: ReferencesResponseItem[];
|
||||
refs: ReadonlyArray<ReferencesResponseItem>;
|
||||
/**
|
||||
* The name of the symbol.
|
||||
*/
|
||||
@@ -821,15 +832,17 @@ declare namespace ts.server.protocol {
|
||||
/**
|
||||
* Information about the item to be renamed.
|
||||
*/
|
||||
interface RenameInfo {
|
||||
type RenameInfo = RenameInfoSuccess | RenameInfoFailure;
|
||||
interface RenameInfoSuccess {
|
||||
/**
|
||||
* True if item can be renamed.
|
||||
*/
|
||||
canRename: boolean;
|
||||
canRename: true;
|
||||
/**
|
||||
* Error message if item can not be renamed.
|
||||
* File or directory to rename.
|
||||
* If set, `getEditsForFileRename` should be called instead of `findRenameLocations`.
|
||||
*/
|
||||
localizedErrorMessage?: string;
|
||||
fileToRename?: string;
|
||||
/**
|
||||
* Display name of the item to be renamed.
|
||||
*/
|
||||
@@ -846,6 +859,15 @@ declare namespace ts.server.protocol {
|
||||
* Optional modifiers for the kind (such as 'public').
|
||||
*/
|
||||
kindModifiers: string;
|
||||
/** Span of text to rename. */
|
||||
triggerSpan: TextSpan;
|
||||
}
|
||||
interface RenameInfoFailure {
|
||||
canRename: false;
|
||||
/**
|
||||
* Error message if item can not be renamed.
|
||||
*/
|
||||
localizedErrorMessage: string;
|
||||
}
|
||||
/**
|
||||
* A group of text spans, all in 'file'.
|
||||
@@ -854,7 +876,11 @@ declare namespace ts.server.protocol {
|
||||
/** The file to which the spans apply */
|
||||
file: string;
|
||||
/** The text spans in this group */
|
||||
locs: TextSpan[];
|
||||
locs: RenameTextSpan[];
|
||||
}
|
||||
interface RenameTextSpan extends TextSpan {
|
||||
readonly prefixText?: string;
|
||||
readonly suffixText?: string;
|
||||
}
|
||||
interface RenameResponseBody {
|
||||
/**
|
||||
@@ -989,6 +1015,14 @@ declare namespace ts.server.protocol {
|
||||
*/
|
||||
interface ConfigureResponse extends Response {
|
||||
}
|
||||
interface ConfigurePluginRequestArguments {
|
||||
pluginName: string;
|
||||
configuration: any;
|
||||
}
|
||||
interface ConfigurePluginRequest extends Request {
|
||||
command: CommandTypes.ConfigurePlugin;
|
||||
arguments: ConfigurePluginRequestArguments;
|
||||
}
|
||||
/**
|
||||
* Information found in an "open" request.
|
||||
*/
|
||||
@@ -1367,7 +1401,7 @@ declare namespace ts.server.protocol {
|
||||
* begin with prefix.
|
||||
*/
|
||||
interface CompletionsRequest extends FileLocationRequest {
|
||||
command: CommandTypes.Completions;
|
||||
command: CommandTypes.Completions | CommandTypes.CompletionInfo;
|
||||
arguments: CompletionsRequestArgs;
|
||||
}
|
||||
/**
|
||||
@@ -1826,6 +1860,7 @@ declare namespace ts.server.protocol {
|
||||
*/
|
||||
interface DiagnosticEvent extends Event {
|
||||
body?: DiagnosticEventBody;
|
||||
event: DiagnosticEventKind;
|
||||
}
|
||||
interface ConfigFileDiagnosticEventBody {
|
||||
/**
|
||||
@@ -1879,6 +1914,54 @@ declare namespace ts.server.protocol {
|
||||
*/
|
||||
openFiles: string[];
|
||||
}
|
||||
type ProjectLoadingStartEventName = "projectLoadingStart";
|
||||
interface ProjectLoadingStartEvent extends Event {
|
||||
event: ProjectLoadingStartEventName;
|
||||
body: ProjectLoadingStartEventBody;
|
||||
}
|
||||
interface ProjectLoadingStartEventBody {
|
||||
/** name of the project */
|
||||
projectName: string;
|
||||
/** reason for loading */
|
||||
reason: string;
|
||||
}
|
||||
type ProjectLoadingFinishEventName = "projectLoadingFinish";
|
||||
interface ProjectLoadingFinishEvent extends Event {
|
||||
event: ProjectLoadingFinishEventName;
|
||||
body: ProjectLoadingFinishEventBody;
|
||||
}
|
||||
interface ProjectLoadingFinishEventBody {
|
||||
/** name of the project */
|
||||
projectName: string;
|
||||
}
|
||||
type SurveyReadyEventName = "surveyReady";
|
||||
interface SurveyReadyEvent extends Event {
|
||||
event: SurveyReadyEventName;
|
||||
body: SurveyReadyEventBody;
|
||||
}
|
||||
interface SurveyReadyEventBody {
|
||||
/** Name of the survey. This is an internal machine- and programmer-friendly name */
|
||||
surveyId: string;
|
||||
}
|
||||
type LargeFileReferencedEventName = "largeFileReferenced";
|
||||
interface LargeFileReferencedEvent extends Event {
|
||||
event: LargeFileReferencedEventName;
|
||||
body: LargeFileReferencedEventBody;
|
||||
}
|
||||
interface LargeFileReferencedEventBody {
|
||||
/**
|
||||
* name of the large file being loaded
|
||||
*/
|
||||
file: string;
|
||||
/**
|
||||
* size of the file
|
||||
*/
|
||||
fileSize: number;
|
||||
/**
|
||||
* max file size allowed on the server
|
||||
*/
|
||||
maxFileSize: number;
|
||||
}
|
||||
/**
|
||||
* Arguments for reload request.
|
||||
*/
|
||||
@@ -2195,6 +2278,7 @@ declare namespace ts.server.protocol {
|
||||
readonly includeCompletionsWithInsertText?: boolean;
|
||||
readonly importModuleSpecifierPreference?: "relative" | "non-relative";
|
||||
readonly allowTextChangesInNewFiles?: boolean;
|
||||
readonly lazyConfiguredProjectsFromExternalProject?: boolean;
|
||||
}
|
||||
interface CompilerOptions {
|
||||
allowJs?: boolean;
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
"A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged_2434": "Uma declaração de namespace não pode estar localizada antes de uma classe ou função com a qual ela é mesclada.",
|
||||
"A_namespace_declaration_is_only_allowed_in_a_namespace_or_module_1235": "Uma declaração de namespace só é permitida e um namespace ou módulo.",
|
||||
"A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_7038": "Uma importação de estilo do namespace não pode ser chamada nem construída e causará uma falha no tempo de execução.",
|
||||
"A_non_dry_build_would_build_project_0_6357": "Um build não -dry compilaria o projeto '{0}'",
|
||||
"A_non_dry_build_would_build_project_0_6357": "Um build não -dry criaria o projeto '{0}'",
|
||||
"A_non_dry_build_would_delete_the_following_files_Colon_0_6356": "Um build não -dry excluiria os seguintes arquivos: {0}",
|
||||
"A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation_2371": "Um inicializador de parâmetro só é permitido em uma implementação de função ou de construtor.",
|
||||
"A_parameter_property_cannot_be_declared_using_a_rest_parameter_1317": "Uma propriedade de parâmetro não pode ser declarada usando um parâmetro rest.",
|
||||
@@ -61,7 +61,7 @@
|
||||
"A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly_1330": "Uma propriedade de uma interface ou tipo literal cujo tipo é um tipo de 'unique symbol' deve ser 'readonly'.",
|
||||
"A_required_parameter_cannot_follow_an_optional_parameter_1016": "Um parâmetro obrigatório não pode seguir um parâmetro opcional.",
|
||||
"A_rest_element_cannot_contain_a_binding_pattern_2501": "Um elemento rest não pode conter um padrão de associação.",
|
||||
"A_rest_element_cannot_have_a_property_name_2566": "Um elemento restante não pode ter um nome de propriedade.",
|
||||
"A_rest_element_cannot_have_a_property_name_2566": "Um elemento rest não pode ter um nome de propriedade.",
|
||||
"A_rest_element_cannot_have_an_initializer_1186": "Um elemento rest não pode ter um inicializador.",
|
||||
"A_rest_element_must_be_last_in_a_destructuring_pattern_2462": "Um elemento rest deve ser o último em um padrão de desestruturação.",
|
||||
"A_rest_parameter_cannot_be_optional_1047": "Um parâmetro rest não pode ser opcional.",
|
||||
@@ -174,7 +174,7 @@
|
||||
"An_object_member_cannot_be_declared_optional_1162": "Um membro de objeto não pode ser declarado como opcional.",
|
||||
"An_overload_signature_cannot_be_declared_as_a_generator_1222": "A assinatura de sobrecarga não pode ser declarada como geradora.",
|
||||
"An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_ex_17006": "Uma expressão unária com o operador '{0}' não é permitida no lado esquerdo de uma expressão de exponenciação. Considere delimitar a expressão em parênteses.",
|
||||
"Annotate_everything_with_types_from_JSDoc_95043": "Anotar tudo com tipos de JSDoc",
|
||||
"Annotate_everything_with_types_from_JSDoc_95043": "Anotar tudo com tipos do JSDoc",
|
||||
"Annotate_with_type_from_JSDoc_95009": "Anotar com o tipo do JSDoc",
|
||||
"Annotate_with_types_from_JSDoc_95010": "Anotar com os tipos do JSDoc",
|
||||
"Argument_expression_expected_1135": "Expressão de argumento esperada.",
|
||||
@@ -368,7 +368,7 @@
|
||||
"Enables_experimental_support_for_ES7_decorators_6065": "Habilita o suporte experimental para decoradores ES7.",
|
||||
"Enables_experimental_support_for_emitting_type_metadata_for_decorators_6066": "Habilita o suporte experimental para a emissão de tipo de metadados para decoradores.",
|
||||
"Enum_0_used_before_its_declaration_2450": "A enumeração '{0}' usada antes de sua declaração.",
|
||||
"Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations_2567": "As declarações de enum apenas podem se mescladas com namespaces ou com outras declarações de enum.",
|
||||
"Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations_2567": "As declarações enum só podem ser mescladas com namespaces ou com outras declarações enum.",
|
||||
"Enum_declarations_must_all_be_const_or_non_const_2473": "Declarações de enumeração devem ser const ou não const.",
|
||||
"Enum_member_expected_1132": "Membro de enumeração esperado.",
|
||||
"Enum_member_must_have_initializer_1061": "O membro de enumeração deve ter um inicializador.",
|
||||
@@ -571,7 +571,7 @@
|
||||
"Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambig_2308": "O módulo {0} já exportou um membro denominado '{1}'. Considere reexportar explicitamente para resolver a ambiguidade.",
|
||||
"Module_0_has_no_default_export_1192": "O módulo '{0}' não tem padrão de exportação.",
|
||||
"Module_0_has_no_exported_member_1_2305": "O módulo '{0}' não tem nenhum membro exportado '{1}'.",
|
||||
"Module_0_has_no_exported_member_1_Did_you_mean_2_2724": "O módulo '{0}' não tem nenhum membro exportado '{1}'. Você quis dizer '{2}'?",
|
||||
"Module_0_has_no_exported_member_1_Did_you_mean_2_2724": "O módulo '{0}' não tem nenhum membro '{1}' exportado. Você quis dizer '{2}'?",
|
||||
"Module_0_is_hidden_by_a_local_declaration_with_the_same_name_2437": "O módulo '{0}' está oculto por uma declaração de local com o mesmo nome.",
|
||||
"Module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct_2497": "O módulo '{0}' resolve para uma entidade sem módulo e não pode ser importado usando este constructo.",
|
||||
"Module_0_uses_export_and_cannot_be_used_with_export_Asterisk_2498": "O módulo '{0}' usa 'export =' e não pode ser usado com 'export *'.",
|
||||
@@ -622,7 +622,7 @@
|
||||
"Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided_5051": "A opção '{0} só pode ser usada quando qualquer uma das opções '--inlineSourceMap' ou '--sourceMap' é fornecida.",
|
||||
"Option_0_cannot_be_specified_with_option_1_5053": "A opção '{0}' não pode ser especificada com a opção '{1}'.",
|
||||
"Option_0_cannot_be_specified_without_specifying_option_1_5052": "A opção '{0}' não pode ser especificada sem especificar a opção '{1}'.",
|
||||
"Option_0_cannot_be_specified_without_specifying_option_1_or_option_2_5069": "A opção '{0}' não pode ser especificada sem especificar a opção '{1}' ou a opção '{2}'.",
|
||||
"Option_0_cannot_be_specified_without_specifying_option_1_or_option_2_5069": "A opção '{0}' não pode ser especificada sem a especificação da opção '{1}' ou '{2}'.",
|
||||
"Option_0_should_have_array_of_strings_as_a_value_6103": "A opção '{0}' deve ter matriz de cadeias de um valor.",
|
||||
"Option_build_must_be_the_first_command_line_argument_6369": "A opção '--build' precisa ser o primeiro argumento da linha de comando.",
|
||||
"Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES_5047": "A opção 'isolatedModules' só pode ser usada quando nenhuma opção de '--module' for fornecida ou a opção 'target' for 'ES2015' ou superior.",
|
||||
@@ -686,7 +686,7 @@
|
||||
"Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies_6354": "O projeto '{0}' está atualizado com os arquivos .d.ts de suas dependências",
|
||||
"Project_references_may_not_form_a_circular_graph_Cycle_detected_Colon_0_6202": "Referências de projeto não podem formar um gráfico circular. Ciclo detectado: {0}",
|
||||
"Projects_in_this_build_Colon_0_6355": "Projetos neste build: {0}",
|
||||
"Projects_to_reference_6300": "Projetos para referência",
|
||||
"Projects_to_reference_6300": "Projetos a serem referenciados",
|
||||
"Property_0_does_not_exist_on_const_enum_1_2479": "A propriedade '{0}' não existe na enumeração 'const' '{1}'.",
|
||||
"Property_0_does_not_exist_on_type_1_2339": "A propriedade '{0}' não existe no tipo '{1}'.",
|
||||
"Property_0_does_not_exist_on_type_1_Did_you_forget_to_use_await_2570": "A propriedade '{0}' não existe no tipo '{1}'. Você esqueceu de usar 'await'?",
|
||||
@@ -740,7 +740,7 @@
|
||||
"Remove_braces_from_arrow_function_95060": "Remover chaves da função de seta",
|
||||
"Remove_declaration_for_Colon_0_90004": "Remover declaração para: '{0}'",
|
||||
"Remove_destructuring_90009": "Remover desestruturação",
|
||||
"Remove_import_from_0_90005": "Remover importação do '{0}'",
|
||||
"Remove_import_from_0_90005": "Remover importação de '{0}'",
|
||||
"Remove_unreachable_code_95050": "Remover código inacessível",
|
||||
"Remove_unused_label_95053": "Remover rótulo não utilizado",
|
||||
"Remove_variable_statement_90010": "Remover instrução de variável",
|
||||
@@ -752,7 +752,7 @@
|
||||
"Report_errors_on_unused_parameters_6135": "Relatar erros nos parâmetros não utilizados.",
|
||||
"Required_type_parameters_may_not_follow_optional_type_parameters_2706": "Os parâmetros de tipo necessários podem não seguir os parâmetros de tipo opcionais.",
|
||||
"Resolution_for_module_0_was_found_in_cache_from_location_1_6147": "A resolução para o módulo '{0}' foi encontrada no cache do local '{1}'.",
|
||||
"Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195": "Resolva 'keyof' para nomes de propriedades com valores de cadeia de caracteres somente (sem números ou símbolos).",
|
||||
"Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195": "Resolva 'keyof' somente para nomes de propriedades com valores de cadeia de caracteres (sem números nem símbolos).",
|
||||
"Resolving_from_node_modules_folder_6118": "Resolvendo na pasta node_modules...",
|
||||
"Resolving_module_0_from_1_6086": "======== Resolvendo módulo '{0}' de '{1}'. ========",
|
||||
"Resolving_module_name_0_relative_to_base_url_1_2_6094": "Resolvendo nome de módulo '{0}' relativo à URL base '{1}' - '{2}'.",
|
||||
@@ -803,8 +803,8 @@
|
||||
"Show_what_would_be_built_or_deleted_if_specified_with_clean_6367": "Mostrar o que seria compilado (ou excluído, se especificado com '--clean')",
|
||||
"Signature_0_must_be_a_type_predicate_1224": "A assinatura '{0}' deve ser um predicado de tipo.",
|
||||
"Skip_type_checking_of_declaration_files_6012": "Ignorar a verificação de tipo dos arquivos de declaração.",
|
||||
"Skipping_build_of_project_0_because_its_dependency_1_has_errors_6362": "Ignorando build do projeto '{0}' porque sua dependência '{1}' tem erros",
|
||||
"Skipping_clean_because_not_all_projects_could_be_located_6371": "Ignorando a limpeza porque nem todos os projetos foram localizados",
|
||||
"Skipping_build_of_project_0_because_its_dependency_1_has_errors_6362": "Ignorando o build do projeto '{0}' porque a dependência '{1}' tem erros",
|
||||
"Skipping_clean_because_not_all_projects_could_be_located_6371": "Ignorando a limpeza porque não foram localizados todos os projetos",
|
||||
"Source_Map_Options_6175": "Opções do Sourcemap",
|
||||
"Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature_2382": "A assinatura de sobrecarga especializada não pode ser atribuída a qualquer assinatura não especializada.",
|
||||
"Specifier_of_dynamic_import_cannot_be_spread_element_1325": "O especificador de importação dinâmica não pode ser o elemento de difusão.",
|
||||
@@ -966,7 +966,7 @@
|
||||
"Unexpected_end_of_text_1126": "Fim inesperado do texto.",
|
||||
"Unexpected_token_1012": "Token inesperado.",
|
||||
"Unexpected_token_A_constructor_method_accessor_or_property_was_expected_1068": "Token inesperado. Um construtor, método, acessador ou propriedade era esperado.",
|
||||
"Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces_1069": "Token inesperado. Um nome de parâmetro de tipo era esperado sem chaves.",
|
||||
"Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces_1069": "Token inesperado. Era esperado um nome de parâmetro de tipo sem chaves.",
|
||||
"Unexpected_token_expected_1179": "Token inesperado. '{' esperado.",
|
||||
"Unknown_compiler_option_0_5023": "Opção do compilador '{0}' desconhecida.",
|
||||
"Unknown_option_excludes_Did_you_mean_exclude_6114": "Opção desconhecida 'excludes'. Você quis dizer 'exclude'?",
|
||||
@@ -993,7 +993,7 @@
|
||||
"Variable_declaration_list_cannot_be_empty_1123": "A lista de declaração de variável não pode estar vazia.",
|
||||
"Version_0_6029": "Versão {0}",
|
||||
"Watch_input_files_6005": "Observe os arquivos de entrada.",
|
||||
"Whether_to_keep_outdated_console_output_in_watch_mode_instead_of_clearing_the_screen_6191": "Se se deve manter a saída de console desatualizada no modo de inspeção, em vez de limpar a tela.",
|
||||
"Whether_to_keep_outdated_console_output_in_watch_mode_instead_of_clearing_the_screen_6191": "Se é necessário manter a saída de console desatualizada no modo de inspeção, em vez de limpar a tela.",
|
||||
"You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library_8001": "Não é possível renomear elementos que são definidos na biblioteca TypeScript padrão.",
|
||||
"You_cannot_rename_this_element_8000": "Você não pode renomear este elemento.",
|
||||
"_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write__1329": "'{0}' aceita muito poucos argumentos para serem usados como um decorador aqui. Você quis dizer para chamá-lo primeiro e gravar '@{0}()'?",
|
||||
|
||||
@@ -49,8 +49,8 @@
|
||||
"A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged_2434": "Bir ad alanı bildirimi, birleştirildiği sınıf veya işlevden önce gelemez.",
|
||||
"A_namespace_declaration_is_only_allowed_in_a_namespace_or_module_1235": "Ad alanı bildirimine yalnızca bir ad alanında veya modülde izin verilir.",
|
||||
"A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_7038": "Bir ad alanı stili içeri aktarma işlemi çağrılamadığından veya oluşturulamadığından çalışma zamanında hataya yol açacak.",
|
||||
"A_non_dry_build_would_build_project_0_6357": "non-dry bir derleme '{0}' projesini derler",
|
||||
"A_non_dry_build_would_delete_the_following_files_Colon_0_6356": "non-dry bir derleme şu dosyaları siler: {0}",
|
||||
"A_non_dry_build_would_build_project_0_6357": "-dry bayrağı kullanılmayan bir derleme '{0}' projesini derler",
|
||||
"A_non_dry_build_would_delete_the_following_files_Colon_0_6356": "-dry bayrağı kullanılmayan bir derleme şu dosyaları siler: {0}",
|
||||
"A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation_2371": "Parametre başlatıcısına yalnızca bir işlevde veya oluşturucu uygulamasında izin verilir.",
|
||||
"A_parameter_property_cannot_be_declared_using_a_rest_parameter_1317": "Parametre özelliği, rest parametresi kullanılarak bildirilemez.",
|
||||
"A_parameter_property_is_only_allowed_in_a_constructor_implementation_2369": "Parametre özelliğine yalnızca bir oluşturucu uygulamasında izin verilir.",
|
||||
@@ -110,7 +110,7 @@
|
||||
"Add_initializers_to_all_uninitialized_properties_95027": "Tüm başlatılmamış özelliklere başlatıcılar ekle",
|
||||
"Add_missing_super_call_90001": "Eksik 'super()' çağrısını ekle",
|
||||
"Add_missing_typeof_95052": "Eksik 'typeof' öğesini ekle",
|
||||
"Add_or_remove_braces_in_an_arrow_function_95058": "Ok işlevine küme ayracı ekleyin veya kaldırın",
|
||||
"Add_or_remove_braces_in_an_arrow_function_95058": "Ok işlevine küme ayracı ekle veya kaldır",
|
||||
"Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037": "Bir üye adıyla eşleşen tüm çözülmemiş değişkenlere niteleyici ekle",
|
||||
"Add_to_all_uncalled_decorators_95044": "Çağrılmayan tüm dekoratörlere '()' ekle",
|
||||
"Add_ts_ignore_to_all_error_messages_95042": "Tüm hata iletilerine '@ts-ignore' ekle",
|
||||
@@ -122,7 +122,7 @@
|
||||
"All_declarations_of_0_must_have_identical_modifiers_2687": "Tüm '{0}' bildirimleri aynı değiştiricilere sahip olmalıdır.",
|
||||
"All_declarations_of_0_must_have_identical_type_parameters_2428": "Tüm '{0}' bildirimleri özdeş tür parametrelerine sahip olmalıdır.",
|
||||
"All_declarations_of_an_abstract_method_must_be_consecutive_2516": "Soyut metoda ait tüm bildirimler ardışık olmalıdır.",
|
||||
"All_destructured_elements_are_unused_6198": "Yok edilen öğelerin hiçbiri kullanılmamış.",
|
||||
"All_destructured_elements_are_unused_6198": "Yapısı bozulan öğelerin hiçbiri kullanılmıyor.",
|
||||
"All_imports_in_import_declaration_are_unused_6192": "İçeri aktarma bildirimindeki hiçbir içeri aktarma kullanılmadı.",
|
||||
"All_variables_are_unused_6199": "Hiçbir değişken kullanılmıyor.",
|
||||
"Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011": "Varsayılan dışarı aktarmaya sahip olmayan modüllerde varsayılan içeri aktarmalara izin verin. Bu işlem kod üretimini etkilemez, yalnızca tür denetimini etkiler.",
|
||||
@@ -232,7 +232,7 @@
|
||||
"Cannot_invoke_an_object_which_is_possibly_null_2721": "Muhtemelen 'null' olan bir nesne çağrılamıyor.",
|
||||
"Cannot_invoke_an_object_which_is_possibly_null_or_undefined_2723": "Muhtemelen 'null' veya 'undefined' olan bir nesne çağrılamıyor.",
|
||||
"Cannot_invoke_an_object_which_is_possibly_undefined_2722": "Muhtemelen 'undefined' olan bir nesne çağrılamıyor.",
|
||||
"Cannot_prepend_project_0_because_it_does_not_have_outFile_set_6308": "'{0}' projesi, 'outFile' kümesi içermediğinden başa eklenemiyor",
|
||||
"Cannot_prepend_project_0_because_it_does_not_have_outFile_set_6308": "{0}' projesi için 'outFile' ayarlanmadığından başa eklenemiyor",
|
||||
"Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided_1205": "'--isolatedModules' bayrağı sağlandığında bir tür yeniden dışarı aktarılamaz.",
|
||||
"Cannot_read_file_0_Colon_1_5012": "'{0}' dosyası okunamıyor: {1}.",
|
||||
"Cannot_redeclare_block_scoped_variable_0_2451": "Blok kapsamlı değişken '{0}', yeniden bildirilemiyor.",
|
||||
@@ -311,7 +311,7 @@
|
||||
"Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name_1207": "Dekoratörler aynı ada sahip birden fazla get/set erişimcisine uygulanamaz.",
|
||||
"Default_export_of_the_module_has_or_is_using_private_name_0_4082": "Modülün varsayılan dışarı aktarımı '{0}' özel adına sahip veya bu adı kullanıyor.",
|
||||
"Delete_all_unused_declarations_95024": "Kullanılmayan tüm bildirimleri sil",
|
||||
"Delete_the_outputs_of_all_projects_6365": "Tüm projelerin çıkışlarını silin",
|
||||
"Delete_the_outputs_of_all_projects_6365": "Tüm projelerin çıkışlarını sil",
|
||||
"Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react__6084": "[Kullanım Dışı] Bunun yerine '--jsxFactory' kullanın. 'react' JSX gösterimi hedefleniyorsa, createElement için çağrılan nesneyi belirtin",
|
||||
"Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file_6170": "[Kullanım Dışı] Bunun yerine '--outFile' kullanın. Çıkışı tek bir dosya olarak birleştirin ve gösterin",
|
||||
"Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files_6160": "[Kullanım Dışı] Bunun yerine '--skipLibCheck' kullanın. Varsayılan kitaplık bildirim dosyalarının tür denetimini atlayın.",
|
||||
@@ -362,13 +362,13 @@
|
||||
"Enable_strict_checking_of_property_initialization_in_classes_6187": "Sınıflarda sıkı özellik başlatma denetimini etkinleştirin.",
|
||||
"Enable_strict_null_checks_6113": "Katı null denetimlerini etkinleştir.",
|
||||
"Enable_tracing_of_the_name_resolution_process_6085": "Ad çözümleme işlemini izlemeyi etkinleştir.",
|
||||
"Enable_verbose_logging_6366": "Ayrıntılı günlüğe yazmayı etkinleştirin",
|
||||
"Enable_verbose_logging_6366": "Ayrıntılı günlüğe yazmayı etkinleştir",
|
||||
"Enables_emit_interoperability_between_CommonJS_and_ES_Modules_via_creation_of_namespace_objects_for__7037": "Tüm içeri aktarma işlemleri için ad alanı nesnelerinin oluşturulması aracılığıyla CommonJS ile ES Modülleri arasında yayımlama birlikte çalışabilirliğine imkan tanır. Şu anlama gelir: 'allowSyntheticDefaultImports'.",
|
||||
"Enables_experimental_support_for_ES7_async_functions_6068": "Zaman uyumsuz ES7 işlevleri için deneysel desteği etkinleştirir.",
|
||||
"Enables_experimental_support_for_ES7_decorators_6065": "ES7 dekoratörleri için deneysel desteği etkinleştirir.",
|
||||
"Enables_experimental_support_for_emitting_type_metadata_for_decorators_6066": "Dekoratörlere tür meta verisi gönderme için deneysel desteği etkinleştirir.",
|
||||
"Enum_0_used_before_its_declaration_2450": "'{0}' sabit listesi, bildiriminden önce kullanıldı.",
|
||||
"Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations_2567": "Enum bildirimleri yalnızca ad alanı veya diğer enum bildirimleri ile birleştirilebilir.",
|
||||
"Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations_2567": "Sabit listesi bildirimleri yalnızca ad alanı veya diğer sabit listesi bildirimleri ile birleştirilebilir.",
|
||||
"Enum_declarations_must_all_be_const_or_non_const_2473": "Sabit listesi bildirimlerinin tümü const veya const olmayan değerler olmalıdır.",
|
||||
"Enum_member_expected_1132": "Sabit listesi üyesi bekleniyor.",
|
||||
"Enum_member_must_have_initializer_1061": "Sabit listesi üyesi bir başlatıcıya sahip olmalıdır.",
|
||||
@@ -571,7 +571,7 @@
|
||||
"Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambig_2308": "{0} modülü, '{1}' adlı bir üyeyi zaten dışarı aktardı. Belirsizliği çözmek için açık olarak yeniden dışarı aktarmayı göz önünde bulundurun.",
|
||||
"Module_0_has_no_default_export_1192": "'{0}' modülü için varsayılan dışarı aktarma yok.",
|
||||
"Module_0_has_no_exported_member_1_2305": "'{0}' modülü, dışarı aktarılan '{1}' üyesine sahip değil.",
|
||||
"Module_0_has_no_exported_member_1_Did_you_mean_2_2724": "'{0}' modülünün dışa aktarılan '{1}' adlı bir üyesi yok. Şunu mu demek istediniz: '{2}'?",
|
||||
"Module_0_has_no_exported_member_1_Did_you_mean_2_2724": "{0}' modülünün dışarı aktarılan '{1}' adlı bir üyesi yok. Şunu mu demek istediniz: '{2}'?",
|
||||
"Module_0_is_hidden_by_a_local_declaration_with_the_same_name_2437": "'{0}' modülü, aynı ada sahip bir yerel bildirim tarafından gizleniyor.",
|
||||
"Module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct_2497": "'{0}' modülü, modül olmayan bir varlığa çözümleniyor ve bu oluşturma ile içeri aktarılamaz.",
|
||||
"Module_0_uses_export_and_cannot_be_used_with_export_Asterisk_2498": "'{0}' modülü 'export =' kullanıyor ve 'export *' ile birlikte kullanılamaz.",
|
||||
@@ -737,7 +737,7 @@
|
||||
"Referenced_project_0_must_have_setting_composite_Colon_true_6306": "Başvurulan proje '{0}' \"composite\": true ayarına sahip olmalıdır.",
|
||||
"Remove_all_unreachable_code_95051": "Tüm erişilemeyen kodları kaldır",
|
||||
"Remove_all_unused_labels_95054": "Kullanılmayan tüm etiketleri kaldır",
|
||||
"Remove_braces_from_arrow_function_95060": "Ok işlevinden köşeli ayraçları kaldırın",
|
||||
"Remove_braces_from_arrow_function_95060": "Ok işlevinden küme ayraçlarını kaldır",
|
||||
"Remove_declaration_for_Colon_0_90004": "'{0}' bildirimini kaldır",
|
||||
"Remove_destructuring_90009": "Yıkmayı kaldır",
|
||||
"Remove_import_from_0_90005": "'{0}' öğesinden içeri aktarmayı kaldır",
|
||||
|
||||
+17459
-13292
File diff suppressed because it is too large
Load Diff
+26740
-19895
File diff suppressed because it is too large
Load Diff
Vendored
+2279
-7677
File diff suppressed because it is too large
Load Diff
+31147
-21995
File diff suppressed because it is too large
Load Diff
Vendored
+719
-737
File diff suppressed because it is too large
Load Diff
+25645
-19356
File diff suppressed because it is too large
Load Diff
Vendored
+717
-736
File diff suppressed because it is too large
Load Diff
+25645
-19356
File diff suppressed because it is too large
Load Diff
+19327
-14893
File diff suppressed because it is too large
Load Diff
@@ -68,7 +68,7 @@
|
||||
"A_rest_parameter_cannot_have_an_initializer_1048": "rest 参数不能具有初始化表达式。",
|
||||
"A_rest_parameter_must_be_last_in_a_parameter_list_1014": "rest 参数必须是参数列表中的最后一个参数。",
|
||||
"A_rest_parameter_must_be_of_an_array_type_2370": "rest 参数必须是数组类型。",
|
||||
"A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma_1013": "Rest 参数或绑定模式可能不具有尾随逗号。",
|
||||
"A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma_1013": "Rest 参数或绑定模式不可带尾随逗号。",
|
||||
"A_return_statement_can_only_be_used_within_a_function_body_1108": "\"return\" 语句只能在函数体中使用。",
|
||||
"A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl_6167": "一系列条目,这些条目将重新映射导入内容,以查找与 \"baseUrl\" 有关的位置。",
|
||||
"A_set_accessor_cannot_have_a_return_type_annotation_1095": "\"set\" 访问器不能具有返回类型批注。",
|
||||
@@ -161,7 +161,7 @@
|
||||
"An_index_signature_parameter_cannot_have_an_accessibility_modifier_1018": "索引签名参数不能具有可访问性修饰符。",
|
||||
"An_index_signature_parameter_cannot_have_an_initializer_1020": "索引签名参数不能具有初始化表达式。",
|
||||
"An_index_signature_parameter_must_have_a_type_annotation_1022": "索引签名参数必须具有类型批注。",
|
||||
"An_index_signature_parameter_type_cannot_be_a_type_alias_Consider_writing_0_Colon_1_Colon_2_instead_1336": "索引签名参数类型不能为类型别名。请考虑改而编写“[{0}: {1}]:{2}”。",
|
||||
"An_index_signature_parameter_type_cannot_be_a_type_alias_Consider_writing_0_Colon_1_Colon_2_instead_1336": "索引签名参数类型不能为类型别名。请考虑改为编写“[{0}: {1}]:{2}”。",
|
||||
"An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead_1337": "索引签名参数类型不能为联合类型。请考虑改用映射的对象类型。",
|
||||
"An_index_signature_parameter_type_must_be_string_or_number_1023": "索引签名参数类型必须为 \"string\" 或 \"number\"。",
|
||||
"An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments_2499": "接口只能扩展具有可选类型参数的标识符/限定名称。",
|
||||
@@ -628,7 +628,7 @@
|
||||
"Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES_5047": "选项 \"isolatedModules\" 只可在提供了选项 \"--module\" 或者选项 \"target\" 是 \"ES2015\" 或更高版本时使用。",
|
||||
"Option_paths_cannot_be_used_without_specifying_baseUrl_option_5060": "在未指定 \"--baseUrl\" 选项的情况下,无法使用选项 \"paths\"。",
|
||||
"Option_project_cannot_be_mixed_with_source_files_on_a_command_line_5042": "选项 \"project\" 在命令行上不能与源文件混合使用。",
|
||||
"Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy_5070": "没有 \"node\" 模块解析策略的情况下,无法指定选项 \"-resolveJsonModule\"。",
|
||||
"Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy_5070": "在没有 \"node\" 模块解析策略的情况下,无法指定选项 \"-resolveJsonModule\"。",
|
||||
"Options_0_and_1_cannot_be_combined_6370": "选项“{0}”与“{1}”不能组合在一起。",
|
||||
"Options_Colon_6027": "选项:",
|
||||
"Output_directory_for_generated_declaration_files_6166": "已生成声明文件的输出目录。",
|
||||
|
||||
@@ -406,11 +406,11 @@
|
||||
"Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions_2521": "運算式會解析成變數宣告 '{0}',而編譯器會使用此宣告支援非同步函式。",
|
||||
"Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta__2544": "運算式將解析成變數宣告 '_newTarget',而供編譯器用來擷取 'new.target' 中繼屬性參考。",
|
||||
"Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference_2400": "運算式會解析成變數宣告 '_this',而編譯器會使用此宣告來擷取 'this' 參考 。",
|
||||
"Extract_constant_95006": "解壓縮常數",
|
||||
"Extract_function_95005": "解壓縮函式",
|
||||
"Extract_to_0_in_1_95004": "解壓縮至 {1} 中的 {0}",
|
||||
"Extract_to_0_in_1_scope_95008": "解壓縮至 {1} 範圍中的 {0}",
|
||||
"Extract_to_0_in_enclosing_scope_95007": "解壓縮至封閉式範圍中的 {0}",
|
||||
"Extract_constant_95006": "擷取常數",
|
||||
"Extract_function_95005": "擷取函式",
|
||||
"Extract_to_0_in_1_95004": "擷取至 {1} 中的 {0}",
|
||||
"Extract_to_0_in_1_scope_95008": "擷取至 {1} 範圍中的 {0}",
|
||||
"Extract_to_0_in_enclosing_scope_95007": "擷取至封閉式範圍中的 {0}",
|
||||
"FILE_6035": "檔案",
|
||||
"FILE_OR_DIRECTORY_6040": "檔案或目錄",
|
||||
"Failed_to_parse_file_0_Colon_1_5014": "無法剖析檔案 '{0}': {1}。",
|
||||
@@ -584,7 +584,7 @@
|
||||
"Module_name_0_was_successfully_resolved_to_1_6089": "======== 模組名稱 '{0}' 已成功解析為 '{1}'。========",
|
||||
"Module_resolution_kind_is_not_specified_using_0_6088": "未指定模組解析種類,將使用 '{0}'。",
|
||||
"Module_resolution_using_rootDirs_has_failed_6111": "使用 'rootDirs' 解析模組失敗。",
|
||||
"Move_to_a_new_file_95049": "移至新行",
|
||||
"Move_to_a_new_file_95049": "移至新檔",
|
||||
"Multiple_consecutive_numeric_separators_are_not_permitted_6189": "不允許多個連續的數字分隔符號。",
|
||||
"Multiple_constructor_implementations_are_not_allowed_2392": "不允許多個建構函式實作。",
|
||||
"NEWLINE_6061": "新行",
|
||||
|
||||
Generated
-6280
File diff suppressed because it is too large
Load Diff
+5
-2
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "typescript",
|
||||
"author": "Microsoft Corp.",
|
||||
"homepage": "http://typescriptlang.org/",
|
||||
"version": "3.1.0",
|
||||
"homepage": "https://www.typescriptlang.org/",
|
||||
"version": "3.3.0",
|
||||
"license": "Apache-2.0",
|
||||
"description": "TypeScript is a language for application scale JavaScript development",
|
||||
"keywords": [
|
||||
@@ -75,12 +75,15 @@
|
||||
"gulp-typescript": "latest",
|
||||
"istanbul": "latest",
|
||||
"jake": "latest",
|
||||
"lodash": "4.17.10",
|
||||
"merge2": "latest",
|
||||
"minimist": "latest",
|
||||
"mkdirp": "latest",
|
||||
"mocha": "latest",
|
||||
"mocha-fivemat-progress-reporter": "latest",
|
||||
"plugin-error": "latest",
|
||||
"pretty-hrtime": "^1.0.3",
|
||||
"prex": "^0.4.3",
|
||||
"q": "latest",
|
||||
"remove-internal": "^2.9.2",
|
||||
"run-sequence": "latest",
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
// @ts-check
|
||||
const symSource = Symbol("CancelToken.source");
|
||||
const symToken = Symbol("CancelSource.token");
|
||||
const symCancellationRequested = Symbol("CancelSource.cancellationRequested");
|
||||
const symCancellationCallbacks = Symbol("CancelSource.cancellationCallbacks");
|
||||
|
||||
class CancelSource {
|
||||
constructor() {
|
||||
this[symCancellationRequested] = false;
|
||||
this[symCancellationCallbacks] = [];
|
||||
}
|
||||
|
||||
/** @type {CancelToken} */
|
||||
get token() {
|
||||
return this[symToken] || (this[symToken] = new CancelToken(this));
|
||||
}
|
||||
|
||||
cancel() {
|
||||
if (!this[symCancellationRequested]) {
|
||||
this[symCancellationRequested] = true;
|
||||
for (const callback of this[symCancellationCallbacks]) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.CancelSource = CancelSource;
|
||||
|
||||
class CancelToken {
|
||||
/**
|
||||
* @param {CancelSource} source
|
||||
*/
|
||||
constructor(source) {
|
||||
if (source[symToken]) return source[symToken];
|
||||
this[symSource] = source;
|
||||
}
|
||||
|
||||
/** @type {boolean} */
|
||||
get cancellationRequested() {
|
||||
return this[symSource][symCancellationRequested];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {() => void} callback
|
||||
*/
|
||||
subscribe(callback) {
|
||||
const source = this[symSource];
|
||||
if (source[symCancellationRequested]) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
source[symCancellationCallbacks].push(callback);
|
||||
|
||||
return {
|
||||
unsubscribe() {
|
||||
const index = source[symCancellationCallbacks].indexOf(callback);
|
||||
if (index !== -1) source[symCancellationCallbacks].splice(index, 1);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.CancelToken = CancelToken;
|
||||
|
||||
class CancelError extends Error {
|
||||
constructor(message = "Operation was canceled") {
|
||||
super(message);
|
||||
this.name = "CancelError";
|
||||
}
|
||||
}
|
||||
exports.CancelError = CancelError;
|
||||
+17
-12
@@ -3,7 +3,7 @@ const cp = require("child_process");
|
||||
const log = require("fancy-log"); // was `require("gulp-util").log (see https://github.com/gulpjs/gulp-util)
|
||||
const isWin = /^win/.test(process.platform);
|
||||
const chalk = require("./chalk");
|
||||
const { CancelToken, CancelError } = require("./cancellation");
|
||||
const { CancellationToken, CancelError } = require("prex");
|
||||
|
||||
module.exports = exec;
|
||||
|
||||
@@ -15,31 +15,36 @@ module.exports = exec;
|
||||
*
|
||||
* @typedef ExecOptions
|
||||
* @property {boolean} [ignoreExitCode]
|
||||
* @property {CancelToken} [cancelToken]
|
||||
* @property {import("prex").CancellationToken} [cancelToken]
|
||||
*/
|
||||
function exec(cmd, args, options = {}) {
|
||||
return /**@type {Promise<{exitCode: number}>}*/(new Promise((resolve, reject) => {
|
||||
log(`> ${chalk.green(cmd)} ${args.join(" ")}`);
|
||||
const { ignoreExitCode, cancelToken = CancellationToken.none } = options;
|
||||
cancelToken.throwIfCancellationRequested();
|
||||
|
||||
// TODO (weswig): Update child_process types to add windowsVerbatimArguments to the type definition
|
||||
const subshellFlag = isWin ? "/c" : "-c";
|
||||
const command = isWin ? [possiblyQuote(cmd), ...args] : [`${cmd} ${args.join(" ")}`];
|
||||
const ex = cp.spawn(isWin ? "cmd" : "/bin/sh", [subshellFlag, ...command], { stdio: "inherit", windowsVerbatimArguments: true });
|
||||
const subscription = options.cancelToken && options.cancelToken.subscribe(() => {
|
||||
ex.kill("SIGINT");
|
||||
ex.kill("SIGTERM");
|
||||
|
||||
log(`> ${chalk.green(cmd)} ${args.join(" ")}`);
|
||||
const proc = cp.spawn(isWin ? "cmd" : "/bin/sh", [subshellFlag, ...command], { stdio: "inherit", windowsVerbatimArguments: true });
|
||||
const registration = cancelToken.register(() => {
|
||||
log(`${chalk.red("killing")} '${chalk.green(cmd)} ${args.join(" ")}'...`);
|
||||
proc.kill("SIGINT");
|
||||
proc.kill("SIGTERM");
|
||||
reject(new CancelError());
|
||||
});
|
||||
ex.on("exit", exitCode => {
|
||||
subscription && subscription.unsubscribe();
|
||||
if (exitCode === 0 || options.ignoreExitCode) {
|
||||
proc.on("exit", exitCode => {
|
||||
registration.unregister();
|
||||
if (exitCode === 0 || ignoreExitCode) {
|
||||
resolve({ exitCode });
|
||||
}
|
||||
else {
|
||||
reject(new Error(`Process exited with code: ${exitCode}`));
|
||||
}
|
||||
});
|
||||
ex.on("error", error => {
|
||||
subscription && subscription.unsubscribe();
|
||||
proc.on("error", error => {
|
||||
registration.unregister();
|
||||
reject(error);
|
||||
});
|
||||
}));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// @ts-check
|
||||
const path = require("path");
|
||||
const child_process = require("child_process");
|
||||
const fs = require("fs");
|
||||
const tsc = require("gulp-typescript");
|
||||
const Vinyl = require("vinyl");
|
||||
const { Duplex, Readable } = require("stream");
|
||||
@@ -42,7 +43,10 @@ function createProject(tsConfigFileName, settings, options) {
|
||||
getVinyl(path) { return inputs.get(path); },
|
||||
getSourceFile(fileName) { return sourceFiles.get(fileName); },
|
||||
createSourceFile(fileName, text, languageVersion) {
|
||||
if (text === undefined) throw new Error("File not cached.");
|
||||
if (text === undefined) {
|
||||
text = fs.readFileSync(fileName, "utf8");
|
||||
}
|
||||
|
||||
/** @type {protocol.SourceFile} */
|
||||
let file;
|
||||
if (options.parse) {
|
||||
|
||||
@@ -140,7 +140,7 @@ function diagnosticFromJson(json, host) {
|
||||
category: json.category,
|
||||
code: json.code,
|
||||
source: json.source,
|
||||
relatedInformation: json.relatedInformation && json.relatedInformation.map(diagnosticRelatedInformationFromJson, host)
|
||||
relatedInformation: json.relatedInformation && json.relatedInformation.map(json => diagnosticRelatedInformationFromJson(json, host))
|
||||
});
|
||||
}
|
||||
exports.diagnosticFromJson = diagnosticFromJson;
|
||||
@@ -169,7 +169,9 @@ function diagnosticRelatedInformationFromJson(json, host) {
|
||||
file: json.file && sourceFileFromJson(json.file, host),
|
||||
start: json.start,
|
||||
length: json.length,
|
||||
messageText: json.messageText
|
||||
messageText: json.messageText,
|
||||
category: json.category,
|
||||
code: json.code
|
||||
};
|
||||
}
|
||||
exports.diagnosticRelatedInformationFromJson = diagnosticRelatedInformationFromJson;
|
||||
|
||||
+65
-26
@@ -3,6 +3,8 @@ const path = require("path");
|
||||
const fs = require("fs");
|
||||
const gulp = require("./gulp");
|
||||
const gulpif = require("gulp-if");
|
||||
const log = require("fancy-log"); // was `require("gulp-util").log (see https://github.com/gulpjs/gulp-util)
|
||||
const chalk = require("./chalk");
|
||||
const sourcemaps = require("gulp-sourcemaps");
|
||||
const merge2 = require("merge2");
|
||||
const tsc = require("gulp-typescript");
|
||||
@@ -12,7 +14,12 @@ const ts = require("../../lib/typescript");
|
||||
const del = require("del");
|
||||
const needsUpdate = require("./needsUpdate");
|
||||
const mkdirp = require("./mkdirp");
|
||||
const prettyTime = require("pretty-hrtime");
|
||||
const { reportDiagnostics } = require("./diagnostics");
|
||||
const { CountdownEvent, ManualResetEvent } = require("prex");
|
||||
|
||||
const workStartedEvent = new ManualResetEvent();
|
||||
const countdown = new CountdownEvent(0);
|
||||
|
||||
class CompilationGulp extends gulp.Gulp {
|
||||
/**
|
||||
@@ -20,15 +27,39 @@ class CompilationGulp extends gulp.Gulp {
|
||||
*/
|
||||
fork(verbose) {
|
||||
const child = new ForkedGulp(this.tasks);
|
||||
if (verbose) {
|
||||
child.on("task_start", e => gulp.emit("task_start", e));
|
||||
child.on("task_stop", e => gulp.emit("task_stop", e));
|
||||
child.on("task_err", e => gulp.emit("task_err", e));
|
||||
child.on("task_not_found", e => gulp.emit("task_not_found", e));
|
||||
child.on("task_recursion", e => gulp.emit("task_recursion", e));
|
||||
}
|
||||
child.on("task_start", e => {
|
||||
if (countdown.remainingCount === 0) {
|
||||
countdown.reset(1);
|
||||
workStartedEvent.set();
|
||||
workStartedEvent.reset();
|
||||
}
|
||||
else {
|
||||
countdown.add();
|
||||
}
|
||||
if (verbose) {
|
||||
log('Starting', `'${chalk.cyan(e.task)}' ${chalk.gray(`(${countdown.remainingCount} remaining)`)}...`);
|
||||
}
|
||||
});
|
||||
child.on("task_stop", e => {
|
||||
countdown.signal();
|
||||
if (verbose) {
|
||||
log('Finished', `'${chalk.cyan(e.task)}' after ${chalk.magenta(prettyTime(/** @type {*}*/(e).hrDuration))} ${chalk.gray(`(${countdown.remainingCount} remaining)`)}`);
|
||||
}
|
||||
});
|
||||
child.on("task_err", e => {
|
||||
countdown.signal();
|
||||
if (verbose) {
|
||||
log(`'${chalk.cyan(e.task)}' ${chalk.red("errored after")} ${chalk.magenta(prettyTime(/** @type {*}*/(e).hrDuration))} ${chalk.gray(`(${countdown.remainingCount} remaining)`)}`);
|
||||
log(e.err ? e.err.stack : e.message);
|
||||
}
|
||||
});
|
||||
return child;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
start() {
|
||||
throw new Error("Not supported, use fork.");
|
||||
}
|
||||
}
|
||||
|
||||
class ForkedGulp extends gulp.Gulp {
|
||||
@@ -211,24 +242,26 @@ exports.flatten = flatten;
|
||||
|
||||
/**
|
||||
* Returns a Promise that resolves when all pending build tasks have completed
|
||||
* @param {import("prex").CancellationToken} [token]
|
||||
*/
|
||||
function wait() {
|
||||
return new Promise(resolve => {
|
||||
if (compilationGulp.allDone()) {
|
||||
resolve();
|
||||
}
|
||||
else {
|
||||
const onDone = () => {
|
||||
compilationGulp.removeListener("onDone", onDone);
|
||||
compilationGulp.removeListener("err", onDone);
|
||||
resolve();
|
||||
};
|
||||
compilationGulp.on("stop", onDone);
|
||||
compilationGulp.on("err", onDone);
|
||||
}
|
||||
});
|
||||
function waitForWorkToComplete(token) {
|
||||
return countdown.wait(token);
|
||||
}
|
||||
exports.wait = wait;
|
||||
exports.waitForWorkToComplete = waitForWorkToComplete;
|
||||
|
||||
/**
|
||||
* Returns a Promise that resolves when all pending build tasks have completed
|
||||
* @param {import("prex").CancellationToken} [token]
|
||||
*/
|
||||
function waitForWorkToStart(token) {
|
||||
return workStartedEvent.wait(token);
|
||||
}
|
||||
exports.waitForWorkToStart = waitForWorkToStart;
|
||||
|
||||
function getRemainingWork() {
|
||||
return countdown.remainingCount > 0;
|
||||
}
|
||||
exports.hasRemainingWork = getRemainingWork;
|
||||
|
||||
/**
|
||||
* Resolve a TypeScript specifier into a fully-qualified module specifier and any requisite dependencies.
|
||||
@@ -650,11 +683,17 @@ function ensureCompileTask(projectGraph, options) {
|
||||
}
|
||||
});
|
||||
}
|
||||
const js = (projectGraphConfig.resolvedOptions.js ? projectGraphConfig.resolvedOptions.js(stream.js) : stream.js)
|
||||
|
||||
const additionalJsOutputs = projectGraphConfig.resolvedOptions.js ? projectGraphConfig.resolvedOptions.js(stream.js)
|
||||
.pipe(gulpif(sourceMap || inlineSourceMap, sourcemaps.write(sourceMapPath, sourceMapOptions))) : undefined;
|
||||
const additionalDtsOutputs = projectGraphConfig.resolvedOptions.dts ? projectGraphConfig.resolvedOptions.dts(stream.dts)
|
||||
.pipe(gulpif(declarationMap, sourcemaps.write(sourceMapPath, sourceMapOptions))) : undefined;
|
||||
|
||||
const js = stream.js
|
||||
.pipe(gulpif(sourceMap || inlineSourceMap, sourcemaps.write(sourceMapPath, sourceMapOptions)));
|
||||
const dts = (projectGraphConfig.resolvedOptions.dts ? projectGraphConfig.resolvedOptions.dts(stream.dts) : stream.dts)
|
||||
const dts = stream.dts
|
||||
.pipe(gulpif(declarationMap, sourcemaps.write(sourceMapPath, sourceMapOptions)));
|
||||
return merge2([js, dts])
|
||||
return merge2([js, dts, additionalJsOutputs, additionalDtsOutputs].filter(x => !!x))
|
||||
.pipe(gulp.dest(destPath));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ const mkdirP = require("./mkdirp");
|
||||
const cmdLineOptions = require("./options");
|
||||
const exec = require("./exec");
|
||||
const log = require("fancy-log"); // was `require("gulp-util").log (see https://github.com/gulpjs/gulp-util)
|
||||
const { CancellationToken } = require("prex");
|
||||
const mochaJs = require.resolve("mocha/bin/_mocha");
|
||||
|
||||
exports.localBaseline = "tests/baselines/local/";
|
||||
@@ -21,9 +22,9 @@ exports.localTest262Baseline = "internal/baselines/test262/local";
|
||||
* @param {string} defaultReporter
|
||||
* @param {boolean} runInParallel
|
||||
* @param {boolean} watchMode
|
||||
* @param {InstanceType<typeof import("./cancellation").CancelToken>} [cancelToken]
|
||||
* @param {import("prex").CancellationToken} [cancelToken]
|
||||
*/
|
||||
async function runConsoleTests(runJs, defaultReporter, runInParallel, watchMode, cancelToken) {
|
||||
async function runConsoleTests(runJs, defaultReporter, runInParallel, watchMode, cancelToken = CancellationToken.none) {
|
||||
let testTimeout = cmdLineOptions.timeout;
|
||||
let tests = cmdLineOptions.tests;
|
||||
const lintFlag = cmdLineOptions.lint;
|
||||
@@ -37,6 +38,7 @@ async function runConsoleTests(runJs, defaultReporter, runInParallel, watchMode,
|
||||
const keepFailed = cmdLineOptions.keepFailed;
|
||||
if (!cmdLineOptions.dirty) {
|
||||
await cleanTestDirs();
|
||||
cancelToken.throwIfCancellationRequested();
|
||||
}
|
||||
|
||||
if (fs.existsSync(testConfigFile)) {
|
||||
|
||||
+312
-8
@@ -4,7 +4,7 @@ const fs = require("fs");
|
||||
const log = require("fancy-log"); // was `require("gulp-util").log (see https://github.com/gulpjs/gulp-util)
|
||||
const ts = require("../../lib/typescript");
|
||||
const { Duplex } = require("stream");
|
||||
const chalk = require("./chalk");
|
||||
const chalk = /**@type {*} */(require("chalk"));
|
||||
const Vinyl = require("vinyl");
|
||||
|
||||
/**
|
||||
@@ -14,7 +14,7 @@ const Vinyl = require("vinyl");
|
||||
* @param {UpToDateOptions} [options]
|
||||
*
|
||||
* @typedef UpToDateOptions
|
||||
* @property {boolean} [verbose]
|
||||
* @property {boolean | "minimal"} [verbose]
|
||||
* @property {(configFilePath: string) => ParsedCommandLine | undefined} [parseProject]
|
||||
*/
|
||||
function upToDate(parsedProject, options) {
|
||||
@@ -47,9 +47,9 @@ function upToDate(parsedProject, options) {
|
||||
cb();
|
||||
},
|
||||
final(cb) {
|
||||
const status = ts.getUpToDateStatus(upToDateHost, parsedProject);
|
||||
const status = getUpToDateStatus(upToDateHost, parsedProject);
|
||||
reportStatus(parsedProject, status, options);
|
||||
if (status.type !== ts.UpToDateStatusType.UpToDate) {
|
||||
if (status.type !== UpToDateStatusType.UpToDate) {
|
||||
for (const input of inputs) duplex.push(input);
|
||||
}
|
||||
duplex.push(null);
|
||||
@@ -88,11 +88,25 @@ function formatMessage(message, ...args) {
|
||||
/**
|
||||
* @param {ParsedCommandLine} project
|
||||
* @param {UpToDateStatus} status
|
||||
* @param {{verbose?: boolean}} options
|
||||
* @param {{verbose?: boolean | "minimal"}} options
|
||||
*/
|
||||
function reportStatus(project, status, options) {
|
||||
switch (options.verbose) {
|
||||
case "minimal":
|
||||
switch (status.type) {
|
||||
case UpToDateStatusType.UpToDate:
|
||||
log.info(`Project '${fileName(project.options.configFilePath)}' is up to date.`);
|
||||
break;
|
||||
default:
|
||||
log.info(`Project '${fileName(project.options.configFilePath)}' is out of date, rebuilding...`);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case true:
|
||||
/**@type {*}*/(ts).formatUpToDateStatus(project.options.configFilePath, status, fileName, formatMessage);
|
||||
break;
|
||||
}
|
||||
if (!options.verbose) return;
|
||||
ts.formatUpToDateStatus(project.options.configFilePath, status, fileName, formatMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,12 +134,302 @@ function formatStringFromArgs(text, args, baseIndex = 0) {
|
||||
return text.replace(/{(\d+)}/g, (_match, index) => args[+index + baseIndex]);
|
||||
}
|
||||
|
||||
const minimumDate = new Date(-8640000000000000);
|
||||
const maximumDate = new Date(8640000000000000);
|
||||
const missingFileModifiedTime = new Date(0);
|
||||
|
||||
/**
|
||||
* @typedef {0} UpToDateStatusType.Unbuildable
|
||||
* @typedef {1} UpToDateStatusType.UpToDate
|
||||
* @typedef {2} UpToDateStatusType.UpToDateWithUpstreamTypes
|
||||
* @typedef {3} UpToDateStatusType.OutputMissing
|
||||
* @typedef {4} UpToDateStatusType.OutOfDateWithSelf
|
||||
* @typedef {5} UpToDateStatusType.OutOfDateWithUpstream
|
||||
* @typedef {6} UpToDateStatusType.UpstreamOutOfDate
|
||||
* @typedef {7} UpToDateStatusType.UpstreamBlocked
|
||||
* @typedef {8} UpToDateStatusType.ComputingUpstream
|
||||
* @typedef {9} UpToDateStatusType.ContainerOnly
|
||||
* @enum {UpToDateStatusType.Unbuildable | UpToDateStatusType.UpToDate | UpToDateStatusType.UpToDateWithUpstreamTypes | UpToDateStatusType.OutputMissing | UpToDateStatusType.OutOfDateWithSelf | UpToDateStatusType.OutOfDateWithUpstream | UpToDateStatusType.UpstreamOutOfDate | UpToDateStatusType.UpstreamBlocked | UpToDateStatusType.ComputingUpstream | UpToDateStatusType.ContainerOnly}
|
||||
*/
|
||||
const UpToDateStatusType = {
|
||||
Unbuildable: /** @type {0} */(0),
|
||||
UpToDate: /** @type {1} */(1),
|
||||
UpToDateWithUpstreamTypes: /** @type {2} */(2),
|
||||
OutputMissing: /** @type {3} */(3),
|
||||
OutOfDateWithSelf: /** @type {4} */(4),
|
||||
OutOfDateWithUpstream: /** @type {5} */(5),
|
||||
UpstreamOutOfDate: /** @type {6} */(6),
|
||||
UpstreamBlocked: /** @type {7} */(7),
|
||||
ComputingUpstream: /** @type {8} */(8),
|
||||
ContainerOnly: /** @type {9} */(9),
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Date} date1
|
||||
* @param {Date} date2
|
||||
* @returns {Date}
|
||||
*/
|
||||
function newer(date1, date2) {
|
||||
return date2 > date1 ? date2 : date1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {UpToDateHost} host
|
||||
* @param {ParsedCommandLine | undefined} project
|
||||
* @returns {UpToDateStatus}
|
||||
*/
|
||||
function getUpToDateStatus(host, project) {
|
||||
if (project === undefined) return { type: UpToDateStatusType.Unbuildable, reason: "File deleted mid-build" };
|
||||
const prior = host.getLastStatus ? host.getLastStatus(project.options.configFilePath) : undefined;
|
||||
if (prior !== undefined) {
|
||||
return prior;
|
||||
}
|
||||
const actual = getUpToDateStatusWorker(host, project);
|
||||
if (host.setLastStatus) {
|
||||
host.setLastStatus(project.options.configFilePath, actual);
|
||||
}
|
||||
return actual;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {UpToDateHost} host
|
||||
* @param {ParsedCommandLine | undefined} project
|
||||
* @returns {UpToDateStatus}
|
||||
*/
|
||||
function getUpToDateStatusWorker(host, project) {
|
||||
/** @type {string} */
|
||||
let newestInputFileName = undefined;
|
||||
let newestInputFileTime = minimumDate;
|
||||
// Get timestamps of input files
|
||||
for (const inputFile of project.fileNames) {
|
||||
if (!host.fileExists(inputFile)) {
|
||||
return {
|
||||
type: UpToDateStatusType.Unbuildable,
|
||||
reason: `${inputFile} does not exist`
|
||||
};
|
||||
}
|
||||
|
||||
const inputTime = host.getModifiedTime(inputFile) || missingFileModifiedTime;
|
||||
if (inputTime > newestInputFileTime) {
|
||||
newestInputFileName = inputFile;
|
||||
newestInputFileTime = inputTime;
|
||||
}
|
||||
}
|
||||
|
||||
// Collect the expected outputs of this project
|
||||
const outputs = /**@type {string[]}*/(/**@type {*}*/(ts).getAllProjectOutputs(project));
|
||||
|
||||
if (outputs.length === 0) {
|
||||
return {
|
||||
type: UpToDateStatusType.ContainerOnly
|
||||
};
|
||||
}
|
||||
|
||||
// Now see if all outputs are newer than the newest input
|
||||
let oldestOutputFileName = "(none)";
|
||||
let oldestOutputFileTime = maximumDate;
|
||||
let newestOutputFileName = "(none)";
|
||||
let newestOutputFileTime = minimumDate;
|
||||
/** @type {string | undefined} */
|
||||
let missingOutputFileName;
|
||||
let newestDeclarationFileContentChangedTime = minimumDate;
|
||||
let isOutOfDateWithInputs = false;
|
||||
for (const output of outputs) {
|
||||
// Output is missing; can stop checking
|
||||
// Don't immediately return because we can still be upstream-blocked, which is a higher-priority status
|
||||
if (!host.fileExists(output)) {
|
||||
missingOutputFileName = output;
|
||||
break;
|
||||
}
|
||||
|
||||
const outputTime = host.getModifiedTime(output) || missingFileModifiedTime;
|
||||
if (outputTime < oldestOutputFileTime) {
|
||||
oldestOutputFileTime = outputTime;
|
||||
oldestOutputFileName = output;
|
||||
}
|
||||
|
||||
// If an output is older than the newest input, we can stop checking
|
||||
// Don't immediately return because we can still be upstream-blocked, which is a higher-priority status
|
||||
if (outputTime < newestInputFileTime) {
|
||||
isOutOfDateWithInputs = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (outputTime > newestOutputFileTime) {
|
||||
newestOutputFileTime = outputTime;
|
||||
newestOutputFileName = output;
|
||||
}
|
||||
|
||||
// Keep track of when the most recent time a .d.ts file was changed.
|
||||
// In addition to file timestamps, we also keep track of when a .d.ts file
|
||||
// had its file touched but not had its contents changed - this allows us
|
||||
// to skip a downstream typecheck
|
||||
if (path.extname(output) === ".d.ts") {
|
||||
const unchangedTime = host.getUnchangedTime ? host.getUnchangedTime(output) : undefined;
|
||||
if (unchangedTime !== undefined) {
|
||||
newestDeclarationFileContentChangedTime = newer(unchangedTime, newestDeclarationFileContentChangedTime);
|
||||
}
|
||||
else {
|
||||
const outputModifiedTime = host.getModifiedTime(output) || missingFileModifiedTime;
|
||||
newestDeclarationFileContentChangedTime = newer(newestDeclarationFileContentChangedTime, outputModifiedTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let pseudoUpToDate = false;
|
||||
let usesPrepend = false;
|
||||
/** @type {string | undefined} */
|
||||
let upstreamChangedProject;
|
||||
if (project.projectReferences) {
|
||||
if (host.setLastStatus) host.setLastStatus(project.options.configFilePath, { type: UpToDateStatusType.ComputingUpstream });
|
||||
for (const ref of project.projectReferences) {
|
||||
usesPrepend = usesPrepend || !!(ref.prepend);
|
||||
const resolvedRef = ts.resolveProjectReferencePath(host, ref);
|
||||
const parsedRef = host.parseConfigFile ? host.parseConfigFile(resolvedRef) : ts.getParsedCommandLineOfConfigFile(resolvedRef, {}, parseConfigHost);
|
||||
const refStatus = getUpToDateStatus(host, parsedRef);
|
||||
|
||||
// Its a circular reference ignore the status of this project
|
||||
if (refStatus.type === UpToDateStatusType.ComputingUpstream) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// An upstream project is blocked
|
||||
if (refStatus.type === UpToDateStatusType.Unbuildable) {
|
||||
return {
|
||||
type: UpToDateStatusType.UpstreamBlocked,
|
||||
upstreamProjectName: ref.path
|
||||
};
|
||||
}
|
||||
|
||||
// If the upstream project is out of date, then so are we (someone shouldn't have asked, though?)
|
||||
if (refStatus.type !== UpToDateStatusType.UpToDate) {
|
||||
return {
|
||||
type: UpToDateStatusType.UpstreamOutOfDate,
|
||||
upstreamProjectName: ref.path
|
||||
};
|
||||
}
|
||||
|
||||
// If the upstream project's newest file is older than our oldest output, we
|
||||
// can't be out of date because of it
|
||||
if (refStatus.newestInputFileTime && refStatus.newestInputFileTime <= oldestOutputFileTime) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the upstream project has only change .d.ts files, and we've built
|
||||
// *after* those files, then we're "psuedo up to date" and eligible for a fast rebuild
|
||||
if (refStatus.newestDeclarationFileContentChangedTime && refStatus.newestDeclarationFileContentChangedTime <= oldestOutputFileTime) {
|
||||
pseudoUpToDate = true;
|
||||
upstreamChangedProject = ref.path;
|
||||
continue;
|
||||
}
|
||||
|
||||
// We have an output older than an upstream output - we are out of date
|
||||
return {
|
||||
type: UpToDateStatusType.OutOfDateWithUpstream,
|
||||
outOfDateOutputFileName: oldestOutputFileName,
|
||||
newerProjectName: ref.path
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (missingOutputFileName !== undefined) {
|
||||
return {
|
||||
type: UpToDateStatusType.OutputMissing,
|
||||
missingOutputFileName
|
||||
};
|
||||
}
|
||||
|
||||
if (isOutOfDateWithInputs) {
|
||||
return {
|
||||
type: UpToDateStatusType.OutOfDateWithSelf,
|
||||
outOfDateOutputFileName: oldestOutputFileName,
|
||||
newerInputFileName: newestInputFileName
|
||||
};
|
||||
}
|
||||
|
||||
if (usesPrepend && pseudoUpToDate) {
|
||||
return {
|
||||
type: UpToDateStatusType.OutOfDateWithUpstream,
|
||||
outOfDateOutputFileName: oldestOutputFileName,
|
||||
newerProjectName: upstreamChangedProject
|
||||
};
|
||||
}
|
||||
|
||||
// Up to date
|
||||
return {
|
||||
type: pseudoUpToDate ? UpToDateStatusType.UpToDateWithUpstreamTypes : UpToDateStatusType.UpToDate,
|
||||
newestDeclarationFileContentChangedTime,
|
||||
newestInputFileTime,
|
||||
newestOutputFileTime,
|
||||
newestInputFileName,
|
||||
newestOutputFileName,
|
||||
oldestOutputFileName
|
||||
};
|
||||
}
|
||||
|
||||
const parseConfigHost = {
|
||||
useCaseSensitiveFileNames: true,
|
||||
getCurrentDirectory: () => process.cwd(),
|
||||
readDirectory: (file) => fs.readdirSync(file),
|
||||
fileExists: file => fs.existsSync(file) && fs.statSync(file).isFile(),
|
||||
readFile: file => fs.readFileSync(file, "utf8"),
|
||||
onUnRecoverableConfigFileDiagnostic: () => undefined
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef {import("vinyl")} File
|
||||
* @typedef {import("../../lib/typescript").ParsedCommandLine & { options: CompilerOptions }} ParsedCommandLine
|
||||
* @typedef {import("../../lib/typescript").CompilerOptions & { configFilePath?: string }} CompilerOptions
|
||||
* @typedef {import("../../lib/typescript").UpToDateHost} UpToDateHost
|
||||
* @typedef {import("../../lib/typescript").UpToDateStatus} UpToDateStatus
|
||||
* @typedef {import("../../lib/typescript").DiagnosticMessage} DiagnosticMessage
|
||||
* @typedef UpToDateHost
|
||||
* @property {(fileName: string) => boolean} fileExists
|
||||
* @property {(fileName: string) => Date} getModifiedTime
|
||||
* @property {(fileName: string) => Date} [getUnchangedTime]
|
||||
* @property {(configFilePath: string) => ParsedCommandLine | undefined} parseConfigFile
|
||||
* @property {(configFilePath: string) => UpToDateStatus} [getLastStatus]
|
||||
* @property {(configFilePath: string, status: UpToDateStatus) => void} [setLastStatus]
|
||||
*
|
||||
* @typedef Status.Unbuildable
|
||||
* @property {UpToDateStatusType.Unbuildable} type
|
||||
* @property {string} reason
|
||||
*
|
||||
* @typedef Status.ContainerOnly
|
||||
* @property {UpToDateStatusType.ContainerOnly} type
|
||||
*
|
||||
* @typedef Status.UpToDate
|
||||
* @property {UpToDateStatusType.UpToDate | UpToDateStatusType.UpToDateWithUpstreamTypes} type
|
||||
* @property {Date} [newestInputFileTime]
|
||||
* @property {string} [newestInputFileName]
|
||||
* @property {Date} [newestDeclarationFileContentChangedTime]
|
||||
* @property {Date} [newestOutputFileTime]
|
||||
* @property {string} [newestOutputFileName]
|
||||
* @property {string} [oldestOutputFileName]
|
||||
*
|
||||
* @typedef Status.OutputMissing
|
||||
* @property {UpToDateStatusType.OutputMissing} type
|
||||
* @property {string} missingOutputFileName
|
||||
*
|
||||
* @typedef Status.OutOfDateWithSelf
|
||||
* @property {UpToDateStatusType.OutOfDateWithSelf} type
|
||||
* @property {string} outOfDateOutputFileName
|
||||
* @property {string} newerInputFileName
|
||||
*
|
||||
* @typedef Status.UpstreamOutOfDate
|
||||
* @property {UpToDateStatusType.UpstreamOutOfDate} type
|
||||
* @property {string} upstreamProjectName
|
||||
*
|
||||
* @typedef Status.UpstreamBlocked
|
||||
* @property {UpToDateStatusType.UpstreamBlocked} type
|
||||
* @property {string} upstreamProjectName
|
||||
*
|
||||
* @typedef Status.ComputingUpstream
|
||||
* @property {UpToDateStatusType.ComputingUpstream} type
|
||||
*
|
||||
* @typedef Status.OutOfDateWithUpstream
|
||||
* @property {UpToDateStatusType.OutOfDateWithUpstream} type
|
||||
* @property {string} outOfDateOutputFileName
|
||||
* @property {string} newerProjectName
|
||||
|
||||
* @typedef {Status.Unbuildable | Status.ContainerOnly | Status.UpToDate | Status.OutputMissing | Status.OutOfDateWithSelf | Status.UpstreamOutOfDate | Status.UpstreamBlocked | Status.ComputingUpstream | Status.OutOfDateWithUpstream} UpToDateStatus
|
||||
*/
|
||||
void 0;
|
||||
@@ -55,13 +55,13 @@ function main(): void {
|
||||
function updateTsFile(tsFilePath: string, tsFileContents: string, majorMinor: string, patch: string, nightlyPatch: string): string {
|
||||
const majorMinorRgx = /export const versionMajorMinor = "(\d+\.\d+)"/;
|
||||
const majorMinorMatch = majorMinorRgx.exec(tsFileContents);
|
||||
assert(majorMinorMatch !== null, `The file seems to no longer have a string matching '${majorMinorRgx}'.`);
|
||||
assert(majorMinorMatch !== null, `The file '${tsFilePath}' seems to no longer have a string matching '${majorMinorRgx}'.`);
|
||||
const parsedMajorMinor = majorMinorMatch![1];
|
||||
assert(parsedMajorMinor === majorMinor, `versionMajorMinor does not match. ${tsFilePath}: '${parsedMajorMinor}'; package.json: '${majorMinor}'`);
|
||||
|
||||
const versionRgx = /export const version = `\$\{versionMajorMinor\}\.(\d)(-dev)?`;/;
|
||||
const patchMatch = versionRgx.exec(tsFileContents);
|
||||
assert(patchMatch !== null, "The file seems to no longer have a string matching " + versionRgx.toString());
|
||||
assert(patchMatch !== null, `The file '${tsFilePath}' seems to no longer have a string matching '${versionRgx.toString()}'.`);
|
||||
const parsedPatch = patchMatch![1];
|
||||
if (parsedPatch !== patch) {
|
||||
throw new Error(`patch does not match. ${tsFilePath}: '${parsedPatch}; package.json: '${patch}'`);
|
||||
|
||||
@@ -46,6 +46,9 @@ class FailedTestsReporter extends Mocha.reporters.Base {
|
||||
}
|
||||
|
||||
const newOptions = Object.assign({}, options, { reporterOptions: reporterOptions.reporterOptions || {} });
|
||||
if (reporterOptions.reporter === "xunit") {
|
||||
newOptions.reporterOptions.output = "TEST-results.xml";
|
||||
}
|
||||
this.reporter = new reporter(runner, newOptions);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ function main(): void {
|
||||
console.error("Unexpected XML file structure. Expected to find result.LCX.$.TgtCul.");
|
||||
process.exit(1);
|
||||
}
|
||||
const outputDirectoryName = getPreferedLocaleName(result.LCX.$.TgtCul);
|
||||
const outputDirectoryName = getPreferedLocaleName(result.LCX.$.TgtCul).toLowerCase();
|
||||
if (!outputDirectoryName) {
|
||||
console.error(`Invalid output locale name for '${result.LCX.$.TgtCul}'.`);
|
||||
process.exit(1);
|
||||
|
||||
@@ -16,7 +16,7 @@ function padNum(number: number) {
|
||||
}
|
||||
|
||||
const userName = process.env.GH_USERNAME;
|
||||
const reviewers = ["weswigham", "sandersn", "mhegazy"]
|
||||
const reviewers = ["weswigham", "sandersn", "RyanCavanaugh"]
|
||||
const now = new Date();
|
||||
const branchName = `user-update-${now.getFullYear()}${padNum(now.getMonth())}${padNum(now.getDay())}`;
|
||||
const remoteUrl = `https://${process.argv[2]}@github.com/${userName}/TypeScript.git`;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"extends": "../tsconfig-base",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../built/local/",
|
||||
"rootDir": ".",
|
||||
"composite": false,
|
||||
"declaration": false,
|
||||
"declarationMap": false,
|
||||
|
||||
+189
-113
@@ -143,7 +143,7 @@ namespace ts {
|
||||
|
||||
let symbolCount = 0;
|
||||
|
||||
let Symbol: { new (flags: SymbolFlags, name: __String): Symbol }; // tslint:disable-line variable-name
|
||||
let Symbol: new (flags: SymbolFlags, name: __String) => Symbol; // tslint:disable-line variable-name
|
||||
let classifiableNames: UnderscoreEscapedMap<true>;
|
||||
|
||||
const unreachableFlow: FlowNode = { flags: FlowFlags.Unreachable };
|
||||
@@ -233,13 +233,23 @@ namespace ts {
|
||||
symbol.members = createSymbolTable();
|
||||
}
|
||||
|
||||
// On merge of const enum module with class or function, reset const enum only flag (namespaces will already recalculate)
|
||||
if (symbol.constEnumOnlyModule && (symbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.RegularEnum))) {
|
||||
symbol.constEnumOnlyModule = false;
|
||||
}
|
||||
|
||||
if (symbolFlags & SymbolFlags.Value) {
|
||||
const { valueDeclaration } = symbol;
|
||||
if (!valueDeclaration ||
|
||||
(valueDeclaration.kind !== node.kind && isEffectiveModuleDeclaration(valueDeclaration))) {
|
||||
// other kinds of value declarations take precedence over modules
|
||||
symbol.valueDeclaration = node;
|
||||
}
|
||||
setValueDeclaration(symbol, node);
|
||||
}
|
||||
}
|
||||
|
||||
function setValueDeclaration(symbol: Symbol, node: Declaration): void {
|
||||
const { valueDeclaration } = symbol;
|
||||
if (!valueDeclaration ||
|
||||
(isAssignmentDeclaration(valueDeclaration) && !isAssignmentDeclaration(node)) ||
|
||||
(valueDeclaration.kind !== node.kind && isEffectiveModuleDeclaration(valueDeclaration))) {
|
||||
// other kinds of value declarations take precedence over modules and assignment declarations
|
||||
symbol.valueDeclaration = node;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,7 +269,7 @@ namespace ts {
|
||||
if (name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
const nameExpression = name.expression;
|
||||
// treat computed property names where expression is string/numeric literal as just string/numeric literal
|
||||
if (isStringOrNumericLiteral(nameExpression)) {
|
||||
if (isStringOrNumericLiteralLike(nameExpression)) {
|
||||
return escapeLeadingUnderscores(nameExpression.text);
|
||||
}
|
||||
|
||||
@@ -287,7 +297,7 @@ namespace ts {
|
||||
// module.exports = ...
|
||||
return InternalSymbolName.ExportEquals;
|
||||
case SyntaxKind.BinaryExpression:
|
||||
if (getSpecialPropertyAssignmentKind(node as BinaryExpression) === SpecialPropertyAssignmentKind.ModuleExports) {
|
||||
if (getAssignmentDeclarationKind(node as BinaryExpression) === AssignmentDeclarationKind.ModuleExports) {
|
||||
// module.exports = ...
|
||||
return InternalSymbolName.ExportEquals;
|
||||
}
|
||||
@@ -373,7 +383,8 @@ namespace ts {
|
||||
// prototype symbols like methods.
|
||||
symbolTable.set(name, symbol = createSymbol(SymbolFlags.None, name));
|
||||
}
|
||||
else {
|
||||
else if (!(includes & SymbolFlags.Variable && symbol.flags & SymbolFlags.Assignment)) {
|
||||
// Assignment declarations are allowed to merge with variables, no matter what other flags they have.
|
||||
if (isNamedDeclaration(node)) {
|
||||
node.name.parent = node;
|
||||
}
|
||||
@@ -459,7 +470,7 @@ namespace ts {
|
||||
// during global merging in the checker. Why? The only case when ambient module is permitted inside another module is module augmentation
|
||||
// and this case is specially handled. Module augmentations should only be merged with original module definition
|
||||
// and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed.
|
||||
if (isJSDocTypeAlias(node)) Debug.assert(isInJavaScriptFile(node)); // We shouldn't add symbols for JSDoc nodes if not in a JS file.
|
||||
if (isJSDocTypeAlias(node)) Debug.assert(isInJSFile(node)); // We shouldn't add symbols for JSDoc nodes if not in a JS file.
|
||||
if ((!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) || isJSDocTypeAlias(node)) {
|
||||
if (hasModifier(node, ModifierFlags.Default) && !getDeclarationName(node)) {
|
||||
return declareSymbol(container.symbol.exports!, container.symbol, node, symbolFlags, symbolExcludes); // No local symbol for an unnamed default!
|
||||
@@ -634,6 +645,7 @@ namespace ts {
|
||||
function bindChildrenWorker(node: Node): void {
|
||||
if (checkUnreachable(node)) {
|
||||
bindEachChild(node);
|
||||
bindJSDoc(node);
|
||||
return;
|
||||
}
|
||||
switch (node.kind) {
|
||||
@@ -723,6 +735,7 @@ namespace ts {
|
||||
case SyntaxKind.Identifier:
|
||||
case SyntaxKind.ThisKeyword:
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
return isNarrowableReference(expr);
|
||||
case SyntaxKind.CallExpression:
|
||||
return hasNarrowableArgument(<CallExpression>expr);
|
||||
@@ -732,15 +745,18 @@ namespace ts {
|
||||
return isNarrowingBinaryExpression(<BinaryExpression>expr);
|
||||
case SyntaxKind.PrefixUnaryExpression:
|
||||
return (<PrefixUnaryExpression>expr).operator === SyntaxKind.ExclamationToken && isNarrowingExpression((<PrefixUnaryExpression>expr).operand);
|
||||
case SyntaxKind.TypeOfExpression:
|
||||
return isNarrowingExpression((<TypeOfExpression>expr).expression);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isNarrowableReference(expr: Expression): boolean {
|
||||
return expr.kind === SyntaxKind.Identifier ||
|
||||
expr.kind === SyntaxKind.ThisKeyword ||
|
||||
expr.kind === SyntaxKind.SuperKeyword ||
|
||||
expr.kind === SyntaxKind.PropertyAccessExpression && isNarrowableReference((<PropertyAccessExpression>expr).expression);
|
||||
return expr.kind === SyntaxKind.Identifier || expr.kind === SyntaxKind.ThisKeyword || expr.kind === SyntaxKind.SuperKeyword ||
|
||||
isPropertyAccessExpression(expr) && isNarrowableReference(expr.expression) ||
|
||||
isElementAccessExpression(expr) && expr.argumentExpression &&
|
||||
(isStringLiteral(expr.argumentExpression) || isNumericLiteral(expr.argumentExpression)) &&
|
||||
isNarrowableReference(expr.expression);
|
||||
}
|
||||
|
||||
function hasNarrowableArgument(expr: CallExpression) {
|
||||
@@ -1170,7 +1186,6 @@ namespace ts {
|
||||
}
|
||||
const preCaseLabel = createBranchLabel();
|
||||
addAntecedent(preCaseLabel, createFlowSwitchClause(preSwitchCaseFlow!, node.parent, clauseStart, i + 1));
|
||||
addAntecedent(preCaseLabel, createFlowSwitchClause(preSwitchCaseFlow!, node.parent, clauseStart, i + 1));
|
||||
addAntecedent(preCaseLabel, fallthroughFlow);
|
||||
currentFlow = finishFlowLabel(preCaseLabel);
|
||||
const clause = clauses[i];
|
||||
@@ -1369,6 +1384,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindJSDocTypeAlias(node: JSDocTypedefTag | JSDocCallbackTag) {
|
||||
node.tagName.parent = node;
|
||||
if (node.fullName) {
|
||||
setParentPointers(node, node.fullName);
|
||||
}
|
||||
@@ -1727,10 +1743,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function bindBlockScopedVariableDeclaration(node: Declaration) {
|
||||
bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
|
||||
}
|
||||
|
||||
function delayedBindJSDocTypedefTag() {
|
||||
if (!delayedTypeAliases) {
|
||||
return;
|
||||
@@ -2007,7 +2019,7 @@ namespace ts {
|
||||
|
||||
function bindJSDoc(node: Node) {
|
||||
if (hasJSDocNodes(node)) {
|
||||
if (isInJavaScriptFile(node)) {
|
||||
if (isInJSFile(node)) {
|
||||
for (const j of node.jsDoc!) {
|
||||
bind(j);
|
||||
}
|
||||
@@ -2066,46 +2078,47 @@ namespace ts {
|
||||
}
|
||||
return checkStrictModeIdentifier(<Identifier>node);
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
if (currentFlow && isNarrowableReference(<Expression>node)) {
|
||||
node.flowNode = currentFlow;
|
||||
}
|
||||
if (isSpecialPropertyDeclaration(node as PropertyAccessExpression)) {
|
||||
bindSpecialPropertyDeclaration(node as PropertyAccessExpression);
|
||||
}
|
||||
if (isInJavaScriptFile(node) &&
|
||||
if (isInJSFile(node) &&
|
||||
file.commonJsModuleIndicator &&
|
||||
isModuleExportsPropertyAccessExpression(node as PropertyAccessExpression) &&
|
||||
!lookupSymbolForNameWorker(container, "module" as __String)) {
|
||||
declareSymbol(container.locals!, /*parent*/ undefined, (node as PropertyAccessExpression).expression as Identifier,
|
||||
!lookupSymbolForNameWorker(blockScopeContainer, "module" as __String)) {
|
||||
declareSymbol(file.locals!, /*parent*/ undefined, (node as PropertyAccessExpression).expression as Identifier,
|
||||
SymbolFlags.FunctionScopedVariable | SymbolFlags.ModuleExports, SymbolFlags.FunctionScopedVariableExcludes);
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.BinaryExpression:
|
||||
const specialKind = getSpecialPropertyAssignmentKind(node as BinaryExpression);
|
||||
const specialKind = getAssignmentDeclarationKind(node as BinaryExpression);
|
||||
switch (specialKind) {
|
||||
case SpecialPropertyAssignmentKind.ExportsProperty:
|
||||
case AssignmentDeclarationKind.ExportsProperty:
|
||||
bindExportsPropertyAssignment(node as BinaryExpression);
|
||||
break;
|
||||
case SpecialPropertyAssignmentKind.ModuleExports:
|
||||
case AssignmentDeclarationKind.ModuleExports:
|
||||
bindModuleExportsAssignment(node as BinaryExpression);
|
||||
break;
|
||||
case SpecialPropertyAssignmentKind.PrototypeProperty:
|
||||
case AssignmentDeclarationKind.PrototypeProperty:
|
||||
bindPrototypePropertyAssignment((node as BinaryExpression).left as PropertyAccessEntityNameExpression, node);
|
||||
break;
|
||||
case SpecialPropertyAssignmentKind.Prototype:
|
||||
case AssignmentDeclarationKind.Prototype:
|
||||
bindPrototypeAssignment(node as BinaryExpression);
|
||||
break;
|
||||
case SpecialPropertyAssignmentKind.ThisProperty:
|
||||
case AssignmentDeclarationKind.ThisProperty:
|
||||
bindThisPropertyAssignment(node as BinaryExpression);
|
||||
break;
|
||||
case SpecialPropertyAssignmentKind.Property:
|
||||
case AssignmentDeclarationKind.Property:
|
||||
bindSpecialPropertyAssignment(node as BinaryExpression);
|
||||
break;
|
||||
case SpecialPropertyAssignmentKind.None:
|
||||
case AssignmentDeclarationKind.None:
|
||||
// Nothing to do
|
||||
break;
|
||||
default:
|
||||
Debug.fail("Unknown special property assignment kind");
|
||||
Debug.fail("Unknown binary expression special property assignment kind");
|
||||
}
|
||||
return checkStrictModeBinaryExpression(<BinaryExpression>node);
|
||||
case SyntaxKind.CatchClause:
|
||||
@@ -2181,7 +2194,20 @@ namespace ts {
|
||||
return bindFunctionExpression(<FunctionExpression>node);
|
||||
|
||||
case SyntaxKind.CallExpression:
|
||||
if (isInJavaScriptFile(node)) {
|
||||
const assignmentKind = getAssignmentDeclarationKind(node as CallExpression);
|
||||
switch (assignmentKind) {
|
||||
case AssignmentDeclarationKind.ObjectDefinePropertyValue:
|
||||
return bindObjectDefinePropertyAssignment(node as BindableObjectDefinePropertyCall);
|
||||
case AssignmentDeclarationKind.ObjectDefinePropertyExports:
|
||||
return bindObjectDefinePropertyExport(node as BindableObjectDefinePropertyCall);
|
||||
case AssignmentDeclarationKind.ObjectDefinePrototypeProperty:
|
||||
return bindObjectDefinePrototypeProperty(node as BindableObjectDefinePropertyCall);
|
||||
case AssignmentDeclarationKind.None:
|
||||
break; // Nothing to do
|
||||
default:
|
||||
return Debug.fail("Unknown call expression assignment declaration kind");
|
||||
}
|
||||
if (isInJSFile(node)) {
|
||||
bindCallExpression(<CallExpression>node);
|
||||
}
|
||||
break;
|
||||
@@ -2283,14 +2309,19 @@ namespace ts {
|
||||
bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node)!);
|
||||
}
|
||||
else {
|
||||
const flags = node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node)
|
||||
const flags = exportAssignmentIsAlias(node)
|
||||
// An export default clause with an EntityNameExpression or a class expression exports all meanings of that identifier or expression;
|
||||
? SymbolFlags.Alias
|
||||
// An export default clause with any other expression exports a value
|
||||
: SymbolFlags.Property;
|
||||
// If there is an `export default x;` alias declaration, can't `export default` anything else.
|
||||
// (In contrast, you can still have `export default function f() {}` and `export default interface I {}`.)
|
||||
declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.All);
|
||||
const symbol = declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.All);
|
||||
|
||||
if (node.isExportEquals) {
|
||||
// Will be an error later, since the module already has other exports. Just make sure this has a valueDeclaration set.
|
||||
setValueDeclaration(symbol, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2298,27 +2329,17 @@ namespace ts {
|
||||
if (node.modifiers && node.modifiers.length) {
|
||||
file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Modifiers_cannot_appear_here));
|
||||
}
|
||||
|
||||
if (node.parent.kind !== SyntaxKind.SourceFile) {
|
||||
file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Global_module_exports_may_only_appear_at_top_level));
|
||||
return;
|
||||
const diag = !isSourceFile(node.parent) ? Diagnostics.Global_module_exports_may_only_appear_at_top_level
|
||||
: !isExternalModule(node.parent) ? Diagnostics.Global_module_exports_may_only_appear_in_module_files
|
||||
: !node.parent.isDeclarationFile ? Diagnostics.Global_module_exports_may_only_appear_in_declaration_files
|
||||
: undefined;
|
||||
if (diag) {
|
||||
file.bindDiagnostics.push(createDiagnosticForNode(node, diag));
|
||||
}
|
||||
else {
|
||||
const parent = node.parent as SourceFile;
|
||||
|
||||
if (!isExternalModule(parent)) {
|
||||
file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Global_module_exports_may_only_appear_in_module_files));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!parent.isDeclarationFile) {
|
||||
file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Global_module_exports_may_only_appear_in_declaration_files));
|
||||
return;
|
||||
}
|
||||
file.symbol.globalExports = file.symbol.globalExports || createSymbolTable();
|
||||
declareSymbol(file.symbol.globalExports, file.symbol, node, SymbolFlags.Alias, SymbolFlags.AliasExcludes);
|
||||
}
|
||||
|
||||
file.symbol.globalExports = file.symbol.globalExports || createSymbolTable();
|
||||
declareSymbol(file.symbol.globalExports, file.symbol, node, SymbolFlags.Alias, SymbolFlags.AliasExcludes);
|
||||
}
|
||||
|
||||
function bindExportDeclaration(node: ExportDeclaration) {
|
||||
@@ -2349,6 +2370,22 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
|
||||
function bindObjectDefinePropertyExport(node: BindableObjectDefinePropertyCall) {
|
||||
if (!setCommonJsModuleIndicator(node)) {
|
||||
return;
|
||||
}
|
||||
const symbol = forEachIdentifierInEntityName(node.arguments[0], /*parent*/ undefined, (id, symbol) => {
|
||||
if (symbol) {
|
||||
addDeclarationToSymbol(symbol, id, SymbolFlags.Module | SymbolFlags.Assignment);
|
||||
}
|
||||
return symbol;
|
||||
});
|
||||
if (symbol) {
|
||||
const flags = SymbolFlags.Property | SymbolFlags.ExportValue;
|
||||
declareSymbol(symbol.exports!, symbol, node, flags, SymbolFlags.None);
|
||||
}
|
||||
}
|
||||
|
||||
function bindExportsPropertyAssignment(node: BinaryExpression) {
|
||||
// When we create a property via 'exports.foo = bar', the 'exports.foo' property access
|
||||
// expression is the declaration
|
||||
@@ -2358,7 +2395,7 @@ namespace ts {
|
||||
const lhs = node.left as PropertyAccessEntityNameExpression;
|
||||
const symbol = forEachIdentifierInEntityName(lhs.expression, /*parent*/ undefined, (id, symbol) => {
|
||||
if (symbol) {
|
||||
addDeclarationToSymbol(symbol, id, SymbolFlags.Module | SymbolFlags.JSContainer);
|
||||
addDeclarationToSymbol(symbol, id, SymbolFlags.Module | SymbolFlags.Assignment);
|
||||
}
|
||||
return symbol;
|
||||
});
|
||||
@@ -2387,11 +2424,11 @@ namespace ts {
|
||||
const flags = exportAssignmentIsAlias(node)
|
||||
? SymbolFlags.Alias // An export= with an EntityNameExpression or a ClassExpression exports all meanings of that identifier or class
|
||||
: SymbolFlags.Property | SymbolFlags.ExportValue | SymbolFlags.ValueModule;
|
||||
declareSymbol(file.symbol.exports!, file.symbol, node, flags, SymbolFlags.None);
|
||||
declareSymbol(file.symbol.exports!, file.symbol, node, flags | SymbolFlags.Assignment, SymbolFlags.None);
|
||||
}
|
||||
|
||||
function bindThisPropertyAssignment(node: BinaryExpression | PropertyAccessExpression) {
|
||||
Debug.assert(isInJavaScriptFile(node));
|
||||
Debug.assert(isInJSFile(node));
|
||||
const thisContainer = getThisContainer(node, /*includeArrowFunctions*/ false);
|
||||
switch (thisContainer.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
@@ -2453,7 +2490,12 @@ namespace ts {
|
||||
node.left.parent = node;
|
||||
node.right.parent = node;
|
||||
const lhs = node.left as PropertyAccessEntityNameExpression;
|
||||
bindPropertyAssignment(lhs, lhs, /*isPrototypeProperty*/ false);
|
||||
bindPropertyAssignment(lhs.expression, lhs, /*isPrototypeProperty*/ false);
|
||||
}
|
||||
|
||||
function bindObjectDefinePrototypeProperty(node: BindableObjectDefinePropertyCall) {
|
||||
const namespaceSymbol = lookupSymbolForPropertyAccess((node.arguments[0] as PropertyAccessExpression).expression as EntityNameExpression);
|
||||
bindPotentiallyNewExpandoMemberToNamespace(node, namespaceSymbol, /*isPrototypeProperty*/ true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2474,9 +2516,20 @@ namespace ts {
|
||||
bindPropertyAssignment(constructorFunction, lhs, /*isPrototypeProperty*/ true);
|
||||
}
|
||||
|
||||
function bindObjectDefinePropertyAssignment(node: BindableObjectDefinePropertyCall) {
|
||||
let namespaceSymbol = lookupSymbolForPropertyAccess(node.arguments[0]);
|
||||
const isToplevel = node.parent.parent.kind === SyntaxKind.SourceFile;
|
||||
namespaceSymbol = bindPotentiallyMissingNamespaces(namespaceSymbol, node.arguments[0], isToplevel, /*isPrototypeProperty*/ false);
|
||||
bindPotentiallyNewExpandoMemberToNamespace(node, namespaceSymbol, /*isPrototypeProperty*/ false);
|
||||
}
|
||||
|
||||
function bindSpecialPropertyAssignment(node: BinaryExpression) {
|
||||
const lhs = node.left as PropertyAccessEntityNameExpression;
|
||||
// Class declarations in Typescript do not allow property declarations
|
||||
const parentSymbol = lookupSymbolForPropertyAccess(lhs.expression);
|
||||
if (!isInJSFile(node) && !isFunctionSymbol(parentSymbol)) {
|
||||
return;
|
||||
}
|
||||
// Fix up parent pointers since we're going to use these nodes before we bind into them
|
||||
node.left.parent = node;
|
||||
node.right.parent = node;
|
||||
@@ -2500,27 +2553,28 @@ namespace ts {
|
||||
bindPropertyAssignment(node.expression, node, /*isPrototypeProperty*/ false);
|
||||
}
|
||||
|
||||
function bindPropertyAssignment(name: EntityNameExpression, propertyAccess: PropertyAccessEntityNameExpression, isPrototypeProperty: boolean) {
|
||||
let namespaceSymbol = lookupSymbolForPropertyAccess(name);
|
||||
const isToplevelNamespaceableInitializer = isBinaryExpression(propertyAccess.parent)
|
||||
? getParentOfBinaryExpression(propertyAccess.parent).parent.kind === SyntaxKind.SourceFile &&
|
||||
!!getJavascriptInitializer(getInitializerOfBinaryExpression(propertyAccess.parent), isPrototypeAccess(propertyAccess.parent.left))
|
||||
: propertyAccess.parent.parent.kind === SyntaxKind.SourceFile;
|
||||
if (!isPrototypeProperty && (!namespaceSymbol || !(namespaceSymbol.flags & SymbolFlags.Namespace)) && isToplevelNamespaceableInitializer) {
|
||||
function bindPotentiallyMissingNamespaces(namespaceSymbol: Symbol | undefined, entityName: EntityNameExpression, isToplevel: boolean, isPrototypeProperty: boolean) {
|
||||
if (isToplevel && !isPrototypeProperty && (!namespaceSymbol || !(namespaceSymbol.flags & SymbolFlags.Namespace))) {
|
||||
// make symbols or add declarations for intermediate containers
|
||||
const flags = SymbolFlags.Module | SymbolFlags.JSContainer;
|
||||
const excludeFlags = SymbolFlags.ValueModuleExcludes & ~SymbolFlags.JSContainer;
|
||||
namespaceSymbol = forEachIdentifierInEntityName(propertyAccess.expression, namespaceSymbol, (id, symbol, parent) => {
|
||||
const flags = SymbolFlags.Module | SymbolFlags.Assignment;
|
||||
const excludeFlags = SymbolFlags.ValueModuleExcludes & ~SymbolFlags.Assignment;
|
||||
namespaceSymbol = forEachIdentifierInEntityName(entityName, namespaceSymbol, (id, symbol, parent) => {
|
||||
if (symbol) {
|
||||
addDeclarationToSymbol(symbol, id, flags);
|
||||
return symbol;
|
||||
}
|
||||
else {
|
||||
return declareSymbol(parent ? parent.exports! : container.locals!, parent, id, flags, excludeFlags);
|
||||
const table = parent ? parent.exports! :
|
||||
file.jsGlobalAugmentations || (file.jsGlobalAugmentations = createSymbolTable());
|
||||
return declareSymbol(table, parent, id, flags, excludeFlags);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!namespaceSymbol || !isJavascriptContainer(namespaceSymbol)) {
|
||||
return namespaceSymbol;
|
||||
}
|
||||
|
||||
function bindPotentiallyNewExpandoMemberToNamespace(declaration: PropertyAccessEntityNameExpression | CallExpression, namespaceSymbol: Symbol | undefined, isPrototypeProperty: boolean) {
|
||||
if (!namespaceSymbol || !isExpandoSymbol(namespaceSymbol)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2529,16 +2583,23 @@ namespace ts {
|
||||
(namespaceSymbol.members || (namespaceSymbol.members = createSymbolTable())) :
|
||||
(namespaceSymbol.exports || (namespaceSymbol.exports = createSymbolTable()));
|
||||
|
||||
// Declare the method/property
|
||||
const jsContainerFlag = isToplevelNamespaceableInitializer ? SymbolFlags.JSContainer : 0;
|
||||
const isMethod = isFunctionLikeDeclaration(getAssignedJavascriptInitializer(propertyAccess)!);
|
||||
const symbolFlags = (isMethod ? SymbolFlags.Method : SymbolFlags.Property) | jsContainerFlag;
|
||||
const symbolExcludes = (isMethod ? SymbolFlags.MethodExcludes : SymbolFlags.PropertyExcludes) & ~jsContainerFlag;
|
||||
declareSymbol(symbolTable, namespaceSymbol, propertyAccess, symbolFlags, symbolExcludes);
|
||||
const isMethod = isFunctionLikeDeclaration(getAssignedExpandoInitializer(declaration)!);
|
||||
const includes = isMethod ? SymbolFlags.Method : SymbolFlags.Property;
|
||||
const excludes = isMethod ? SymbolFlags.MethodExcludes : SymbolFlags.PropertyExcludes;
|
||||
declareSymbol(symbolTable, namespaceSymbol, declaration, includes | SymbolFlags.Assignment, excludes & ~SymbolFlags.Assignment);
|
||||
}
|
||||
|
||||
function bindPropertyAssignment(name: EntityNameExpression, propertyAccess: PropertyAccessEntityNameExpression, isPrototypeProperty: boolean) {
|
||||
let namespaceSymbol = lookupSymbolForPropertyAccess(name);
|
||||
const isToplevel = isBinaryExpression(propertyAccess.parent)
|
||||
? getParentOfBinaryExpression(propertyAccess.parent).parent.kind === SyntaxKind.SourceFile
|
||||
: propertyAccess.parent.parent.kind === SyntaxKind.SourceFile;
|
||||
namespaceSymbol = bindPotentiallyMissingNamespaces(namespaceSymbol, propertyAccess.expression, isToplevel, isPrototypeProperty);
|
||||
bindPotentiallyNewExpandoMemberToNamespace(propertyAccess, namespaceSymbol, isPrototypeProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Javascript containers are:
|
||||
* Javascript expando values are:
|
||||
* - Functions
|
||||
* - classes
|
||||
* - namespaces
|
||||
@@ -2547,11 +2608,14 @@ namespace ts {
|
||||
* - with empty object literals
|
||||
* - with non-empty object literals if assigned to the prototype property
|
||||
*/
|
||||
function isJavascriptContainer(symbol: Symbol): boolean {
|
||||
function isExpandoSymbol(symbol: Symbol): boolean {
|
||||
if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.NamespaceModule)) {
|
||||
return true;
|
||||
}
|
||||
const node = symbol.valueDeclaration;
|
||||
if (node && isCallExpression(node)) {
|
||||
return !!getAssignedExpandoInitializer(node);
|
||||
}
|
||||
let init = !node ? undefined :
|
||||
isVariableDeclaration(node) ? node.initializer :
|
||||
isBinaryExpression(node) ? node.right :
|
||||
@@ -2560,12 +2624,12 @@ namespace ts {
|
||||
init = init && getRightMostAssignedExpression(init);
|
||||
if (init) {
|
||||
const isPrototypeAssignment = isPrototypeAccess(isVariableDeclaration(node) ? node.name : isBinaryExpression(node) ? node.left : node);
|
||||
return !!getJavascriptInitializer(isBinaryExpression(init) && init.operatorToken.kind === SyntaxKind.BarBarToken ? init.right : init, isPrototypeAssignment);
|
||||
return !!getExpandoInitializer(isBinaryExpression(init) && init.operatorToken.kind === SyntaxKind.BarBarToken ? init.right : init, isPrototypeAssignment);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function getParentOfBinaryExpression(expr: BinaryExpression) {
|
||||
function getParentOfBinaryExpression(expr: Node) {
|
||||
while (isBinaryExpression(expr.parent)) {
|
||||
expr = expr.parent;
|
||||
}
|
||||
@@ -2652,8 +2716,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (!isBindingPattern(node.name)) {
|
||||
const isEnum = isInJSFile(node) && !!getJSDocEnumTag(node);
|
||||
const enumFlags = (isEnum ? SymbolFlags.RegularEnum : SymbolFlags.None);
|
||||
const enumExcludes = (isEnum ? SymbolFlags.RegularEnumExcludes : SymbolFlags.None);
|
||||
if (isBlockOrCatchScoped(node)) {
|
||||
bindBlockScopedVariableDeclaration(node);
|
||||
bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable | enumFlags, SymbolFlags.BlockScopedVariableExcludes | enumExcludes);
|
||||
}
|
||||
else if (isParameterDeclaration(node)) {
|
||||
// It is safe to walk up parent chain to find whether the node is a destructuring parameter declaration
|
||||
@@ -2668,7 +2735,7 @@ namespace ts {
|
||||
declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes);
|
||||
}
|
||||
else {
|
||||
declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes);
|
||||
declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable | enumFlags, SymbolFlags.FunctionScopedVariableExcludes | enumExcludes);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2796,9 +2863,7 @@ namespace ts {
|
||||
// report error on class declarations
|
||||
node.kind === SyntaxKind.ClassDeclaration ||
|
||||
// report error on instantiated modules or const-enums only modules if preserveConstEnums is set
|
||||
(node.kind === SyntaxKind.ModuleDeclaration && shouldReportErrorOnModuleDeclaration(<ModuleDeclaration>node)) ||
|
||||
// report error on regular enums and const enums if preserveConstEnums is set
|
||||
(isEnumDeclaration(node) && (!isEnumConst(node) || options.preserveConstEnums));
|
||||
(node.kind === SyntaxKind.ModuleDeclaration && shouldReportErrorOnModuleDeclaration(<ModuleDeclaration>node));
|
||||
|
||||
if (reportError) {
|
||||
currentFlow = reportedUnreachableFlow;
|
||||
@@ -2843,7 +2908,7 @@ namespace ts {
|
||||
// As opposed to a pure declaration like an `interface`
|
||||
function isExecutableStatement(s: Statement): boolean {
|
||||
// Don't remove statements that can validly be used before they appear.
|
||||
return !isFunctionDeclaration(s) && !isPurelyTypeDeclaration(s) &&
|
||||
return !isFunctionDeclaration(s) && !isPurelyTypeDeclaration(s) && !isEnumDeclaration(s) &&
|
||||
// `var x;` may declare a variable used above
|
||||
!(isVariableStatement(s) && !(getCombinedNodeFlags(s) & (NodeFlags.Let | NodeFlags.Const)) && s.declarationList.declarations.some(d => !d.initializer));
|
||||
}
|
||||
@@ -2862,7 +2927,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isExportsOrModuleExportsOrAlias(sourceFile: SourceFile, node: Expression): boolean {
|
||||
return isExportsIdentifier(node) ||
|
||||
isModuleExportsPropertyAccessExpression(node) ||
|
||||
@@ -2886,6 +2950,9 @@ namespace ts {
|
||||
if (local) {
|
||||
return local.exportSymbol || local;
|
||||
}
|
||||
if (isSourceFile(container) && container.jsGlobalAugmentations && container.jsGlobalAugmentations.has(name)) {
|
||||
return container.jsGlobalAugmentations.get(name);
|
||||
}
|
||||
return container.symbol && container.symbol.exports && container.symbol.exports.get(name);
|
||||
}
|
||||
|
||||
@@ -2990,7 +3057,7 @@ namespace ts {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
if (subtreeFlags & TransformFlags.ContainsSpread
|
||||
if (subtreeFlags & TransformFlags.ContainsRestOrSpread
|
||||
|| (expression.transformFlags & (TransformFlags.Super | TransformFlags.ContainsSuper))) {
|
||||
// If the this node contains a SpreadExpression, or is a super call, then it is an ES6
|
||||
// node.
|
||||
@@ -3021,7 +3088,7 @@ namespace ts {
|
||||
if (node.typeArguments) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
if (subtreeFlags & TransformFlags.ContainsSpread) {
|
||||
if (subtreeFlags & TransformFlags.ContainsRestOrSpread) {
|
||||
// If the this node contains a SpreadElementExpression then it is an ES6
|
||||
// node.
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
@@ -3064,18 +3131,18 @@ namespace ts {
|
||||
// syntax.
|
||||
if (node.questionToken
|
||||
|| node.type
|
||||
|| subtreeFlags & TransformFlags.ContainsDecorators
|
||||
|| (subtreeFlags & TransformFlags.ContainsTypeScriptClassSyntax && some(node.decorators))
|
||||
|| isThisIdentifier(name)) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
// If a parameter has an accessibility modifier, then it is TypeScript syntax.
|
||||
if (hasModifier(node, ModifierFlags.ParameterPropertyModifier)) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.ContainsParameterPropertyAssignments;
|
||||
transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.ContainsTypeScriptClassSyntax;
|
||||
}
|
||||
|
||||
// parameters with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@@ -3128,7 +3195,7 @@ namespace ts {
|
||||
// TypeScript syntax.
|
||||
// An exported declaration may be TypeScript syntax, but is handled by the visitor
|
||||
// for a namespace declaration.
|
||||
if ((subtreeFlags & TransformFlags.TypeScriptClassSyntaxMask)
|
||||
if ((subtreeFlags & TransformFlags.ContainsTypeScriptClassSyntax)
|
||||
|| node.typeParameters) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
@@ -3150,7 +3217,7 @@ namespace ts {
|
||||
|
||||
// A class with a parameter property assignment, property initializer, or decorator is
|
||||
// TypeScript syntax.
|
||||
if (subtreeFlags & TransformFlags.TypeScriptClassSyntaxMask
|
||||
if (subtreeFlags & TransformFlags.ContainsTypeScriptClassSyntax
|
||||
|| node.typeParameters) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
@@ -3227,7 +3294,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// function declarations with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@@ -3251,7 +3318,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// function declarations with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@@ -3282,7 +3349,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// function declarations with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@@ -3297,7 +3364,7 @@ namespace ts {
|
||||
// If the PropertyDeclaration has an initializer or a computed name, we need to inform its ancestor
|
||||
// so that it handle the transformation.
|
||||
if (node.initializer || isComputedPropertyName(node.name)) {
|
||||
transformFlags |= TransformFlags.ContainsPropertyInitializer;
|
||||
transformFlags |= TransformFlags.ContainsTypeScriptClassSyntax;
|
||||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
@@ -3331,7 +3398,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// function declarations with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@@ -3373,7 +3440,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// function expressions with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@@ -3414,7 +3481,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// arrow functions with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@@ -3434,7 +3501,9 @@ namespace ts {
|
||||
// ES6 syntax, and requires a lexical `this` binding.
|
||||
if (transformFlags & TransformFlags.Super) {
|
||||
transformFlags ^= TransformFlags.Super;
|
||||
transformFlags |= TransformFlags.ContainsSuper;
|
||||
// super inside of an async function requires hoisting the super access (ES2017).
|
||||
// same for super inside of an async generator, which is ESNext.
|
||||
transformFlags |= TransformFlags.ContainsSuper | TransformFlags.ContainsES2017 | TransformFlags.ContainsESNext;
|
||||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
@@ -3450,7 +3519,9 @@ namespace ts {
|
||||
// ES6 syntax, and requires a lexical `this` binding.
|
||||
if (expressionFlags & TransformFlags.Super) {
|
||||
transformFlags &= ~TransformFlags.Super;
|
||||
transformFlags |= TransformFlags.ContainsSuper;
|
||||
// super inside of an async function requires hoisting the super access (ES2017).
|
||||
// same for super inside of an async generator, which is ESNext.
|
||||
transformFlags |= TransformFlags.ContainsSuper | TransformFlags.ContainsES2017 | TransformFlags.ContainsESNext;
|
||||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
@@ -3462,7 +3533,7 @@ namespace ts {
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern;
|
||||
|
||||
// A VariableDeclaration containing ObjectRest is ESNext syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@@ -3636,6 +3707,10 @@ namespace ts {
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
break;
|
||||
|
||||
case SyntaxKind.ForOfStatement:
|
||||
// This node is either ES2015 syntax or ES2017 syntax (if it is a for-await-of).
|
||||
if ((<ForOfStatement>node).awaitModifier) {
|
||||
@@ -3652,6 +3727,7 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.AnyKeyword:
|
||||
case SyntaxKind.NumberKeyword:
|
||||
case SyntaxKind.BigIntKeyword:
|
||||
case SyntaxKind.NeverKeyword:
|
||||
case SyntaxKind.ObjectKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
@@ -3711,11 +3787,11 @@ namespace ts {
|
||||
break;
|
||||
|
||||
case SyntaxKind.SpreadElement:
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsSpread;
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsRestOrSpread;
|
||||
break;
|
||||
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
transformFlags |= TransformFlags.AssertESNext | TransformFlags.ContainsObjectSpread;
|
||||
transformFlags |= TransformFlags.AssertESNext | TransformFlags.ContainsObjectRestOrSpread;
|
||||
break;
|
||||
|
||||
case SyntaxKind.SuperKeyword:
|
||||
@@ -3731,8 +3807,8 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern;
|
||||
if (subtreeFlags & TransformFlags.ContainsRest) {
|
||||
transformFlags |= TransformFlags.AssertESNext | TransformFlags.ContainsObjectRest;
|
||||
if (subtreeFlags & TransformFlags.ContainsRestOrSpread) {
|
||||
transformFlags |= TransformFlags.AssertESNext | TransformFlags.ContainsObjectRestOrSpread;
|
||||
}
|
||||
excludeFlags = TransformFlags.BindingPatternExcludes;
|
||||
break;
|
||||
@@ -3745,13 +3821,13 @@ namespace ts {
|
||||
case SyntaxKind.BindingElement:
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
if ((<BindingElement>node).dotDotDotToken) {
|
||||
transformFlags |= TransformFlags.ContainsRest;
|
||||
transformFlags |= TransformFlags.ContainsRestOrSpread;
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.Decorator:
|
||||
// This node is TypeScript syntax, and marks its container as also being TypeScript syntax.
|
||||
transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.ContainsDecorators;
|
||||
transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.ContainsTypeScriptClassSyntax;
|
||||
break;
|
||||
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
@@ -3768,7 +3844,7 @@ namespace ts {
|
||||
transformFlags |= TransformFlags.ContainsLexicalThis;
|
||||
}
|
||||
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectSpread) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
// If an ObjectLiteralExpression contains a spread element, then it
|
||||
// is an ES next node.
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
@@ -3779,7 +3855,7 @@ namespace ts {
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
excludeFlags = TransformFlags.ArrayLiteralOrCallOrNewExcludes;
|
||||
if (subtreeFlags & TransformFlags.ContainsSpread) {
|
||||
if (subtreeFlags & TransformFlags.ContainsRestOrSpread) {
|
||||
// If the this node contains a SpreadExpression, then it is an ES6
|
||||
// node.
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
@@ -3827,7 +3903,6 @@ namespace ts {
|
||||
* For performance reasons, `computeTransformFlagsForNode` uses local constant values rather
|
||||
* than calling this function.
|
||||
*/
|
||||
/* @internal */
|
||||
export function getTransformFlagsSubtreeExclusions(kind: SyntaxKind) {
|
||||
if (kind >= SyntaxKind.FirstTypeNode && kind <= SyntaxKind.LastTypeNode) {
|
||||
return TransformFlags.TypeExcludes;
|
||||
@@ -3860,6 +3935,7 @@ namespace ts {
|
||||
return TransformFlags.MethodOrAccessorExcludes;
|
||||
case SyntaxKind.AnyKeyword:
|
||||
case SyntaxKind.NumberKeyword:
|
||||
case SyntaxKind.BigIntKeyword:
|
||||
case SyntaxKind.NeverKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
case SyntaxKind.ObjectKeyword:
|
||||
|
||||
+159
-19
@@ -30,10 +30,22 @@ namespace ts {
|
||||
* These will be commited whenever the iteration through affected files of current changed file is complete
|
||||
*/
|
||||
currentAffectedFilesSignatures: Map<string> | undefined;
|
||||
/**
|
||||
* Newly computed visible to outside referencedSet
|
||||
*/
|
||||
currentAffectedFilesExportedModulesMap: BuilderState.ComputingExportedModulesMap | undefined;
|
||||
/**
|
||||
* Already seen affected files
|
||||
*/
|
||||
seenAffectedFiles: Map<true> | undefined;
|
||||
/**
|
||||
* whether this program has cleaned semantic diagnostics cache for lib files
|
||||
*/
|
||||
cleanedDiagnosticsOfLibFiles?: boolean;
|
||||
/**
|
||||
* True if the semantic diagnostics were copied from the old state
|
||||
*/
|
||||
semanticDiagnosticsFromOldState?: Map<true>;
|
||||
/**
|
||||
* program corresponding to this state
|
||||
*/
|
||||
@@ -56,8 +68,11 @@ namespace ts {
|
||||
state.semanticDiagnosticsPerFile = createMap<ReadonlyArray<Diagnostic>>();
|
||||
}
|
||||
state.changedFilesSet = createMap<true>();
|
||||
|
||||
const useOldState = BuilderState.canReuseOldState(state.referencedMap, oldState);
|
||||
const canCopySemanticDiagnostics = useOldState && oldState!.semanticDiagnosticsPerFile && !!state.semanticDiagnosticsPerFile;
|
||||
const oldCompilerOptions = useOldState ? oldState!.program.getCompilerOptions() : undefined;
|
||||
const canCopySemanticDiagnostics = useOldState && oldState!.semanticDiagnosticsPerFile && !!state.semanticDiagnosticsPerFile &&
|
||||
!compilerOptionsAffectSemanticDiagnostics(compilerOptions, oldCompilerOptions!);
|
||||
if (useOldState) {
|
||||
// Verify the sanity of old state
|
||||
if (!oldState!.currentChangedFilePath) {
|
||||
@@ -74,6 +89,8 @@ namespace ts {
|
||||
// Update changed files and copy semantic diagnostics if we can
|
||||
const referencedMap = state.referencedMap;
|
||||
const oldReferencedMap = useOldState ? oldState!.referencedMap : undefined;
|
||||
const copyDeclarationFileDiagnostics = canCopySemanticDiagnostics && !compilerOptions.skipLibCheck === !oldCompilerOptions!.skipLibCheck;
|
||||
const copyLibFileDiagnostics = copyDeclarationFileDiagnostics && !compilerOptions.skipDefaultLibCheck === !oldCompilerOptions!.skipDefaultLibCheck;
|
||||
state.fileInfos.forEach((info, sourceFilePath) => {
|
||||
let oldInfo: Readonly<BuilderState.FileInfo> | undefined;
|
||||
let newReferences: BuilderState.ReferencedSet | undefined;
|
||||
@@ -92,10 +109,19 @@ namespace ts {
|
||||
state.changedFilesSet.set(sourceFilePath, true);
|
||||
}
|
||||
else if (canCopySemanticDiagnostics) {
|
||||
const sourceFile = state.program.getSourceFileByPath(sourceFilePath as Path)!;
|
||||
|
||||
if (sourceFile.isDeclarationFile && !copyDeclarationFileDiagnostics) { return; }
|
||||
if (sourceFile.hasNoDefaultLib && !copyLibFileDiagnostics) { return; }
|
||||
|
||||
// Unchanged file copy diagnostics
|
||||
const diagnostics = oldState!.semanticDiagnosticsPerFile!.get(sourceFilePath);
|
||||
if (diagnostics) {
|
||||
state.semanticDiagnosticsPerFile!.set(sourceFilePath, diagnostics);
|
||||
if (!state.semanticDiagnosticsFromOldState) {
|
||||
state.semanticDiagnosticsFromOldState = createMap<true>();
|
||||
}
|
||||
state.semanticDiagnosticsFromOldState.set(sourceFilePath, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -120,17 +146,17 @@ namespace ts {
|
||||
while (true) {
|
||||
const { affectedFiles } = state;
|
||||
if (affectedFiles) {
|
||||
const { seenAffectedFiles, semanticDiagnosticsPerFile } = state;
|
||||
const seenAffectedFiles = state.seenAffectedFiles!;
|
||||
let affectedFilesIndex = state.affectedFilesIndex!; // TODO: GH#18217
|
||||
while (affectedFilesIndex < affectedFiles.length) {
|
||||
const affectedFile = affectedFiles[affectedFilesIndex];
|
||||
if (!seenAffectedFiles!.has(affectedFile.path)) {
|
||||
if (!seenAffectedFiles.has(affectedFile.path)) {
|
||||
// Set the next affected file as seen and remove the cached semantic diagnostics
|
||||
state.affectedFilesIndex = affectedFilesIndex;
|
||||
semanticDiagnosticsPerFile!.delete(affectedFile.path);
|
||||
cleanSemanticDiagnosticsOfAffectedFile(state, affectedFile);
|
||||
return affectedFile;
|
||||
}
|
||||
seenAffectedFiles!.set(affectedFile.path, true);
|
||||
seenAffectedFiles.set(affectedFile.path, true);
|
||||
affectedFilesIndex++;
|
||||
}
|
||||
|
||||
@@ -140,6 +166,7 @@ namespace ts {
|
||||
// Commit the changes in file signature
|
||||
BuilderState.updateSignaturesFromCache(state, state.currentAffectedFilesSignatures!);
|
||||
state.currentAffectedFilesSignatures!.clear();
|
||||
BuilderState.updateExportedFilesMapFromCache(state, state.currentAffectedFilesExportedModulesMap);
|
||||
state.affectedFiles = undefined;
|
||||
}
|
||||
|
||||
@@ -160,14 +187,120 @@ namespace ts {
|
||||
|
||||
// Get next batch of affected files
|
||||
state.currentAffectedFilesSignatures = state.currentAffectedFilesSignatures || createMap();
|
||||
state.affectedFiles = BuilderState.getFilesAffectedBy(state, state.program, nextKey.value as Path, cancellationToken, computeHash, state.currentAffectedFilesSignatures);
|
||||
if (state.exportedModulesMap) {
|
||||
state.currentAffectedFilesExportedModulesMap = state.currentAffectedFilesExportedModulesMap || createMap<BuilderState.ReferencedSet | false>();
|
||||
}
|
||||
state.affectedFiles = BuilderState.getFilesAffectedBy(state, state.program, nextKey.value as Path, cancellationToken, computeHash, state.currentAffectedFilesSignatures, state.currentAffectedFilesExportedModulesMap);
|
||||
state.currentChangedFilePath = nextKey.value as Path;
|
||||
state.semanticDiagnosticsPerFile!.delete(nextKey.value as Path);
|
||||
state.affectedFilesIndex = 0;
|
||||
state.seenAffectedFiles = state.seenAffectedFiles || createMap<true>();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the semantic diagnostics cached from old state for affected File and the files that are referencing modules that export entities from affected file
|
||||
*/
|
||||
function cleanSemanticDiagnosticsOfAffectedFile(state: BuilderProgramState, affectedFile: SourceFile) {
|
||||
if (removeSemanticDiagnosticsOf(state, affectedFile.path)) {
|
||||
// If there are no more diagnostics from old cache, done
|
||||
return;
|
||||
}
|
||||
|
||||
// Clean lib file diagnostics if its all files excluding default files to emit
|
||||
if (state.allFilesExcludingDefaultLibraryFile === state.affectedFiles && !state.cleanedDiagnosticsOfLibFiles) {
|
||||
state.cleanedDiagnosticsOfLibFiles = true;
|
||||
const options = state.program.getCompilerOptions();
|
||||
if (forEach(state.program.getSourceFiles(), f =>
|
||||
state.program.isSourceFileDefaultLibrary(f) &&
|
||||
!skipTypeChecking(f, options) &&
|
||||
removeSemanticDiagnosticsOf(state, f.path)
|
||||
)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If there was change in signature for the changed file,
|
||||
// then delete the semantic diagnostics for files that are affected by using exports of this module
|
||||
|
||||
if (!state.exportedModulesMap || state.affectedFiles!.length === 1 || !state.changedFilesSet.has(affectedFile.path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.assert(!!state.currentAffectedFilesExportedModulesMap);
|
||||
const seenFileAndExportsOfFile = createMap<true>();
|
||||
// Go through exported modules from cache first
|
||||
// If exported modules has path, all files referencing file exported from are affected
|
||||
if (forEachEntry(state.currentAffectedFilesExportedModulesMap!, (exportedModules, exportedFromPath) =>
|
||||
exportedModules &&
|
||||
exportedModules.has(affectedFile.path) &&
|
||||
removeSemanticDiagnosticsOfFilesReferencingPath(state, exportedFromPath as Path, seenFileAndExportsOfFile)
|
||||
)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If exported from path is not from cache and exported modules has path, all files referencing file exported from are affected
|
||||
forEachEntry(state.exportedModulesMap, (exportedModules, exportedFromPath) =>
|
||||
!state.currentAffectedFilesExportedModulesMap!.has(exportedFromPath) && // If we already iterated this through cache, ignore it
|
||||
exportedModules.has(affectedFile.path) &&
|
||||
removeSemanticDiagnosticsOfFilesReferencingPath(state, exportedFromPath as Path, seenFileAndExportsOfFile)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* removes the semantic diagnostics of files referencing referencedPath and
|
||||
* returns true if there are no more semantic diagnostics from old state
|
||||
*/
|
||||
function removeSemanticDiagnosticsOfFilesReferencingPath(state: BuilderProgramState, referencedPath: Path, seenFileAndExportsOfFile: Map<true>) {
|
||||
return forEachEntry(state.referencedMap!, (referencesInFile, filePath) =>
|
||||
referencesInFile.has(referencedPath) && removeSemanticDiagnosticsOfFileAndExportsOfFile(state, filePath as Path, seenFileAndExportsOfFile)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes semantic diagnostics of file and anything that exports this file
|
||||
*/
|
||||
function removeSemanticDiagnosticsOfFileAndExportsOfFile(state: BuilderProgramState, filePath: Path, seenFileAndExportsOfFile: Map<true>): boolean {
|
||||
if (!addToSeen(seenFileAndExportsOfFile, filePath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (removeSemanticDiagnosticsOf(state, filePath)) {
|
||||
// If there are no more diagnostics from old cache, done
|
||||
return true;
|
||||
}
|
||||
|
||||
Debug.assert(!!state.currentAffectedFilesExportedModulesMap);
|
||||
// Go through exported modules from cache first
|
||||
// If exported modules has path, all files referencing file exported from are affected
|
||||
if (forEachEntry(state.currentAffectedFilesExportedModulesMap!, (exportedModules, exportedFromPath) =>
|
||||
exportedModules &&
|
||||
exportedModules.has(filePath) &&
|
||||
removeSemanticDiagnosticsOfFileAndExportsOfFile(state, exportedFromPath as Path, seenFileAndExportsOfFile)
|
||||
)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If exported from path is not from cache and exported modules has path, all files referencing file exported from are affected
|
||||
return !!forEachEntry(state.exportedModulesMap!, (exportedModules, exportedFromPath) =>
|
||||
!state.currentAffectedFilesExportedModulesMap!.has(exportedFromPath) && // If we already iterated this through cache, ignore it
|
||||
exportedModules.has(filePath) &&
|
||||
removeSemanticDiagnosticsOfFileAndExportsOfFile(state, exportedFromPath as Path, seenFileAndExportsOfFile)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes semantic diagnostics for path and
|
||||
* returns true if there are no more semantic diagnostics from the old state
|
||||
*/
|
||||
function removeSemanticDiagnosticsOf(state: BuilderProgramState, path: Path) {
|
||||
if (!state.semanticDiagnosticsFromOldState) {
|
||||
return true;
|
||||
}
|
||||
state.semanticDiagnosticsFromOldState.delete(path);
|
||||
state.semanticDiagnosticsPerFile!.delete(path);
|
||||
return !state.semanticDiagnosticsFromOldState.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called after completing operation on the next affected file.
|
||||
* The operations here are postponed to ensure that cancellation during the iteration is handled correctly
|
||||
@@ -220,7 +353,7 @@ namespace ts {
|
||||
configFileParsingDiagnostics: ReadonlyArray<Diagnostic>;
|
||||
}
|
||||
|
||||
export function getBuilderCreationParameters(newProgramOrRootNames: Program | ReadonlyArray<string> | undefined, hostOrOptions: BuilderProgramHost | CompilerOptions | undefined, oldProgramOrHost?: BuilderProgram | CompilerHost, configFileParsingDiagnosticsOrOldProgram?: ReadonlyArray<Diagnostic> | BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): BuilderCreationParameters {
|
||||
export function getBuilderCreationParameters(newProgramOrRootNames: Program | ReadonlyArray<string> | undefined, hostOrOptions: BuilderProgramHost | CompilerOptions | undefined, oldProgramOrHost?: BuilderProgram | CompilerHost, configFileParsingDiagnosticsOrOldProgram?: ReadonlyArray<Diagnostic> | BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>, projectReferences?: ReadonlyArray<ProjectReference>): BuilderCreationParameters {
|
||||
let host: BuilderProgramHost;
|
||||
let newProgram: Program;
|
||||
let oldProgram: BuilderProgram;
|
||||
@@ -233,7 +366,14 @@ namespace ts {
|
||||
}
|
||||
else if (isArray(newProgramOrRootNames)) {
|
||||
oldProgram = configFileParsingDiagnosticsOrOldProgram as BuilderProgram;
|
||||
newProgram = createProgram(newProgramOrRootNames, hostOrOptions as CompilerOptions, oldProgramOrHost as CompilerHost, oldProgram && oldProgram.getProgram(), configFileParsingDiagnostics);
|
||||
newProgram = createProgram({
|
||||
rootNames: newProgramOrRootNames,
|
||||
options: hostOrOptions as CompilerOptions,
|
||||
host: oldProgramOrHost as CompilerHost,
|
||||
oldProgram: oldProgram && oldProgram.getProgram(),
|
||||
configFileParsingDiagnostics,
|
||||
projectReferences
|
||||
});
|
||||
host = oldProgramOrHost as CompilerHost;
|
||||
}
|
||||
else {
|
||||
@@ -336,7 +476,7 @@ namespace ts {
|
||||
assertSourceFileOkWithoutNextAffectedCall(state, targetSourceFile);
|
||||
if (!targetSourceFile) {
|
||||
// Emit and report any errors we ran into.
|
||||
let sourceMaps: SourceMapData[] = [];
|
||||
let sourceMaps: SourceMapEmitResult[] = [];
|
||||
let emitSkipped = false;
|
||||
let diagnostics: Diagnostic[] | undefined;
|
||||
let emittedFiles: string[] = [];
|
||||
@@ -549,9 +689,9 @@ namespace ts {
|
||||
* Create the builder to manage semantic diagnostics and cache them
|
||||
*/
|
||||
export function createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): SemanticDiagnosticsBuilderProgram;
|
||||
export function createSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): SemanticDiagnosticsBuilderProgram;
|
||||
export function createSemanticDiagnosticsBuilderProgram(newProgramOrRootNames: Program | ReadonlyArray<string> | undefined, hostOrOptions: BuilderProgramHost | CompilerOptions | undefined, oldProgramOrHost?: CompilerHost | SemanticDiagnosticsBuilderProgram, configFileParsingDiagnosticsOrOldProgram?: ReadonlyArray<Diagnostic> | SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>) {
|
||||
return createBuilderProgram(BuilderProgramKind.SemanticDiagnosticsBuilderProgram, getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics));
|
||||
export function createSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>, projectReferences?: ReadonlyArray<ProjectReference>): SemanticDiagnosticsBuilderProgram;
|
||||
export function createSemanticDiagnosticsBuilderProgram(newProgramOrRootNames: Program | ReadonlyArray<string> | undefined, hostOrOptions: BuilderProgramHost | CompilerOptions | undefined, oldProgramOrHost?: CompilerHost | SemanticDiagnosticsBuilderProgram, configFileParsingDiagnosticsOrOldProgram?: ReadonlyArray<Diagnostic> | SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>, projectReferences?: ReadonlyArray<ProjectReference>) {
|
||||
return createBuilderProgram(BuilderProgramKind.SemanticDiagnosticsBuilderProgram, getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -559,18 +699,18 @@ namespace ts {
|
||||
* to emit the those files and manage semantic diagnostics cache as well
|
||||
*/
|
||||
export function createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): EmitAndSemanticDiagnosticsBuilderProgram;
|
||||
export function createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): EmitAndSemanticDiagnosticsBuilderProgram;
|
||||
export function createEmitAndSemanticDiagnosticsBuilderProgram(newProgramOrRootNames: Program | ReadonlyArray<string> | undefined, hostOrOptions: BuilderProgramHost | CompilerOptions | undefined, oldProgramOrHost?: CompilerHost | EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnosticsOrOldProgram?: ReadonlyArray<Diagnostic> | EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>) {
|
||||
return createBuilderProgram(BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram, getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics));
|
||||
export function createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>, projectReferences?: ReadonlyArray<ProjectReference>): EmitAndSemanticDiagnosticsBuilderProgram;
|
||||
export function createEmitAndSemanticDiagnosticsBuilderProgram(newProgramOrRootNames: Program | ReadonlyArray<string> | undefined, hostOrOptions: BuilderProgramHost | CompilerOptions | undefined, oldProgramOrHost?: CompilerHost | EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnosticsOrOldProgram?: ReadonlyArray<Diagnostic> | EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>, projectReferences?: ReadonlyArray<ProjectReference>) {
|
||||
return createBuilderProgram(BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram, getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a builder thats just abstraction over program and can be used with watch
|
||||
*/
|
||||
export function createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): BuilderProgram;
|
||||
export function createAbstractBuilder(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): BuilderProgram;
|
||||
export function createAbstractBuilder(newProgramOrRootNames: Program | ReadonlyArray<string> | undefined, hostOrOptions: BuilderProgramHost | CompilerOptions | undefined, oldProgramOrHost?: CompilerHost | BuilderProgram, configFileParsingDiagnosticsOrOldProgram?: ReadonlyArray<Diagnostic> | BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): BuilderProgram {
|
||||
const { newProgram: program } = getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics);
|
||||
export function createAbstractBuilder(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>, projectReferences?: ReadonlyArray<ProjectReference>): BuilderProgram;
|
||||
export function createAbstractBuilder(newProgramOrRootNames: Program | ReadonlyArray<string> | undefined, hostOrOptions: BuilderProgramHost | CompilerOptions | undefined, oldProgramOrHost?: CompilerHost | BuilderProgram, configFileParsingDiagnosticsOrOldProgram?: ReadonlyArray<Diagnostic> | BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>, projectReferences?: ReadonlyArray<ProjectReference>): BuilderProgram {
|
||||
const { newProgram: program } = getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences);
|
||||
return {
|
||||
// Only return program, all other methods are not implemented
|
||||
getProgram: () => program,
|
||||
|
||||
+158
-17
@@ -2,6 +2,7 @@ namespace ts {
|
||||
export interface EmitOutput {
|
||||
outputFiles: OutputFile[];
|
||||
emitSkipped: boolean;
|
||||
/* @internal */ exportedModulesFromDeclarationEmit?: ExportedModulesFromDeclarationEmit;
|
||||
}
|
||||
|
||||
export interface OutputFile {
|
||||
@@ -17,7 +18,7 @@ namespace ts {
|
||||
cancellationToken?: CancellationToken, customTransformers?: CustomTransformers): EmitOutput {
|
||||
const outputFiles: OutputFile[] = [];
|
||||
const emitResult = program.emit(sourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers);
|
||||
return { outputFiles, emitSkipped: emitResult.emitSkipped };
|
||||
return { outputFiles, emitSkipped: emitResult.emitSkipped, exportedModulesFromDeclarationEmit: emitResult.exportedModulesFromDeclarationEmit };
|
||||
|
||||
function writeFile(fileName: string, text: string, writeByteOrderMark: boolean) {
|
||||
outputFiles.push({ name: fileName, writeByteOrderMark, text });
|
||||
@@ -35,6 +36,11 @@ namespace ts {
|
||||
* Thus non undefined value indicates, module emit
|
||||
*/
|
||||
readonly referencedMap: ReadonlyMap<BuilderState.ReferencedSet> | undefined;
|
||||
/**
|
||||
* Contains the map of exported modules ReferencedSet=exorted module files from the file if module emit is enabled
|
||||
* Otherwise undefined
|
||||
*/
|
||||
readonly exportedModulesMap: Map<BuilderState.ReferencedSet> | undefined;
|
||||
/**
|
||||
* Map of files that have already called update signature.
|
||||
* That means hence forth these files are assumed to have
|
||||
@@ -70,6 +76,37 @@ namespace ts.BuilderState {
|
||||
*/
|
||||
export type ComputeHash = (data: string) => string;
|
||||
|
||||
/**
|
||||
* Exported modules to from declaration emit being computed.
|
||||
* This can contain false in the affected file path to specify that there are no exported module(types from other modules) for this file
|
||||
*/
|
||||
export type ComputingExportedModulesMap = Map<ReferencedSet | false>;
|
||||
|
||||
/**
|
||||
* Get the referencedFile from the imported module symbol
|
||||
*/
|
||||
function getReferencedFileFromImportedModuleSymbol(symbol: Symbol) {
|
||||
if (symbol.declarations && symbol.declarations[0]) {
|
||||
const declarationSourceFile = getSourceFileOfNode(symbol.declarations[0]);
|
||||
return declarationSourceFile && declarationSourceFile.resolvedPath;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the referencedFile from the import name node from file
|
||||
*/
|
||||
function getReferencedFileFromImportLiteral(checker: TypeChecker, importName: StringLiteralLike) {
|
||||
const symbol = checker.getSymbolAtLocation(importName);
|
||||
return symbol && getReferencedFileFromImportedModuleSymbol(symbol);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path to reference file from file name, it could be resolvedPath if present otherwise path
|
||||
*/
|
||||
function getReferencedFileFromFileName(program: Program, fileName: string, sourceFileDirectory: Path, getCanonicalFileName: GetCanonicalFileName): Path {
|
||||
return toPath(program.getProjectReferenceRedirect(fileName) || fileName, sourceFileDirectory, getCanonicalFileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the referenced files for a file from the program with values for the keys as referenced file's path to be true
|
||||
*/
|
||||
@@ -82,12 +119,9 @@ namespace ts.BuilderState {
|
||||
if (sourceFile.imports && sourceFile.imports.length > 0) {
|
||||
const checker: TypeChecker = program.getTypeChecker();
|
||||
for (const importName of sourceFile.imports) {
|
||||
const symbol = checker.getSymbolAtLocation(importName);
|
||||
if (symbol && symbol.declarations && symbol.declarations[0]) {
|
||||
const declarationSourceFile = getSourceFileOfNode(symbol.declarations[0]);
|
||||
if (declarationSourceFile) {
|
||||
addReferencedFile(declarationSourceFile.path);
|
||||
}
|
||||
const declarationSourceFilePath = getReferencedFileFromImportLiteral(checker, importName);
|
||||
if (declarationSourceFilePath) {
|
||||
addReferencedFile(declarationSourceFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -96,7 +130,7 @@ namespace ts.BuilderState {
|
||||
// Handle triple slash references
|
||||
if (sourceFile.referencedFiles && sourceFile.referencedFiles.length > 0) {
|
||||
for (const referencedFile of sourceFile.referencedFiles) {
|
||||
const referencedPath = toPath(referencedFile.fileName, sourceFileDirectory, getCanonicalFileName);
|
||||
const referencedPath = getReferencedFileFromFileName(program, referencedFile.fileName, sourceFileDirectory, getCanonicalFileName);
|
||||
addReferencedFile(referencedPath);
|
||||
}
|
||||
}
|
||||
@@ -109,13 +143,44 @@ namespace ts.BuilderState {
|
||||
}
|
||||
|
||||
const fileName = resolvedTypeReferenceDirective.resolvedFileName!; // TODO: GH#18217
|
||||
const typeFilePath = toPath(fileName, sourceFileDirectory, getCanonicalFileName);
|
||||
const typeFilePath = getReferencedFileFromFileName(program, fileName, sourceFileDirectory, getCanonicalFileName);
|
||||
addReferencedFile(typeFilePath);
|
||||
});
|
||||
}
|
||||
|
||||
// Add module augmentation as references
|
||||
if (sourceFile.moduleAugmentations.length) {
|
||||
const checker = program.getTypeChecker();
|
||||
for (const moduleName of sourceFile.moduleAugmentations) {
|
||||
if (!isStringLiteral(moduleName)) { continue; }
|
||||
const symbol = checker.getSymbolAtLocation(moduleName);
|
||||
if (!symbol) { continue; }
|
||||
|
||||
// Add any file other than our own as reference
|
||||
addReferenceFromAmbientModule(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
// From ambient modules
|
||||
for (const ambientModule of program.getTypeChecker().getAmbientModules()) {
|
||||
if (ambientModule.declarations.length > 1) {
|
||||
addReferenceFromAmbientModule(ambientModule);
|
||||
}
|
||||
}
|
||||
|
||||
return referencedFiles;
|
||||
|
||||
function addReferenceFromAmbientModule(symbol: Symbol) {
|
||||
// Add any file other than our own as reference
|
||||
for (const declaration of symbol.declarations) {
|
||||
const declarationSourceFile = getSourceFileOfNode(declaration);
|
||||
if (declarationSourceFile &&
|
||||
declarationSourceFile !== sourceFile) {
|
||||
addReferencedFile(declarationSourceFile.resolvedPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addReferencedFile(referencedPath: Path) {
|
||||
if (!referencedFiles) {
|
||||
referencedFiles = createMap<true>();
|
||||
@@ -137,6 +202,7 @@ namespace ts.BuilderState {
|
||||
export function create(newProgram: Program, getCanonicalFileName: GetCanonicalFileName, oldState?: Readonly<BuilderState>): BuilderState {
|
||||
const fileInfos = createMap<FileInfo>();
|
||||
const referencedMap = newProgram.getCompilerOptions().module !== ModuleKind.None ? createMap<ReferencedSet>() : undefined;
|
||||
const exportedModulesMap = referencedMap ? createMap<ReferencedSet>() : undefined;
|
||||
const hasCalledUpdateShapeSignature = createMap<true>();
|
||||
const useOldState = canReuseOldState(referencedMap, oldState);
|
||||
|
||||
@@ -149,6 +215,13 @@ namespace ts.BuilderState {
|
||||
if (newReferences) {
|
||||
referencedMap.set(sourceFile.path, newReferences);
|
||||
}
|
||||
// Copy old visible to outside files map
|
||||
if (useOldState) {
|
||||
const exportedModules = oldState!.exportedModulesMap!.get(sourceFile.path);
|
||||
if (exportedModules) {
|
||||
exportedModulesMap!.set(sourceFile.path, exportedModules);
|
||||
}
|
||||
}
|
||||
}
|
||||
fileInfos.set(sourceFile.path, { version, signature: oldInfo && oldInfo.signature });
|
||||
}
|
||||
@@ -156,6 +229,7 @@ namespace ts.BuilderState {
|
||||
return {
|
||||
fileInfos,
|
||||
referencedMap,
|
||||
exportedModulesMap,
|
||||
hasCalledUpdateShapeSignature,
|
||||
allFilesExcludingDefaultLibraryFile: undefined,
|
||||
allFileNames: undefined
|
||||
@@ -165,7 +239,7 @@ namespace ts.BuilderState {
|
||||
/**
|
||||
* Gets the files affected by the path from the program
|
||||
*/
|
||||
export function getFilesAffectedBy(state: BuilderState, programOfThisState: Program, path: Path, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash, cacheToUpdateSignature?: Map<string>): ReadonlyArray<SourceFile> {
|
||||
export function getFilesAffectedBy(state: BuilderState, programOfThisState: Program, path: Path, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash, cacheToUpdateSignature?: Map<string>, exportedModulesMapCache?: ComputingExportedModulesMap): ReadonlyArray<SourceFile> {
|
||||
// Since the operation could be cancelled, the signatures are always stored in the cache
|
||||
// They will be commited once it is safe to use them
|
||||
// eg when calling this api from tsserver, if there is no cancellation of the operation
|
||||
@@ -176,11 +250,11 @@ namespace ts.BuilderState {
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
if (!updateShapeSignature(state, programOfThisState, sourceFile, signatureCache, cancellationToken, computeHash)) {
|
||||
if (!updateShapeSignature(state, programOfThisState, sourceFile, signatureCache, cancellationToken, computeHash, exportedModulesMapCache)) {
|
||||
return [sourceFile];
|
||||
}
|
||||
|
||||
const result = (state.referencedMap ? getFilesAffectedByUpdatedShapeWhenModuleEmit : getFilesAffectedByUpdatedShapeWhenNonModuleEmit)(state, programOfThisState, sourceFile, signatureCache, cancellationToken, computeHash);
|
||||
const result = (state.referencedMap ? getFilesAffectedByUpdatedShapeWhenModuleEmit : getFilesAffectedByUpdatedShapeWhenNonModuleEmit)(state, programOfThisState, sourceFile, signatureCache, cancellationToken, computeHash, exportedModulesMapCache);
|
||||
if (!cacheToUpdateSignature) {
|
||||
// Commit all the signatures in the signature cache
|
||||
updateSignaturesFromCache(state, signatureCache);
|
||||
@@ -202,8 +276,9 @@ namespace ts.BuilderState {
|
||||
/**
|
||||
* Returns if the shape of the signature has changed since last emit
|
||||
*/
|
||||
function updateShapeSignature(state: Readonly<BuilderState>, programOfThisState: Program, sourceFile: SourceFile, cacheToUpdateSignature: Map<string>, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash) {
|
||||
function updateShapeSignature(state: Readonly<BuilderState>, programOfThisState: Program, sourceFile: SourceFile, cacheToUpdateSignature: Map<string>, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash, exportedModulesMapCache?: ComputingExportedModulesMap) {
|
||||
Debug.assert(!!sourceFile);
|
||||
Debug.assert(!exportedModulesMapCache || !!state.exportedModulesMap, "Compute visible to outside map only if visibleToOutsideReferencedMap present in the state");
|
||||
|
||||
// If we have cached the result for this file, that means hence forth we should assume file shape is uptodate
|
||||
if (state.hasCalledUpdateShapeSignature.has(sourceFile.path) || cacheToUpdateSignature.has(sourceFile.path)) {
|
||||
@@ -217,21 +292,71 @@ namespace ts.BuilderState {
|
||||
let latestSignature: string;
|
||||
if (sourceFile.isDeclarationFile) {
|
||||
latestSignature = sourceFile.version;
|
||||
if (exportedModulesMapCache && latestSignature !== prevSignature) {
|
||||
// All the references in this file are exported
|
||||
const references = state.referencedMap ? state.referencedMap.get(sourceFile.path) : undefined;
|
||||
exportedModulesMapCache.set(sourceFile.path, references || false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const emitOutput = getFileEmitOutput(programOfThisState, sourceFile, /*emitOnlyDtsFiles*/ true, cancellationToken);
|
||||
if (emitOutput.outputFiles && emitOutput.outputFiles.length > 0) {
|
||||
latestSignature = computeHash(emitOutput.outputFiles[0].text);
|
||||
if (exportedModulesMapCache && latestSignature !== prevSignature) {
|
||||
updateExportedModules(sourceFile, emitOutput.exportedModulesFromDeclarationEmit, exportedModulesMapCache);
|
||||
}
|
||||
}
|
||||
else {
|
||||
latestSignature = prevSignature!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
}
|
||||
cacheToUpdateSignature.set(sourceFile.path, latestSignature);
|
||||
|
||||
return !prevSignature || latestSignature !== prevSignature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Coverts the declaration emit result into exported modules map
|
||||
*/
|
||||
function updateExportedModules(sourceFile: SourceFile, exportedModulesFromDeclarationEmit: ExportedModulesFromDeclarationEmit | undefined, exportedModulesMapCache: ComputingExportedModulesMap) {
|
||||
if (!exportedModulesFromDeclarationEmit) {
|
||||
exportedModulesMapCache.set(sourceFile.path, false);
|
||||
return;
|
||||
}
|
||||
|
||||
let exportedModules: Map<true> | undefined;
|
||||
exportedModulesFromDeclarationEmit.forEach(symbol => addExportedModule(getReferencedFileFromImportedModuleSymbol(symbol)));
|
||||
exportedModulesMapCache.set(sourceFile.path, exportedModules || false);
|
||||
|
||||
function addExportedModule(exportedModulePath: Path | undefined) {
|
||||
if (exportedModulePath) {
|
||||
if (!exportedModules) {
|
||||
exportedModules = createMap<true>();
|
||||
}
|
||||
exportedModules.set(exportedModulePath, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the exported modules from cache into state's exported modules map
|
||||
* This should be called whenever it is safe to commit the state of the builder
|
||||
*/
|
||||
export function updateExportedFilesMapFromCache(state: BuilderState, exportedModulesMapCache: ComputingExportedModulesMap | undefined) {
|
||||
if (exportedModulesMapCache) {
|
||||
Debug.assert(!!state.exportedModulesMap);
|
||||
exportedModulesMapCache.forEach((exportedModules, path) => {
|
||||
if (exportedModules) {
|
||||
state.exportedModulesMap!.set(path, exportedModules);
|
||||
}
|
||||
else {
|
||||
state.exportedModulesMap!.delete(path);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the dependencies of the sourceFile
|
||||
*/
|
||||
@@ -243,7 +368,7 @@ namespace ts.BuilderState {
|
||||
}
|
||||
|
||||
// If this is non module emit, or its a global file, it depends on all the source files
|
||||
if (!state.referencedMap || (!isExternalModule(sourceFile) && !containsOnlyAmbientModules(sourceFile))) {
|
||||
if (!state.referencedMap || isFileAffectingGlobalScope(sourceFile)) {
|
||||
return getAllFileNames(state, programOfThisState);
|
||||
}
|
||||
|
||||
@@ -305,6 +430,22 @@ namespace ts.BuilderState {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if file contains anything that augments to global scope we need to build them as if
|
||||
* they are global files as well as module
|
||||
*/
|
||||
function containsGlobalScopeAugmentation(sourceFile: SourceFile) {
|
||||
return some(sourceFile.moduleAugmentations, augmentation => isGlobalScopeAugmentation(augmentation.parent as ModuleDeclaration));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the file will invalidate all files because it affectes global scope
|
||||
*/
|
||||
function isFileAffectingGlobalScope(sourceFile: SourceFile) {
|
||||
return containsGlobalScopeAugmentation(sourceFile) ||
|
||||
!isExternalModule(sourceFile) && !containsOnlyAmbientModules(sourceFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all files of the program excluding the default library file
|
||||
*/
|
||||
@@ -347,8 +488,8 @@ namespace ts.BuilderState {
|
||||
/**
|
||||
* When program emits modular code, gets the files affected by the sourceFile whose shape has changed
|
||||
*/
|
||||
function getFilesAffectedByUpdatedShapeWhenModuleEmit(state: BuilderState, programOfThisState: Program, sourceFileWithUpdatedShape: SourceFile, cacheToUpdateSignature: Map<string>, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash | undefined) {
|
||||
if (!isExternalModule(sourceFileWithUpdatedShape) && !containsOnlyAmbientModules(sourceFileWithUpdatedShape)) {
|
||||
function getFilesAffectedByUpdatedShapeWhenModuleEmit(state: BuilderState, programOfThisState: Program, sourceFileWithUpdatedShape: SourceFile, cacheToUpdateSignature: Map<string>, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash | undefined, exportedModulesMapCache: ComputingExportedModulesMap | undefined) {
|
||||
if (isFileAffectingGlobalScope(sourceFileWithUpdatedShape)) {
|
||||
return getAllFilesExcludingDefaultLibraryFile(state, programOfThisState, sourceFileWithUpdatedShape);
|
||||
}
|
||||
|
||||
@@ -370,7 +511,7 @@ namespace ts.BuilderState {
|
||||
if (!seenFileNamesMap.has(currentPath)) {
|
||||
const currentSourceFile = programOfThisState.getSourceFileByPath(currentPath)!;
|
||||
seenFileNamesMap.set(currentPath, currentSourceFile);
|
||||
if (currentSourceFile && updateShapeSignature(state, programOfThisState, currentSourceFile, cacheToUpdateSignature, cancellationToken, computeHash!)) { // TODO: GH#18217
|
||||
if (currentSourceFile && updateShapeSignature(state, programOfThisState, currentSourceFile, cacheToUpdateSignature, cancellationToken, computeHash!, exportedModulesMapCache)) { // TODO: GH#18217
|
||||
queue.push(...getReferencedByPaths(state, currentPath));
|
||||
}
|
||||
}
|
||||
|
||||
+4515
-3168
File diff suppressed because it is too large
Load Diff
+476
-176
File diff suppressed because it is too large
Load Diff
@@ -1,431 +0,0 @@
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
export interface CommentWriter {
|
||||
reset(): void;
|
||||
setSourceFile(sourceFile: SourceFile): void;
|
||||
setWriter(writer: EmitTextWriter | undefined): void;
|
||||
emitNodeWithComments(hint: EmitHint, node: Node | undefined, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
emitBodyWithDetachedComments(node: Node, detachedRange: TextRange, emitCallback: (node: Node) => void): void;
|
||||
emitTrailingCommentsOfPosition(pos: number, prefixSpace?: boolean): void;
|
||||
emitLeadingCommentsOfPosition(pos: number): void;
|
||||
}
|
||||
|
||||
export function createCommentWriter(printerOptions: PrinterOptions, emitPos: ((pos: number) => void) | undefined): CommentWriter {
|
||||
const extendedDiagnostics = printerOptions.extendedDiagnostics;
|
||||
const newLine = getNewLineCharacter(printerOptions);
|
||||
let writer: EmitTextWriter;
|
||||
let containerPos = -1;
|
||||
let containerEnd = -1;
|
||||
let declarationListContainerEnd = -1;
|
||||
let currentSourceFile: SourceFile;
|
||||
let currentText: string;
|
||||
let currentLineMap: ReadonlyArray<number>;
|
||||
let detachedCommentsInfo: { nodePos: number, detachedCommentEndPos: number}[] | undefined;
|
||||
let hasWrittenComment = false;
|
||||
let disabled: boolean = !!printerOptions.removeComments;
|
||||
|
||||
return {
|
||||
reset,
|
||||
setWriter,
|
||||
setSourceFile,
|
||||
emitNodeWithComments,
|
||||
emitBodyWithDetachedComments,
|
||||
emitTrailingCommentsOfPosition,
|
||||
emitLeadingCommentsOfPosition,
|
||||
};
|
||||
|
||||
function emitNodeWithComments(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
if (disabled) {
|
||||
emitCallback(hint, node);
|
||||
return;
|
||||
}
|
||||
|
||||
if (node) {
|
||||
hasWrittenComment = false;
|
||||
|
||||
const emitNode = node.emitNode;
|
||||
const emitFlags = emitNode && emitNode.flags || 0;
|
||||
const { pos, end } = emitNode && emitNode.commentRange || node;
|
||||
if ((pos < 0 && end < 0) || (pos === end)) {
|
||||
// Both pos and end are synthesized, so just emit the node without comments.
|
||||
emitNodeWithSynthesizedComments(hint, node, emitNode, emitFlags, emitCallback);
|
||||
}
|
||||
else {
|
||||
if (extendedDiagnostics) {
|
||||
performance.mark("preEmitNodeWithComment");
|
||||
}
|
||||
|
||||
const isEmittedNode = node.kind !== SyntaxKind.NotEmittedStatement;
|
||||
// We have to explicitly check that the node is JsxText because if the compilerOptions.jsx is "preserve" we will not do any transformation.
|
||||
// It is expensive to walk entire tree just to set one kind of node to have no comments.
|
||||
const skipLeadingComments = pos < 0 || (emitFlags & EmitFlags.NoLeadingComments) !== 0 || node.kind === SyntaxKind.JsxText;
|
||||
const skipTrailingComments = end < 0 || (emitFlags & EmitFlags.NoTrailingComments) !== 0 || node.kind === SyntaxKind.JsxText;
|
||||
|
||||
// Emit leading comments if the position is not synthesized and the node
|
||||
// has not opted out from emitting leading comments.
|
||||
if (!skipLeadingComments) {
|
||||
emitLeadingComments(pos, isEmittedNode);
|
||||
}
|
||||
|
||||
// Save current container state on the stack.
|
||||
const savedContainerPos = containerPos;
|
||||
const savedContainerEnd = containerEnd;
|
||||
const savedDeclarationListContainerEnd = declarationListContainerEnd;
|
||||
|
||||
if (!skipLeadingComments || (pos >= 0 && (emitFlags & EmitFlags.NoLeadingComments) !== 0)) {
|
||||
// Advance the container position of comments get emitted or if they've been disabled explicitly using NoLeadingComments.
|
||||
containerPos = pos;
|
||||
}
|
||||
|
||||
if (!skipTrailingComments || (end >= 0 && (emitFlags & EmitFlags.NoTrailingComments) !== 0)) {
|
||||
// As above.
|
||||
containerEnd = end;
|
||||
|
||||
// To avoid invalid comment emit in a down-level binding pattern, we
|
||||
// keep track of the last declaration list container's end
|
||||
if (node.kind === SyntaxKind.VariableDeclarationList) {
|
||||
declarationListContainerEnd = end;
|
||||
}
|
||||
}
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.measure("commentTime", "preEmitNodeWithComment");
|
||||
}
|
||||
|
||||
emitNodeWithSynthesizedComments(hint, node, emitNode, emitFlags, emitCallback);
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.mark("postEmitNodeWithComment");
|
||||
}
|
||||
|
||||
// Restore previous container state.
|
||||
containerPos = savedContainerPos;
|
||||
containerEnd = savedContainerEnd;
|
||||
declarationListContainerEnd = savedDeclarationListContainerEnd;
|
||||
|
||||
// Emit trailing comments if the position is not synthesized and the node
|
||||
// has not opted out from emitting leading comments and is an emitted node.
|
||||
if (!skipTrailingComments && isEmittedNode) {
|
||||
emitTrailingComments(end);
|
||||
}
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.measure("commentTime", "postEmitNodeWithComment");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emitNodeWithSynthesizedComments(hint: EmitHint, node: Node, emitNode: EmitNode | undefined, emitFlags: EmitFlags, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
const leadingComments = emitNode && emitNode.leadingComments;
|
||||
if (some(leadingComments)) {
|
||||
if (extendedDiagnostics) {
|
||||
performance.mark("preEmitNodeWithSynthesizedComments");
|
||||
}
|
||||
|
||||
forEach(leadingComments, emitLeadingSynthesizedComment);
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.measure("commentTime", "preEmitNodeWithSynthesizedComments");
|
||||
}
|
||||
}
|
||||
|
||||
emitNodeWithNestedComments(hint, node, emitFlags, emitCallback);
|
||||
|
||||
const trailingComments = emitNode && emitNode.trailingComments;
|
||||
if (some(trailingComments)) {
|
||||
if (extendedDiagnostics) {
|
||||
performance.mark("postEmitNodeWithSynthesizedComments");
|
||||
}
|
||||
|
||||
forEach(trailingComments, emitTrailingSynthesizedComment);
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.measure("commentTime", "postEmitNodeWithSynthesizedComments");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emitLeadingSynthesizedComment(comment: SynthesizedComment) {
|
||||
if (comment.kind === SyntaxKind.SingleLineCommentTrivia) {
|
||||
writer.writeLine();
|
||||
}
|
||||
writeSynthesizedComment(comment);
|
||||
if (comment.hasTrailingNewLine || comment.kind === SyntaxKind.SingleLineCommentTrivia) {
|
||||
writer.writeLine();
|
||||
}
|
||||
else {
|
||||
writer.write(" ");
|
||||
}
|
||||
}
|
||||
|
||||
function emitTrailingSynthesizedComment(comment: SynthesizedComment) {
|
||||
if (!writer.isAtStartOfLine()) {
|
||||
writer.write(" ");
|
||||
}
|
||||
writeSynthesizedComment(comment);
|
||||
if (comment.hasTrailingNewLine) {
|
||||
writer.writeLine();
|
||||
}
|
||||
}
|
||||
|
||||
function writeSynthesizedComment(comment: SynthesizedComment) {
|
||||
const text = formatSynthesizedComment(comment);
|
||||
const lineMap = comment.kind === SyntaxKind.MultiLineCommentTrivia ? computeLineStarts(text) : undefined;
|
||||
writeCommentRange(text, lineMap!, writer, 0, text.length, newLine);
|
||||
}
|
||||
|
||||
function formatSynthesizedComment(comment: SynthesizedComment) {
|
||||
return comment.kind === SyntaxKind.MultiLineCommentTrivia
|
||||
? `/*${comment.text}*/`
|
||||
: `//${comment.text}`;
|
||||
}
|
||||
|
||||
function emitNodeWithNestedComments(hint: EmitHint, node: Node, emitFlags: EmitFlags, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
if (emitFlags & EmitFlags.NoNestedComments) {
|
||||
disabled = true;
|
||||
emitCallback(hint, node);
|
||||
disabled = false;
|
||||
}
|
||||
else {
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
}
|
||||
|
||||
function emitBodyWithDetachedComments(node: Node, detachedRange: TextRange, emitCallback: (node: Node) => void) {
|
||||
if (extendedDiagnostics) {
|
||||
performance.mark("preEmitBodyWithDetachedComments");
|
||||
}
|
||||
|
||||
const { pos, end } = detachedRange;
|
||||
const emitFlags = getEmitFlags(node);
|
||||
const skipLeadingComments = pos < 0 || (emitFlags & EmitFlags.NoLeadingComments) !== 0;
|
||||
const skipTrailingComments = disabled || end < 0 || (emitFlags & EmitFlags.NoTrailingComments) !== 0;
|
||||
|
||||
if (!skipLeadingComments) {
|
||||
emitDetachedCommentsAndUpdateCommentsInfo(detachedRange);
|
||||
}
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.measure("commentTime", "preEmitBodyWithDetachedComments");
|
||||
}
|
||||
|
||||
if (emitFlags & EmitFlags.NoNestedComments && !disabled) {
|
||||
disabled = true;
|
||||
emitCallback(node);
|
||||
disabled = false;
|
||||
}
|
||||
else {
|
||||
emitCallback(node);
|
||||
}
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.mark("beginEmitBodyWithDetachedCommetns");
|
||||
}
|
||||
|
||||
if (!skipTrailingComments) {
|
||||
emitLeadingComments(detachedRange.end, /*isEmittedNode*/ true);
|
||||
if (hasWrittenComment && !writer.isAtStartOfLine()) {
|
||||
writer.writeLine();
|
||||
}
|
||||
}
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.measure("commentTime", "beginEmitBodyWithDetachedCommetns");
|
||||
}
|
||||
}
|
||||
|
||||
function emitLeadingComments(pos: number, isEmittedNode: boolean) {
|
||||
hasWrittenComment = false;
|
||||
|
||||
if (isEmittedNode) {
|
||||
forEachLeadingCommentToEmit(pos, emitLeadingComment);
|
||||
}
|
||||
else if (pos === 0) {
|
||||
// If the node will not be emitted in JS, remove all the comments(normal, pinned and ///) associated with the node,
|
||||
// unless it is a triple slash comment at the top of the file.
|
||||
// For Example:
|
||||
// /// <reference-path ...>
|
||||
// declare var x;
|
||||
// /// <reference-path ...>
|
||||
// interface F {}
|
||||
// The first /// will NOT be removed while the second one will be removed even though both node will not be emitted
|
||||
forEachLeadingCommentToEmit(pos, emitTripleSlashLeadingComment);
|
||||
}
|
||||
}
|
||||
|
||||
function emitTripleSlashLeadingComment(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) {
|
||||
if (isTripleSlashComment(commentPos, commentEnd)) {
|
||||
emitLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos);
|
||||
}
|
||||
}
|
||||
|
||||
function shouldWriteComment(text: string, pos: number) {
|
||||
if (printerOptions.onlyPrintJsDocStyle) {
|
||||
return (isJSDocLikeText(text, pos) || isPinnedComment(text, pos));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function emitLeadingComment(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) {
|
||||
if (!shouldWriteComment(currentText, commentPos)) return;
|
||||
if (!hasWrittenComment) {
|
||||
emitNewLineBeforeLeadingCommentOfPosition(currentLineMap, writer, rangePos, commentPos);
|
||||
hasWrittenComment = true;
|
||||
}
|
||||
|
||||
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
|
||||
if (emitPos) emitPos(commentPos);
|
||||
writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine);
|
||||
if (emitPos) emitPos(commentEnd);
|
||||
|
||||
if (hasTrailingNewLine) {
|
||||
writer.writeLine();
|
||||
}
|
||||
else if (kind === SyntaxKind.MultiLineCommentTrivia) {
|
||||
writer.write(" ");
|
||||
}
|
||||
}
|
||||
|
||||
function emitLeadingCommentsOfPosition(pos: number) {
|
||||
if (disabled || pos === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
emitLeadingComments(pos, /*isEmittedNode*/ true);
|
||||
}
|
||||
|
||||
function emitTrailingComments(pos: number) {
|
||||
forEachTrailingCommentToEmit(pos, emitTrailingComment);
|
||||
}
|
||||
|
||||
function emitTrailingComment(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean) {
|
||||
if (!shouldWriteComment(currentText, commentPos)) return;
|
||||
// trailing comments are emitted at space/*trailing comment1 */space/*trailing comment2*/
|
||||
if (!writer.isAtStartOfLine()) {
|
||||
writer.write(" ");
|
||||
}
|
||||
|
||||
if (emitPos) emitPos(commentPos);
|
||||
writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine);
|
||||
if (emitPos) emitPos(commentEnd);
|
||||
|
||||
if (hasTrailingNewLine) {
|
||||
writer.writeLine();
|
||||
}
|
||||
}
|
||||
|
||||
function emitTrailingCommentsOfPosition(pos: number, prefixSpace?: boolean) {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.mark("beforeEmitTrailingCommentsOfPosition");
|
||||
}
|
||||
|
||||
forEachTrailingCommentToEmit(pos, prefixSpace ? emitTrailingComment : emitTrailingCommentOfPosition);
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.measure("commentTime", "beforeEmitTrailingCommentsOfPosition");
|
||||
}
|
||||
}
|
||||
|
||||
function emitTrailingCommentOfPosition(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean) {
|
||||
// trailing comments of a position are emitted at /*trailing comment1 */space/*trailing comment*/space
|
||||
|
||||
if (emitPos) emitPos(commentPos);
|
||||
writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine);
|
||||
if (emitPos) emitPos(commentEnd);
|
||||
|
||||
if (hasTrailingNewLine) {
|
||||
writer.writeLine();
|
||||
}
|
||||
else {
|
||||
writer.write(" ");
|
||||
}
|
||||
}
|
||||
|
||||
function forEachLeadingCommentToEmit(pos: number, cb: (commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) => void) {
|
||||
// Emit the leading comments only if the container's pos doesn't match because the container should take care of emitting these comments
|
||||
if (containerPos === -1 || pos !== containerPos) {
|
||||
if (hasDetachedComments(pos)) {
|
||||
forEachLeadingCommentWithoutDetachedComments(cb);
|
||||
}
|
||||
else {
|
||||
forEachLeadingCommentRange(currentText, pos, cb, /*state*/ pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function forEachTrailingCommentToEmit(end: number, cb: (commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean) => void) {
|
||||
// Emit the trailing comments only if the container's end doesn't match because the container should take care of emitting these comments
|
||||
if (containerEnd === -1 || (end !== containerEnd && end !== declarationListContainerEnd)) {
|
||||
forEachTrailingCommentRange(currentText, end, cb);
|
||||
}
|
||||
}
|
||||
|
||||
function reset() {
|
||||
currentSourceFile = undefined!;
|
||||
currentText = undefined!;
|
||||
currentLineMap = undefined!;
|
||||
detachedCommentsInfo = undefined;
|
||||
}
|
||||
|
||||
function setWriter(output: EmitTextWriter): void {
|
||||
writer = output;
|
||||
}
|
||||
|
||||
function setSourceFile(sourceFile: SourceFile) {
|
||||
currentSourceFile = sourceFile;
|
||||
currentText = currentSourceFile.text;
|
||||
currentLineMap = getLineStarts(currentSourceFile);
|
||||
detachedCommentsInfo = undefined;
|
||||
}
|
||||
|
||||
function hasDetachedComments(pos: number) {
|
||||
return detachedCommentsInfo !== undefined && last(detachedCommentsInfo).nodePos === pos;
|
||||
}
|
||||
|
||||
function forEachLeadingCommentWithoutDetachedComments(cb: (commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) => void) {
|
||||
// get the leading comments from detachedPos
|
||||
const pos = last(detachedCommentsInfo!).detachedCommentEndPos;
|
||||
if (detachedCommentsInfo!.length - 1) {
|
||||
detachedCommentsInfo!.pop();
|
||||
}
|
||||
else {
|
||||
detachedCommentsInfo = undefined;
|
||||
}
|
||||
|
||||
forEachLeadingCommentRange(currentText, pos, cb, /*state*/ pos);
|
||||
}
|
||||
|
||||
function emitDetachedCommentsAndUpdateCommentsInfo(range: TextRange) {
|
||||
const currentDetachedCommentInfo = emitDetachedComments(currentText, currentLineMap, writer, writeComment, range, newLine, disabled);
|
||||
if (currentDetachedCommentInfo) {
|
||||
if (detachedCommentsInfo) {
|
||||
detachedCommentsInfo.push(currentDetachedCommentInfo);
|
||||
}
|
||||
else {
|
||||
detachedCommentsInfo = [currentDetachedCommentInfo];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function writeComment(text: string, lineMap: number[], writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) {
|
||||
if (!shouldWriteComment(currentText, commentPos)) return;
|
||||
if (emitPos) emitPos(commentPos);
|
||||
writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine);
|
||||
if (emitPos) emitPos(commentEnd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given comment is a triple-slash
|
||||
*
|
||||
* @return true if the comment is a triple-slash comment else false
|
||||
*/
|
||||
function isTripleSlashComment(commentPos: number, commentEnd: number) {
|
||||
return isRecognizedTripleSlashComment(currentText, commentPos, commentEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
+77
-36
@@ -1,7 +1,7 @@
|
||||
namespace ts {
|
||||
// WARNING: The script `configureNightly.ts` uses a regexp to parse out these values.
|
||||
// If changing the text in this section, be sure to test `configureNightly` too.
|
||||
export const versionMajorMinor = "3.1";
|
||||
export const versionMajorMinor = "3.3";
|
||||
/** The version of the TypeScript compiler release */
|
||||
export const version = `${versionMajorMinor}.0-dev`;
|
||||
}
|
||||
@@ -16,6 +16,10 @@ namespace ts {
|
||||
[index: string]: T;
|
||||
}
|
||||
|
||||
export interface SortedReadonlyArray<T> extends ReadonlyArray<T> {
|
||||
" __sortedArrayBrand": any;
|
||||
}
|
||||
|
||||
export interface SortedArray<T> extends Array<T> {
|
||||
" __sortedArrayBrand": any;
|
||||
}
|
||||
@@ -65,6 +69,7 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
export const emptyArray: never[] = [] as never[];
|
||||
|
||||
/** Create a MapLike with good performance. */
|
||||
function createDictionaryObject<T>(): MapLike<T> {
|
||||
@@ -107,13 +112,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
// The global Map object. This may not be available, so we must test for it.
|
||||
declare const Map: { new <T>(): Map<T> } | undefined;
|
||||
declare const Map: (new <T>() => Map<T>) | undefined;
|
||||
// Internet Explorer's Map doesn't support iteration, so don't use it.
|
||||
// tslint:disable-next-line no-in-operator variable-name
|
||||
export const MapCtr = typeof Map !== "undefined" && "entries" in Map.prototype ? Map : shimMap();
|
||||
|
||||
// Keep the class inside a function so it doesn't get compiled if it's not used.
|
||||
function shimMap(): { new <T>(): Map<T> } {
|
||||
function shimMap(): new <T>() => Map<T> {
|
||||
|
||||
class MapIterator<T, U extends (string | T | [string, T])> {
|
||||
private data: MapLike<T>;
|
||||
@@ -510,12 +515,27 @@ namespace ts {
|
||||
* @param array The array to map.
|
||||
* @param mapfn The callback used to map the result into one or more values.
|
||||
*/
|
||||
export function flatMap<T, U>(array: ReadonlyArray<T>, mapfn: (x: T, i: number) => U | ReadonlyArray<U> | undefined): U[];
|
||||
export function flatMap<T, U>(array: ReadonlyArray<T> | undefined, mapfn: (x: T, i: number) => U | ReadonlyArray<U> | undefined): U[] | undefined;
|
||||
export function flatMap<T, U>(array: ReadonlyArray<T> | undefined, mapfn: (x: T, i: number) => U | ReadonlyArray<U> | undefined): U[] | undefined {
|
||||
export function flatMap<T, U>(array: ReadonlyArray<T> | undefined, mapfn: (x: T, i: number) => U | ReadonlyArray<U> | undefined): ReadonlyArray<U> {
|
||||
let result: U[] | undefined;
|
||||
if (array) {
|
||||
result = [];
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const v = mapfn(array[i], i);
|
||||
if (v) {
|
||||
if (isArray(v)) {
|
||||
result = addRange(result, v);
|
||||
}
|
||||
else {
|
||||
result = append(result, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result || emptyArray;
|
||||
}
|
||||
|
||||
export function flatMapToMutable<T, U>(array: ReadonlyArray<T> | undefined, mapfn: (x: T, i: number) => U | ReadonlyArray<U> | undefined): U[] {
|
||||
const result: U[] = [];
|
||||
if (array) {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const v = mapfn(array[i], i);
|
||||
if (v) {
|
||||
@@ -789,11 +809,8 @@ namespace ts {
|
||||
* @param comparer An optional `Comparer` used to sort entries before comparison, though the
|
||||
* result will remain in the original order in `array`.
|
||||
*/
|
||||
export function deduplicate<T>(array: ReadonlyArray<T>, equalityComparer?: EqualityComparer<T>, comparer?: Comparer<T>): T[];
|
||||
export function deduplicate<T>(array: ReadonlyArray<T> | undefined, equalityComparer?: EqualityComparer<T>, comparer?: Comparer<T>): T[] | undefined;
|
||||
export function deduplicate<T>(array: ReadonlyArray<T> | undefined, equalityComparer: EqualityComparer<T>, comparer?: Comparer<T>): T[] | undefined {
|
||||
return !array ? undefined :
|
||||
array.length === 0 ? [] :
|
||||
export function deduplicate<T>(array: ReadonlyArray<T>, equalityComparer: EqualityComparer<T>, comparer?: Comparer<T>): T[] {
|
||||
return array.length === 0 ? [] :
|
||||
array.length === 1 ? array.slice() :
|
||||
comparer ? deduplicateRelational(array, equalityComparer, comparer) :
|
||||
deduplicateEquality(array, equalityComparer);
|
||||
@@ -802,11 +819,8 @@ namespace ts {
|
||||
/**
|
||||
* Deduplicates an array that has already been sorted.
|
||||
*/
|
||||
function deduplicateSorted<T>(array: ReadonlyArray<T>, comparer: EqualityComparer<T> | Comparer<T>): T[];
|
||||
function deduplicateSorted<T>(array: ReadonlyArray<T> | undefined, comparer: EqualityComparer<T> | Comparer<T>): T[] | undefined;
|
||||
function deduplicateSorted<T>(array: ReadonlyArray<T> | undefined, comparer: EqualityComparer<T> | Comparer<T>): T[] | undefined {
|
||||
if (!array) return undefined;
|
||||
if (array.length === 0) return [];
|
||||
function deduplicateSorted<T>(array: SortedReadonlyArray<T>, comparer: EqualityComparer<T> | Comparer<T>): SortedReadonlyArray<T> {
|
||||
if (array.length === 0) return emptyArray as any as SortedReadonlyArray<T>;
|
||||
|
||||
let last = array[0];
|
||||
const deduplicated: T[] = [last];
|
||||
@@ -828,7 +842,7 @@ namespace ts {
|
||||
deduplicated.push(last = next);
|
||||
}
|
||||
|
||||
return deduplicated;
|
||||
return deduplicated as any as SortedReadonlyArray<T>;
|
||||
}
|
||||
|
||||
export function insertSorted<T>(array: SortedArray<T>, insert: T, compare: Comparer<T>): void {
|
||||
@@ -843,11 +857,13 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function sortAndDeduplicate<T>(array: ReadonlyArray<T>, comparer: Comparer<T>, equalityComparer?: EqualityComparer<T>) {
|
||||
return deduplicateSorted(sort(array, comparer), equalityComparer || comparer);
|
||||
export function sortAndDeduplicate<T>(array: ReadonlyArray<string>): SortedReadonlyArray<string>;
|
||||
export function sortAndDeduplicate<T>(array: ReadonlyArray<T>, comparer: Comparer<T>, equalityComparer?: EqualityComparer<T>): SortedReadonlyArray<T>;
|
||||
export function sortAndDeduplicate<T>(array: ReadonlyArray<T>, comparer?: Comparer<T>, equalityComparer?: EqualityComparer<T>): SortedReadonlyArray<T> {
|
||||
return deduplicateSorted(sort(array, comparer), equalityComparer || comparer || compareStringsCaseSensitive as any as Comparer<T>);
|
||||
}
|
||||
|
||||
export function arrayIsEqualTo<T>(array1: ReadonlyArray<T> | undefined, array2: ReadonlyArray<T> | undefined, equalityComparer: (a: T, b: T) => boolean = equateValues): boolean {
|
||||
export function arrayIsEqualTo<T>(array1: ReadonlyArray<T> | undefined, array2: ReadonlyArray<T> | undefined, equalityComparer: (a: T, b: T, index: number) => boolean = equateValues): boolean {
|
||||
if (!array1 || !array2) {
|
||||
return array1 === array2;
|
||||
}
|
||||
@@ -857,7 +873,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
for (let i = 0; i < array1.length; i++) {
|
||||
if (!equalityComparer(array1[i], array2[i])) {
|
||||
if (!equalityComparer(array1[i], array2[i], i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1025,8 +1041,8 @@ namespace ts {
|
||||
/**
|
||||
* Returns a new sorted array.
|
||||
*/
|
||||
export function sort<T>(array: ReadonlyArray<T>, comparer: Comparer<T>): T[] {
|
||||
return array.slice().sort(comparer);
|
||||
export function sort<T>(array: ReadonlyArray<T>, comparer?: Comparer<T>): SortedReadonlyArray<T> {
|
||||
return (array.length === 0 ? array : array.slice().sort(comparer)) as SortedReadonlyArray<T>;
|
||||
}
|
||||
|
||||
export function arrayIterator<T>(array: ReadonlyArray<T>): Iterator<T> {
|
||||
@@ -1045,10 +1061,10 @@ namespace ts {
|
||||
/**
|
||||
* Stable sort of an array. Elements equal to each other maintain their relative position in the array.
|
||||
*/
|
||||
export function stableSort<T>(array: ReadonlyArray<T>, comparer: Comparer<T>) {
|
||||
export function stableSort<T>(array: ReadonlyArray<T>, comparer: Comparer<T>): SortedReadonlyArray<T> {
|
||||
const indices = array.map((_, i) => i);
|
||||
stableSortIndices(array, indices, comparer);
|
||||
return indices.map(i => array[i]);
|
||||
return indices.map(i => array[i]) as SortedArray<T> as SortedReadonlyArray<T>;
|
||||
}
|
||||
|
||||
export function rangeEquals<T>(array1: ReadonlyArray<T>, array2: ReadonlyArray<T>, pos: number, end: number) {
|
||||
@@ -1140,13 +1156,26 @@ namespace ts {
|
||||
* @param offset An offset into `array` at which to start the search.
|
||||
*/
|
||||
export function binarySearch<T, U>(array: ReadonlyArray<T>, value: T, keySelector: (v: T) => U, keyComparer: Comparer<U>, offset?: number): number {
|
||||
if (!array || array.length === 0) {
|
||||
return binarySearchKey(array, keySelector(value), keySelector, keyComparer, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a binary search, finding the index at which an object with `key` occurs in `array`.
|
||||
* If no such index is found, returns the 2's-complement of first index at which
|
||||
* `array[index]` exceeds `key`.
|
||||
* @param array A sorted array whose first element must be no larger than number
|
||||
* @param key The key to be searched for in the array.
|
||||
* @param keySelector A callback used to select the search key from each element of `array`.
|
||||
* @param keyComparer A callback used to compare two keys in a sorted array.
|
||||
* @param offset An offset into `array` at which to start the search.
|
||||
*/
|
||||
export function binarySearchKey<T, U>(array: ReadonlyArray<T>, key: U, keySelector: (v: T) => U, keyComparer: Comparer<U>, offset?: number): number {
|
||||
if (!some(array)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
let low = offset || 0;
|
||||
let high = array.length - 1;
|
||||
const key = keySelector(value);
|
||||
while (low <= high) {
|
||||
const middle = low + ((high - low) >> 1);
|
||||
const midKey = keySelector(array[middle]);
|
||||
@@ -1239,9 +1268,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** Shims `Array.from`. */
|
||||
export function arrayFrom<T, U>(iterator: Iterator<T>, map: (t: T) => U): U[];
|
||||
export function arrayFrom<T>(iterator: Iterator<T>): T[];
|
||||
export function arrayFrom(iterator: Iterator<any>, map?: (t: any) => any): any[] {
|
||||
export function arrayFrom<T, U>(iterator: Iterator<T> | IterableIterator<T>, map: (t: T) => U): U[];
|
||||
export function arrayFrom<T>(iterator: Iterator<T> | IterableIterator<T>): T[];
|
||||
export function arrayFrom(iterator: Iterator<any> | IterableIterator<any>, map?: (t: any) => any): any[] {
|
||||
const result: any[] = [];
|
||||
for (let { value, done } = iterator.next(); !done; { value, done } = iterator.next()) {
|
||||
result.push(map ? map(value) : value);
|
||||
@@ -1272,7 +1301,7 @@ namespace ts {
|
||||
if (!left || !right) return false;
|
||||
for (const key in left) {
|
||||
if (hasOwnProperty.call(left, key)) {
|
||||
if (!hasOwnProperty.call(right, key) === undefined) return false;
|
||||
if (!hasOwnProperty.call(right, key)) return false;
|
||||
if (!equalityComparer(left[key], right[key])) return false;
|
||||
}
|
||||
}
|
||||
@@ -1414,9 +1443,12 @@ namespace ts {
|
||||
/**
|
||||
* Tests whether a value is string
|
||||
*/
|
||||
export function isString(text: any): text is string {
|
||||
export function isString(text: unknown): text is string {
|
||||
return typeof text === "string";
|
||||
}
|
||||
export function isNumber(x: unknown): x is number {
|
||||
return typeof x === "number";
|
||||
}
|
||||
|
||||
export function tryCast<TOut extends TIn, TIn = any>(value: TIn | undefined, test: (value: TIn) => value is TOut): TOut | undefined;
|
||||
export function tryCast<T>(value: T, test: (value: T) => boolean): T | undefined;
|
||||
@@ -1539,6 +1571,7 @@ namespace ts {
|
||||
* Every function should be assignable to this, but this should not be assignable to every function.
|
||||
*/
|
||||
export type AnyFunction = (...args: never[]) => void;
|
||||
export type AnyConstructor = new (...args: unknown[]) => unknown;
|
||||
|
||||
export namespace Debug {
|
||||
export let currentAssertionLevel = AssertionLevel.None;
|
||||
@@ -1603,8 +1636,9 @@ namespace ts {
|
||||
return value;
|
||||
}
|
||||
|
||||
export function assertNever(member: never, message?: string, stackCrawlMark?: AnyFunction): never {
|
||||
return fail(message || `Illegal value: ${member}`, stackCrawlMark || assertNever);
|
||||
export function assertNever(member: never, message = "Illegal value:", stackCrawlMark?: AnyFunction): never {
|
||||
const detail = "kind" in member && "pos" in member ? "SyntaxKind: " + showSyntaxKind(member as Node) : JSON.stringify(member);
|
||||
return fail(`${message} ${detail}`, stackCrawlMark || assertNever);
|
||||
}
|
||||
|
||||
export function getFunctionName(func: AnyFunction) {
|
||||
@@ -2031,7 +2065,6 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** Represents a "prefix*suffix" pattern. */
|
||||
/* @internal */
|
||||
export interface Pattern {
|
||||
prefix: string;
|
||||
suffix: string;
|
||||
@@ -2130,4 +2163,12 @@ namespace ts {
|
||||
deleted(oldItems[oldIndex++]);
|
||||
}
|
||||
}
|
||||
|
||||
export function fill<T>(length: number, cb: (index: number) => T): T[] {
|
||||
const result = Array<T>(length);
|
||||
for (let i = 0; i < length; i++) {
|
||||
result[i] = cb(i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -835,7 +835,7 @@
|
||||
"category": "Error",
|
||||
"code": 1253
|
||||
},
|
||||
"A 'const' initializer in an ambient context must be a string or numeric literal.": {
|
||||
"A 'const' initializer in an ambient context must be a string or numeric literal or literal enum reference.": {
|
||||
"category": "Error",
|
||||
"code": 1254
|
||||
},
|
||||
@@ -987,6 +987,42 @@
|
||||
"category": "Error",
|
||||
"code": 1344
|
||||
},
|
||||
"An expression of type 'void' cannot be tested for truthiness": {
|
||||
"category": "Error",
|
||||
"code": 1345
|
||||
},
|
||||
"This parameter is not allowed with 'use strict' directive.": {
|
||||
"category": "Error",
|
||||
"code": 1346
|
||||
},
|
||||
"'use strict' directive cannot be used with non-simple parameter list.": {
|
||||
"category": "Error",
|
||||
"code": 1347
|
||||
},
|
||||
"Non-simple parameter declared here.": {
|
||||
"category": "Error",
|
||||
"code": 1348
|
||||
},
|
||||
"'use strict' directive used here.": {
|
||||
"category": "Error",
|
||||
"code": 1349
|
||||
},
|
||||
"Print the final configuration instead of building.": {
|
||||
"category": "Message",
|
||||
"code": 1350
|
||||
},
|
||||
"An identifier or keyword cannot immediately follow a numeric literal.": {
|
||||
"category": "Error",
|
||||
"code": 1351
|
||||
},
|
||||
"A bigint literal cannot use exponential notation.": {
|
||||
"category": "Error",
|
||||
"code": 1352
|
||||
},
|
||||
"A bigint literal must be an integer.": {
|
||||
"category": "Error",
|
||||
"code": 1353
|
||||
},
|
||||
|
||||
"Duplicate identifier '{0}'.": {
|
||||
"category": "Error",
|
||||
@@ -1036,7 +1072,7 @@
|
||||
"category": "Error",
|
||||
"code": 2311
|
||||
},
|
||||
"An interface may only extend a class or another interface.": {
|
||||
"An interface can only extend an object type or intersection of object types with statically known members.": {
|
||||
"category": "Error",
|
||||
"code": 2312
|
||||
},
|
||||
@@ -1212,7 +1248,7 @@
|
||||
"category": "Error",
|
||||
"code": 2355
|
||||
},
|
||||
"An arithmetic operand must be of type 'any', 'number' or an enum type.": {
|
||||
"An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type.": {
|
||||
"category": "Error",
|
||||
"code": 2356
|
||||
},
|
||||
@@ -1236,11 +1272,11 @@
|
||||
"category": "Error",
|
||||
"code": 2361
|
||||
},
|
||||
"The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.": {
|
||||
"The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.": {
|
||||
"category": "Error",
|
||||
"code": 2362
|
||||
},
|
||||
"The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.": {
|
||||
"The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.": {
|
||||
"category": "Error",
|
||||
"code": 2363
|
||||
},
|
||||
@@ -1464,7 +1500,7 @@
|
||||
"category": "Error",
|
||||
"code": 2420
|
||||
},
|
||||
"A class may only implement another class or interface.": {
|
||||
"A class can only implement an object type or intersection of object types with statically known members.": {
|
||||
"category": "Error",
|
||||
"code": 2422
|
||||
},
|
||||
@@ -1608,14 +1644,6 @@
|
||||
"category": "Error",
|
||||
"code": 2458
|
||||
},
|
||||
"Type '{0}' has no property '{1}' and no string index signature.": {
|
||||
"category": "Error",
|
||||
"code": 2459
|
||||
},
|
||||
"Type '{0}' has no property '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 2460
|
||||
},
|
||||
"Type '{0}' is not an array type.": {
|
||||
"category": "Error",
|
||||
"code": 2461
|
||||
@@ -1668,7 +1696,7 @@
|
||||
"category": "Error",
|
||||
"code": 2473
|
||||
},
|
||||
"In 'const' enum declarations member initializer must be constant expression.": {
|
||||
"const enum member initializers can only contain literal values and other computed enum values.": {
|
||||
"category": "Error",
|
||||
"code": 2474
|
||||
},
|
||||
@@ -1732,7 +1760,7 @@
|
||||
"category": "Error",
|
||||
"code": 2492
|
||||
},
|
||||
"Tuple type '{0}' with length '{1}' cannot be assigned to tuple with length '{2}'.": {
|
||||
"Tuple type '{0}' of length '{1}' has no element at index '{2}'.": {
|
||||
"category": "Error",
|
||||
"code": 2493
|
||||
},
|
||||
@@ -1796,7 +1824,7 @@
|
||||
"category": "Error",
|
||||
"code": 2508
|
||||
},
|
||||
"Base constructor return type '{0}' is not a class or interface type.": {
|
||||
"Base constructor return type '{0}' is not an object type or intersection of object types with statically known members.": {
|
||||
"category": "Error",
|
||||
"code": 2509
|
||||
},
|
||||
@@ -1920,7 +1948,7 @@
|
||||
"category": "Error",
|
||||
"code": 2539
|
||||
},
|
||||
"Cannot assign to '{0}' because it is a constant or a read-only property.": {
|
||||
"Cannot assign to '{0}' because it is a read-only property.": {
|
||||
"category": "Error",
|
||||
"code": 2540
|
||||
},
|
||||
@@ -1960,10 +1988,6 @@
|
||||
"category": "Error",
|
||||
"code": 2549
|
||||
},
|
||||
"Generic type instantiation is excessively deep and possibly infinite.": {
|
||||
"category": "Error",
|
||||
"code": 2550
|
||||
},
|
||||
"Property '{0}' does not exist on type '{1}'. Did you mean '{2}'?": {
|
||||
"category": "Error",
|
||||
"code": 2551
|
||||
@@ -2064,6 +2088,50 @@
|
||||
"category": "Error",
|
||||
"code": 2575
|
||||
},
|
||||
"Property '{0}' is a static member of type '{1}'": {
|
||||
"category": "Error",
|
||||
"code": 2576
|
||||
},
|
||||
"Return type annotation circularly references itself.": {
|
||||
"category": "Error",
|
||||
"code": 2577
|
||||
},
|
||||
"Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.": {
|
||||
"category": "Error",
|
||||
"code": 2580
|
||||
},
|
||||
"Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i @types/jquery` and then add `jquery` to the types field in your tsconfig.": {
|
||||
"category": "Error",
|
||||
"code": 2581
|
||||
},
|
||||
"Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig.": {
|
||||
"category": "Error",
|
||||
"code": 2582
|
||||
},
|
||||
"Cannot find name '{0}'. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later.": {
|
||||
"category": "Error",
|
||||
"code": 2583
|
||||
},
|
||||
"Cannot find name '{0}'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.": {
|
||||
"category": "Error",
|
||||
"code": 2584
|
||||
},
|
||||
"'{0}' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later.": {
|
||||
"category": "Error",
|
||||
"code": 2585
|
||||
},
|
||||
"Enum type '{0}' circularly references itself.": {
|
||||
"category": "Error",
|
||||
"code": 2586
|
||||
},
|
||||
"JSDoc type '{0}' circularly references itself.": {
|
||||
"category": "Error",
|
||||
"code": 2587
|
||||
},
|
||||
"Cannot assign to '{0}' because it is a constant.": {
|
||||
"category": "Error",
|
||||
"code": 2588
|
||||
},
|
||||
"JSX element attributes type '{0}' may not be a union type.": {
|
||||
"category": "Error",
|
||||
"code": 2600
|
||||
@@ -2429,6 +2497,50 @@
|
||||
"category": "Error",
|
||||
"code": 2732
|
||||
},
|
||||
"It is highly likely that you are missing a semicolon.": {
|
||||
"category": "Error",
|
||||
"code": 2734
|
||||
},
|
||||
"Did you mean for '{0}' to be constrained to type 'new (...args: any[]) => {1}'?": {
|
||||
"category": "Error",
|
||||
"code": 2735
|
||||
},
|
||||
"Operator '{0}' cannot be applied to type '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 2736
|
||||
},
|
||||
"BigInt literals are not available when targeting lower than ESNext.": {
|
||||
"category": "Error",
|
||||
"code": 2737
|
||||
},
|
||||
"An outer value of 'this' is shadowed by this container.": {
|
||||
"category": "Message",
|
||||
"code": 2738
|
||||
},
|
||||
"Type '{0}' is missing the following properties from type '{1}': {2}": {
|
||||
"category": "Error",
|
||||
"code": 2739
|
||||
},
|
||||
"Type '{0}' is missing the following properties from type '{1}': {2}, and {3} more.": {
|
||||
"category": "Error",
|
||||
"code": 2740
|
||||
},
|
||||
"Property '{0}' is missing in type '{1}' but required in type '{2}'.": {
|
||||
"category": "Error",
|
||||
"code": 2741
|
||||
},
|
||||
"The inferred type of '{0}' cannot be named without a reference to '{1}'. This is likely not portable. A type annotation is necessary.": {
|
||||
"category": "Error",
|
||||
"code": 2742
|
||||
},
|
||||
"No overload expects {0} type arguments, but overloads do exist that expect either {1} or {2} type arguments.": {
|
||||
"category": "Error",
|
||||
"code": 2743
|
||||
},
|
||||
"Type parameter defaults can only reference previously declared type parameters.": {
|
||||
"category": "Error",
|
||||
"code": 2744
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
@@ -2884,10 +2996,18 @@
|
||||
"category": "Error",
|
||||
"code": 5070
|
||||
},
|
||||
"Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.": {
|
||||
"Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'.": {
|
||||
"category": "Error",
|
||||
"code": 5071
|
||||
},
|
||||
"Unknown build option '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 5072
|
||||
},
|
||||
"Build option '{0}' requires a value of type {1}.": {
|
||||
"category": "Error",
|
||||
"code": 5073
|
||||
},
|
||||
|
||||
"Generates a sourcemap for each corresponding '.d.ts' file.": {
|
||||
"category": "Message",
|
||||
@@ -3261,7 +3381,7 @@
|
||||
"category": "Message",
|
||||
"code": 6104
|
||||
},
|
||||
"Expected type of '{0}' field in 'package.json' to be 'string', got '{1}'.": {
|
||||
"Expected type of '{0}' field in 'package.json' to be '{1}', got '{2}'.": {
|
||||
"category": "Message",
|
||||
"code": 6105
|
||||
},
|
||||
@@ -3659,6 +3779,54 @@
|
||||
"category": "Error",
|
||||
"code": 6205
|
||||
},
|
||||
"'package.json' has a 'typesVersions' field with version-specific path mappings.": {
|
||||
"category": "Message",
|
||||
"code": 6206
|
||||
},
|
||||
"'package.json' does not have a 'typesVersions' entry that matches version '{0}'.": {
|
||||
"category": "Message",
|
||||
"code": 6207
|
||||
},
|
||||
"'package.json' has a 'typesVersions' entry '{0}' that matches compiler version '{1}', looking for a pattern to match module name '{2}'.": {
|
||||
"category": "Message",
|
||||
"code": 6208
|
||||
},
|
||||
"'package.json' has a 'typesVersions' entry '{0}' that is not a valid semver range.": {
|
||||
"category": "Message",
|
||||
"code": 6209
|
||||
},
|
||||
"An argument for '{0}' was not provided.": {
|
||||
"category": "Message",
|
||||
"code": 6210
|
||||
},
|
||||
"An argument matching this binding pattern was not provided.": {
|
||||
"category": "Message",
|
||||
"code": 6211
|
||||
},
|
||||
"Did you mean to call this expression?": {
|
||||
"category": "Message",
|
||||
"code": 6212
|
||||
},
|
||||
"Did you mean to use 'new' with this expression?": {
|
||||
"category": "Message",
|
||||
"code": 6213
|
||||
},
|
||||
"Enable strict 'bind', 'call', and 'apply' methods on functions.": {
|
||||
"category": "Message",
|
||||
"code": 6214
|
||||
},
|
||||
"Using compiler options of project reference redirect '{0}'.": {
|
||||
"category": "Message",
|
||||
"code": 6215
|
||||
},
|
||||
"Found 1 error.": {
|
||||
"category": "Message",
|
||||
"code": 6216
|
||||
},
|
||||
"Found {0} errors.": {
|
||||
"category": "Message",
|
||||
"code": 6217
|
||||
},
|
||||
|
||||
"Projects to reference": {
|
||||
"category": "Message",
|
||||
@@ -3781,10 +3949,6 @@
|
||||
"category": "Error",
|
||||
"code": 6370
|
||||
},
|
||||
"Skipping clean because not all projects could be located": {
|
||||
"category": "Error",
|
||||
"code": 6371
|
||||
},
|
||||
|
||||
"The expected type comes from property '{0}' which is declared here on type '{1}'": {
|
||||
"category": "Message",
|
||||
@@ -3794,6 +3958,10 @@
|
||||
"category": "Message",
|
||||
"code": 6501
|
||||
},
|
||||
"The expected type comes from the return type of this signature.": {
|
||||
"category": "Message",
|
||||
"code": 6502
|
||||
},
|
||||
|
||||
"Variable '{0}' implicitly has an '{1}' type.": {
|
||||
"category": "Error",
|
||||
@@ -3823,6 +3991,10 @@
|
||||
"category": "Error",
|
||||
"code": 7013
|
||||
},
|
||||
"Function type, which lacks return-type annotation, implicitly has an '{0}' return type.": {
|
||||
"category": "Error",
|
||||
"code": 7014
|
||||
},
|
||||
"Element implicitly has an 'any' type because index expression is not of type 'number'.": {
|
||||
"category": "Error",
|
||||
"code": 7015
|
||||
@@ -3901,7 +4073,7 @@
|
||||
"category": "Error",
|
||||
"code": 7034
|
||||
},
|
||||
"Try `npm install @types/{0}` if it exists or add a new declaration (.d.ts) file containing `declare module '{0}';`": {
|
||||
"Try `npm install @types/{1}` if it exists or add a new declaration (.d.ts) file containing `declare module '{0}';`": {
|
||||
"category": "Error",
|
||||
"code": 7035
|
||||
},
|
||||
@@ -3921,7 +4093,7 @@
|
||||
"category": "Error",
|
||||
"code": 7039
|
||||
},
|
||||
"If the '{0}' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/{0}`": {
|
||||
"If the '{0}' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/{1}`": {
|
||||
"category": "Error",
|
||||
"code": 7040
|
||||
},
|
||||
@@ -3929,6 +4101,47 @@
|
||||
"category": "Error",
|
||||
"code": 7041
|
||||
},
|
||||
"Module '{0}' was resolved to '{1}', but '--resolveJsonModule' is not used.": {
|
||||
"category": "Error",
|
||||
"code": 7042
|
||||
},
|
||||
"Variable '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage.": {
|
||||
"category": "Suggestion",
|
||||
"code": 7043
|
||||
},
|
||||
"Parameter '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage.": {
|
||||
"category": "Suggestion",
|
||||
"code": 7044
|
||||
},
|
||||
"Member '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage.": {
|
||||
"category": "Suggestion",
|
||||
"code": 7045
|
||||
},
|
||||
"Variable '{0}' implicitly has type '{1}' in some locations, but a better type may be inferred from usage.": {
|
||||
"category": "Suggestion",
|
||||
"code": 7046
|
||||
},
|
||||
"Rest parameter '{0}' implicitly has an 'any[]' type, but a better type may be inferred from usage.": {
|
||||
"category": "Suggestion",
|
||||
"code": 7047
|
||||
},
|
||||
"Property '{0}' implicitly has type 'any', but a better type for its get accessor may be inferred from usage.": {
|
||||
"category": "Suggestion",
|
||||
"code": 7048
|
||||
},
|
||||
"Property '{0}' implicitly has type 'any', but a better type for its set accessor may be inferred from usage.": {
|
||||
"category": "Suggestion",
|
||||
"code": 7049
|
||||
},
|
||||
"'{0}' implicitly has an '{1}' return type, but a better type may be inferred from usage.": {
|
||||
"category": "Suggestion",
|
||||
"code": 7050
|
||||
},
|
||||
"Parameter has a name but no type. Did you mean '{0}: {1}'?": {
|
||||
"category": "Error",
|
||||
"code": 7051
|
||||
},
|
||||
|
||||
"You cannot rename this element.": {
|
||||
"category": "Error",
|
||||
"code": 8000
|
||||
@@ -4049,6 +4262,10 @@
|
||||
"category": "Error",
|
||||
"code": 8030
|
||||
},
|
||||
"You cannot rename a module via a global import.": {
|
||||
"category": "Error",
|
||||
"code": 8031
|
||||
},
|
||||
"Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause.": {
|
||||
"category": "Error",
|
||||
"code": 9002
|
||||
@@ -4171,7 +4388,10 @@
|
||||
"category": "Suggestion",
|
||||
"code": 80005
|
||||
},
|
||||
|
||||
"This may be converted to an async function.": {
|
||||
"category": "Suggestion",
|
||||
"code": 80006
|
||||
},
|
||||
"Add missing 'super()' call": {
|
||||
"category": "Message",
|
||||
"code": 90001
|
||||
@@ -4304,6 +4524,10 @@
|
||||
"category": "Message",
|
||||
"code": 90033
|
||||
},
|
||||
"Add parameter name": {
|
||||
"category": "Message",
|
||||
"code": 90034
|
||||
},
|
||||
"Convert function to an ES2015 class": {
|
||||
"category": "Message",
|
||||
"code": 95001
|
||||
@@ -4551,5 +4775,41 @@
|
||||
"Add all missing imports": {
|
||||
"category": "Message",
|
||||
"code": 95064
|
||||
},
|
||||
"Convert to async function": {
|
||||
"category": "Message",
|
||||
"code": 95065
|
||||
},
|
||||
"Convert all to async functions": {
|
||||
"category": "Message",
|
||||
"code": 95066
|
||||
},
|
||||
"Generate types for '{0}'": {
|
||||
"category": "Message",
|
||||
"code": 95067
|
||||
},
|
||||
"Generate types for all packages without types": {
|
||||
"category": "Message",
|
||||
"code": 95068
|
||||
},
|
||||
"Add 'unknown' conversion for non-overlapping types": {
|
||||
"category": "Message",
|
||||
"code": 95069
|
||||
},
|
||||
"Add 'unknown' to all conversions of non-overlapping types": {
|
||||
"category": "Message",
|
||||
"code": 95070
|
||||
},
|
||||
"Add missing 'new' operator to call": {
|
||||
"category": "Message",
|
||||
"code": 95071
|
||||
},
|
||||
"Add missing 'new' operator to all calls": {
|
||||
"category": "Message",
|
||||
"code": 95072
|
||||
},
|
||||
"Add names to all parameters without names": {
|
||||
"category": "Message",
|
||||
"code": 95073
|
||||
}
|
||||
}
|
||||
|
||||
+1044
-277
File diff suppressed because it is too large
Load Diff
+86
-17
@@ -68,13 +68,16 @@ namespace ts {
|
||||
/* @internal */ export function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier, isSingleQuote: boolean): StringLiteral; // tslint:disable-line unified-signatures
|
||||
/** If a node is passed, creates a string literal whose source text is read from a source node during emit. */
|
||||
export function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): StringLiteral;
|
||||
export function createLiteral(value: number): NumericLiteral;
|
||||
export function createLiteral(value: number | PseudoBigInt): NumericLiteral;
|
||||
export function createLiteral(value: boolean): BooleanLiteral;
|
||||
export function createLiteral(value: string | number | boolean): PrimaryExpression;
|
||||
export function createLiteral(value: string | number | boolean | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier, isSingleQuote?: boolean): PrimaryExpression {
|
||||
export function createLiteral(value: string | number | PseudoBigInt | boolean): PrimaryExpression;
|
||||
export function createLiteral(value: string | number | PseudoBigInt | boolean | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier, isSingleQuote?: boolean): PrimaryExpression {
|
||||
if (typeof value === "number") {
|
||||
return createNumericLiteral(value + "");
|
||||
}
|
||||
if (typeof value === "object" && "base10Value" in value) { // PseudoBigInt
|
||||
return createBigIntLiteral(pseudoBigIntToString(value) + "n");
|
||||
}
|
||||
if (typeof value === "boolean") {
|
||||
return value ? createTrue() : createFalse();
|
||||
}
|
||||
@@ -93,6 +96,12 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createBigIntLiteral(value: string): BigIntLiteral {
|
||||
const node = <BigIntLiteral>createSynthesizedNode(SyntaxKind.BigIntLiteral);
|
||||
node.text = value;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createStringLiteral(text: string): StringLiteral {
|
||||
const node = <StringLiteral>createSynthesizedNode(SyntaxKind.StringLiteral);
|
||||
node.text = text;
|
||||
@@ -235,7 +244,7 @@ namespace ts {
|
||||
|
||||
// Modifiers
|
||||
|
||||
export function createModifier<T extends Modifier["kind"]>(kind: T) {
|
||||
export function createModifier<T extends Modifier["kind"]>(kind: T): Token<T> {
|
||||
return createToken(kind);
|
||||
}
|
||||
|
||||
@@ -2170,6 +2179,56 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
// JSDoc
|
||||
|
||||
/* @internal */
|
||||
export function createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression {
|
||||
const node = createSynthesizedNode(SyntaxKind.JSDocTypeExpression) as JSDocTypeExpression;
|
||||
node.type = type;
|
||||
return node;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createJSDocTypeTag(typeExpression?: JSDocTypeExpression, comment?: string): JSDocTypeTag {
|
||||
const tag = createJSDocTag<JSDocTypeTag>(SyntaxKind.JSDocTypeTag, "type");
|
||||
tag.typeExpression = typeExpression;
|
||||
tag.comment = comment;
|
||||
return tag;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createJSDocReturnTag(typeExpression?: JSDocTypeExpression, comment?: string): JSDocReturnTag {
|
||||
const tag = createJSDocTag<JSDocReturnTag>(SyntaxKind.JSDocReturnTag, "returns");
|
||||
tag.typeExpression = typeExpression;
|
||||
tag.comment = comment;
|
||||
return tag;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createJSDocParamTag(name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, comment?: string): JSDocParameterTag {
|
||||
const tag = createJSDocTag<JSDocParameterTag>(SyntaxKind.JSDocParameterTag, "param");
|
||||
tag.typeExpression = typeExpression;
|
||||
tag.name = name;
|
||||
tag.isBracketed = isBracketed;
|
||||
tag.comment = comment;
|
||||
return tag;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createJSDocComment(comment?: string | undefined, tags?: NodeArray<JSDocTag> | undefined) {
|
||||
const node = createSynthesizedNode(SyntaxKind.JSDocComment) as JSDoc;
|
||||
node.comment = comment;
|
||||
node.tags = tags;
|
||||
return node;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
function createJSDocTag<T extends JSDocTag>(kind: T["kind"], tagName: string): T {
|
||||
const node = createSynthesizedNode(kind) as T;
|
||||
node.tagName = createIdentifier(tagName);
|
||||
return node;
|
||||
}
|
||||
|
||||
// JSX
|
||||
|
||||
export function createJsxElement(openingElement: JsxOpeningElement, children: ReadonlyArray<JsxChild>, closingElement: JsxClosingElement) {
|
||||
@@ -3416,6 +3475,7 @@ namespace ts {
|
||||
return cacheIdentifiers;
|
||||
case SyntaxKind.ThisKeyword:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
return false;
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
@@ -3894,6 +3954,20 @@ namespace ts {
|
||||
return statementOffset;
|
||||
}
|
||||
|
||||
export function findUseStrictPrologue(statements: ReadonlyArray<Statement>): Statement | undefined {
|
||||
for (const statement of statements) {
|
||||
if (isPrologueDirective(statement)) {
|
||||
if (isUseStrictPrologue(statement)) {
|
||||
return statement;
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function startsWithUseStrict(statements: ReadonlyArray<Statement>) {
|
||||
const firstStatement = firstOrUndefined(statements);
|
||||
return firstStatement !== undefined
|
||||
@@ -3907,18 +3981,7 @@ namespace ts {
|
||||
* @param statements An array of statements
|
||||
*/
|
||||
export function ensureUseStrict(statements: NodeArray<Statement>): NodeArray<Statement> {
|
||||
let foundUseStrict = false;
|
||||
for (const statement of statements) {
|
||||
if (isPrologueDirective(statement)) {
|
||||
if (isUseStrictPrologue(statement as ExpressionStatement)) {
|
||||
foundUseStrict = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
const foundUseStrict = findUseStrictPrologue(statements);
|
||||
|
||||
if (!foundUseStrict) {
|
||||
return setTextRange(
|
||||
@@ -4709,7 +4772,7 @@ namespace ts {
|
||||
/**
|
||||
* Gets the property name of a BindingOrAssignmentElement
|
||||
*/
|
||||
export function getPropertyNameOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement) {
|
||||
export function getPropertyNameOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): PropertyName | undefined {
|
||||
switch (bindingElement.kind) {
|
||||
case SyntaxKind.BindingElement:
|
||||
// `a` in `let { a: b } = ...`
|
||||
@@ -4754,6 +4817,12 @@ namespace ts {
|
||||
Debug.fail("Invalid property name for binding element.");
|
||||
}
|
||||
|
||||
function isStringOrNumericLiteral(node: Node): node is StringLiteral | NumericLiteral {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.StringLiteral
|
||||
|| kind === SyntaxKind.NumericLiteral;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the elements of a BindingOrAssignmentPattern
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
export interface InspectValueOptions {
|
||||
readonly fileNameToRequire: string;
|
||||
}
|
||||
|
||||
export const enum ValueKind { Const, Array, FunctionOrClass, Object }
|
||||
export interface ValueInfoBase {
|
||||
readonly name: string;
|
||||
}
|
||||
export type ValueInfo = ValueInfoSimple | ValueInfoArray | ValueInfoFunctionOrClass | ValueInfoObject;
|
||||
export interface ValueInfoSimple extends ValueInfoBase {
|
||||
readonly kind: ValueKind.Const;
|
||||
readonly typeName: string;
|
||||
readonly comment?: string | undefined;
|
||||
}
|
||||
export interface ValueInfoFunctionOrClass extends ValueInfoBase {
|
||||
readonly kind: ValueKind.FunctionOrClass;
|
||||
readonly source: string | number; // For a native function, this is the length.
|
||||
readonly prototypeMembers: ReadonlyArray<ValueInfo>;
|
||||
readonly namespaceMembers: ReadonlyArray<ValueInfo>;
|
||||
}
|
||||
export interface ValueInfoArray extends ValueInfoBase {
|
||||
readonly kind: ValueKind.Array;
|
||||
readonly inner: ValueInfo;
|
||||
}
|
||||
export interface ValueInfoObject extends ValueInfoBase {
|
||||
readonly kind: ValueKind.Object;
|
||||
readonly hasNontrivialPrototype: boolean;
|
||||
readonly members: ReadonlyArray<ValueInfo>;
|
||||
}
|
||||
|
||||
export function inspectModule(fileNameToRequire: string): ValueInfo {
|
||||
return inspectValue(removeFileExtension(getBaseFileName(fileNameToRequire)), tryRequire(fileNameToRequire));
|
||||
}
|
||||
|
||||
export function inspectValue(name: string, value: unknown): ValueInfo {
|
||||
return getValueInfo(name, value, getRecurser());
|
||||
}
|
||||
|
||||
type Recurser = <T>(obj: unknown, name: string, cbOk: () => T, cbFail: (isCircularReference: boolean, keyStack: ReadonlyArray<string>) => T) => T;
|
||||
function getRecurser(): Recurser {
|
||||
const seen: unknown[] = [];
|
||||
const nameStack: string[] = [];
|
||||
return (obj, name, cbOk, cbFail) => {
|
||||
if (seen.indexOf(obj) !== -1 || nameStack.length > 4) {
|
||||
return cbFail(seen.indexOf(obj) !== -1, nameStack);
|
||||
}
|
||||
|
||||
seen.push(obj);
|
||||
nameStack.push(name);
|
||||
const res = cbOk();
|
||||
nameStack.pop();
|
||||
seen.pop();
|
||||
return res;
|
||||
};
|
||||
}
|
||||
|
||||
function getValueInfo(name: string, value: unknown, recurser: Recurser): ValueInfo {
|
||||
return recurser(value, name,
|
||||
(): ValueInfo => {
|
||||
if (typeof value === "function") return getFunctionOrClassInfo(value as AnyFunction, name, recurser);
|
||||
if (typeof value === "object") {
|
||||
const builtin = getBuiltinType(name, value as object, recurser);
|
||||
if (builtin !== undefined) return builtin;
|
||||
const entries = getEntriesOfObject(value as object);
|
||||
const hasNontrivialPrototype = Object.getPrototypeOf(value) !== Object.prototype;
|
||||
const members = flatMap(entries, ({ key, value }) => getValueInfo(key, value, recurser));
|
||||
return { kind: ValueKind.Object, name, hasNontrivialPrototype, members };
|
||||
}
|
||||
return { kind: ValueKind.Const, name, typeName: isNullOrUndefined(value) ? "any" : typeof value };
|
||||
},
|
||||
(isCircularReference, keyStack) => anyValue(name, ` ${isCircularReference ? "Circular reference" : "Too-deep object hierarchy"} from ${keyStack.join(".")}`));
|
||||
}
|
||||
|
||||
function getFunctionOrClassInfo(fn: AnyFunction, name: string, recurser: Recurser): ValueInfoFunctionOrClass {
|
||||
const prototypeMembers = getPrototypeMembers(fn, recurser);
|
||||
const namespaceMembers = flatMap(getEntriesOfObject(fn), ({ key, value }) => getValueInfo(key, value, recurser));
|
||||
const toString = cast(Function.prototype.toString.call(fn), isString);
|
||||
const source = stringContains(toString, "{ [native code] }") ? getFunctionLength(fn) : toString;
|
||||
return { kind: ValueKind.FunctionOrClass, name, source, namespaceMembers, prototypeMembers };
|
||||
}
|
||||
|
||||
const builtins: () => ReadonlyMap<AnyConstructor> = memoize(() => {
|
||||
const map = createMap<AnyConstructor>();
|
||||
for (const { key, value } of getEntriesOfObject(global)) {
|
||||
if (typeof value === "function" && typeof value.prototype === "object" && value !== Object) {
|
||||
map.set(key, value as AnyConstructor);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
});
|
||||
function getBuiltinType(name: string, value: object, recurser: Recurser): ValueInfo | undefined {
|
||||
return isArray(value)
|
||||
? { name, kind: ValueKind.Array, inner: value.length && getValueInfo("element", first(value), recurser) || anyValue(name) }
|
||||
: forEachEntry(builtins(), (builtin, builtinName): ValueInfo | undefined =>
|
||||
value instanceof builtin ? { kind: ValueKind.Const, name, typeName: builtinName } : undefined);
|
||||
}
|
||||
|
||||
function getPrototypeMembers(fn: AnyFunction, recurser: Recurser): ReadonlyArray<ValueInfo> {
|
||||
const prototype = fn.prototype as unknown;
|
||||
// tslint:disable-next-line no-unnecessary-type-assertion (TODO: update LKG and it will really be unnecessary)
|
||||
return typeof prototype !== "object" || prototype === null ? emptyArray : mapDefined(getEntriesOfObject(prototype as object), ({ key, value }) =>
|
||||
key === "constructor" ? undefined : getValueInfo(key, value, recurser));
|
||||
}
|
||||
|
||||
const ignoredProperties: ReadonlyArray<string> = ["arguments", "caller", "constructor", "eval", "super_"];
|
||||
const reservedFunctionProperties: ReadonlyArray<string> = Object.getOwnPropertyNames(noop);
|
||||
interface ObjectEntry { readonly key: string; readonly value: unknown; }
|
||||
function getEntriesOfObject(obj: object): ReadonlyArray<ObjectEntry> {
|
||||
const seen = createMap<true>();
|
||||
const entries: ObjectEntry[] = [];
|
||||
let chain = obj;
|
||||
while (!isNullOrUndefined(chain) && chain !== Object.prototype && chain !== Function.prototype) {
|
||||
for (const key of Object.getOwnPropertyNames(chain)) {
|
||||
if (!isJsPrivate(key) &&
|
||||
ignoredProperties.indexOf(key) === -1 &&
|
||||
(typeof obj !== "function" || reservedFunctionProperties.indexOf(key) === -1) &&
|
||||
// Don't add property from a higher prototype if it already exists in a lower one
|
||||
addToSeen(seen, key)) {
|
||||
const value = safeGetPropertyOfObject(chain, key);
|
||||
// Don't repeat "toString" that matches signature from Object.prototype
|
||||
if (!(key === "toString" && typeof value === "function" && value.length === 0)) {
|
||||
entries.push({ key, value });
|
||||
}
|
||||
}
|
||||
}
|
||||
chain = Object.getPrototypeOf(chain);
|
||||
}
|
||||
return entries.sort((e1, e2) => compareStringsCaseSensitive(e1.key, e2.key));
|
||||
}
|
||||
|
||||
function getFunctionLength(fn: AnyFunction): number {
|
||||
return tryCast(safeGetPropertyOfObject(fn, "length"), isNumber) || 0;
|
||||
}
|
||||
|
||||
function safeGetPropertyOfObject(obj: object, key: string): unknown {
|
||||
const desc = Object.getOwnPropertyDescriptor(obj, key);
|
||||
return desc && desc.value;
|
||||
}
|
||||
|
||||
function isNullOrUndefined(value: unknown): value is null | undefined {
|
||||
return value == null; // tslint:disable-line
|
||||
}
|
||||
|
||||
function anyValue(name: string, comment?: string): ValueInfo {
|
||||
return { kind: ValueKind.Const, name, typeName: "any", comment };
|
||||
}
|
||||
|
||||
export function isJsPrivate(name: string): boolean {
|
||||
return startsWith(name, "_");
|
||||
}
|
||||
|
||||
function tryRequire(fileNameToRequire: string): unknown {
|
||||
try {
|
||||
return require(fileNameToRequire);
|
||||
}
|
||||
catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
+538
-335
File diff suppressed because it is too large
Load Diff
+165
-160
@@ -1,8 +1,52 @@
|
||||
// Used by importFixes, getEditsForFileRename, and declaration emit to synthesize import module specifiers.
|
||||
/* @internal */
|
||||
namespace ts.moduleSpecifiers {
|
||||
export interface ModuleSpecifierPreferences {
|
||||
readonly importModuleSpecifierPreference?: "relative" | "non-relative";
|
||||
const enum RelativePreference { Relative, NonRelative, Auto }
|
||||
// See UserPreferences#importPathEnding
|
||||
const enum Ending { Minimal, Index, JsExtension }
|
||||
|
||||
// Processed preferences
|
||||
interface Preferences {
|
||||
readonly relativePreference: RelativePreference;
|
||||
readonly ending: Ending;
|
||||
}
|
||||
|
||||
function getPreferences({ importModuleSpecifierPreference, importModuleSpecifierEnding }: UserPreferences, compilerOptions: CompilerOptions, importingSourceFile: SourceFile): Preferences {
|
||||
return {
|
||||
relativePreference: importModuleSpecifierPreference === "relative" ? RelativePreference.Relative : importModuleSpecifierPreference === "non-relative" ? RelativePreference.NonRelative : RelativePreference.Auto,
|
||||
ending: getEnding(),
|
||||
};
|
||||
function getEnding(): Ending {
|
||||
switch (importModuleSpecifierEnding) {
|
||||
case "minimal": return Ending.Minimal;
|
||||
case "index": return Ending.Index;
|
||||
case "js": return Ending.JsExtension;
|
||||
default: return usesJsExtensionOnImports(importingSourceFile) ? Ending.JsExtension
|
||||
: getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeJs ? Ending.Index : Ending.Minimal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getPreferencesForUpdate(compilerOptions: CompilerOptions, oldImportSpecifier: string): Preferences {
|
||||
return {
|
||||
relativePreference: isExternalModuleNameRelative(oldImportSpecifier) ? RelativePreference.Relative : RelativePreference.NonRelative,
|
||||
ending: hasJSOrJsonFileExtension(oldImportSpecifier) ? Ending.JsExtension
|
||||
: getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeJs || endsWith(oldImportSpecifier, "index") ? Ending.Index : Ending.Minimal,
|
||||
};
|
||||
}
|
||||
|
||||
export function updateModuleSpecifier(
|
||||
compilerOptions: CompilerOptions,
|
||||
importingSourceFileName: Path,
|
||||
toFileName: string,
|
||||
host: ModuleSpecifierResolutionHost,
|
||||
files: ReadonlyArray<SourceFile>,
|
||||
redirectTargetsMap: RedirectTargetsMap,
|
||||
oldImportSpecifier: string,
|
||||
): string | undefined {
|
||||
const res = getModuleSpecifierWorker(compilerOptions, importingSourceFileName, toFileName, host, files, redirectTargetsMap, getPreferencesForUpdate(compilerOptions, oldImportSpecifier));
|
||||
if (res === oldImportSpecifier) return undefined;
|
||||
return res;
|
||||
}
|
||||
|
||||
// Note: importingSourceFile is just for usesJsExtensionOnImports
|
||||
@@ -13,148 +57,98 @@ namespace ts.moduleSpecifiers {
|
||||
toFileName: string,
|
||||
host: ModuleSpecifierResolutionHost,
|
||||
files: ReadonlyArray<SourceFile>,
|
||||
preferences: ModuleSpecifierPreferences = {},
|
||||
preferences: UserPreferences = {},
|
||||
redirectTargetsMap: RedirectTargetsMap,
|
||||
): string {
|
||||
const info = getInfo(compilerOptions, importingSourceFile, importingSourceFileName, host);
|
||||
const modulePaths = getAllModulePaths(files, importingSourceFileName, toFileName, info.getCanonicalFileName, host, redirectTargetsMap);
|
||||
return firstDefined(modulePaths, moduleFileName => getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions)) ||
|
||||
first(getLocalModuleSpecifiers(toFileName, info, compilerOptions, preferences));
|
||||
return getModuleSpecifierWorker(compilerOptions, importingSourceFileName, toFileName, host, files, redirectTargetsMap, getPreferences(preferences, compilerOptions, importingSourceFile));
|
||||
}
|
||||
|
||||
export function getModuleSpecifierForDeclarationFile(
|
||||
moduleSymbol: Symbol,
|
||||
function getModuleSpecifierWorker(
|
||||
compilerOptions: CompilerOptions,
|
||||
importingSourceFile: SourceFile,
|
||||
importingSourceFileName: Path,
|
||||
toFileName: string,
|
||||
host: ModuleSpecifierResolutionHost,
|
||||
files: ReadonlyArray<SourceFile>,
|
||||
preferences: ModuleSpecifierPreferences,
|
||||
redirectTargetsMap: RedirectTargetsMap,
|
||||
preferences: Preferences
|
||||
): string {
|
||||
return first(first(getModuleSpecifiers(moduleSymbol, compilerOptions, importingSourceFile, host, files, preferences, redirectTargetsMap)));
|
||||
const info = getInfo(importingSourceFileName, host);
|
||||
const modulePaths = getAllModulePaths(files, importingSourceFileName, toFileName, info.getCanonicalFileName, host, redirectTargetsMap);
|
||||
return firstDefined(modulePaths, moduleFileName => tryGetModuleNameAsNodeModule(moduleFileName, info, host, compilerOptions)) ||
|
||||
getLocalModuleSpecifier(toFileName, info, compilerOptions, preferences);
|
||||
}
|
||||
|
||||
// For each symlink/original for a module, returns a list of ways to import that file.
|
||||
// Returns an import for each symlink and for the realpath.
|
||||
export function getModuleSpecifiers(
|
||||
moduleSymbol: Symbol,
|
||||
compilerOptions: CompilerOptions,
|
||||
importingSourceFile: SourceFile,
|
||||
host: ModuleSpecifierResolutionHost,
|
||||
files: ReadonlyArray<SourceFile>,
|
||||
preferences: ModuleSpecifierPreferences,
|
||||
userPreferences: UserPreferences,
|
||||
redirectTargetsMap: RedirectTargetsMap,
|
||||
): ReadonlyArray<ReadonlyArray<string>> {
|
||||
): ReadonlyArray<string> {
|
||||
const ambient = tryGetModuleNameFromAmbientModule(moduleSymbol);
|
||||
if (ambient) return [[ambient]];
|
||||
if (ambient) return [ambient];
|
||||
|
||||
const info = getInfo(compilerOptions, importingSourceFile, importingSourceFile.path, host);
|
||||
if (!files) {
|
||||
return Debug.fail("Files list must be present to resolve symlinks in specifier resolution");
|
||||
}
|
||||
const moduleSourceFile = getSourceFileOfNode(moduleSymbol.valueDeclaration);
|
||||
const info = getInfo(importingSourceFile.path, host);
|
||||
const moduleSourceFile = getSourceFileOfNode(moduleSymbol.valueDeclaration || getNonAugmentationDeclaration(moduleSymbol));
|
||||
const modulePaths = getAllModulePaths(files, importingSourceFile.path, moduleSourceFile.fileName, info.getCanonicalFileName, host, redirectTargetsMap);
|
||||
|
||||
const global = mapDefined(modulePaths, moduleFileName => getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions));
|
||||
return global.length ? global.map(g => [g]) : modulePaths.map(moduleFileName =>
|
||||
getLocalModuleSpecifiers(moduleFileName, info, compilerOptions, preferences));
|
||||
const preferences = getPreferences(userPreferences, compilerOptions, importingSourceFile);
|
||||
const global = mapDefined(modulePaths, moduleFileName => tryGetModuleNameAsNodeModule(moduleFileName, info, host, compilerOptions));
|
||||
return global.length ? global : modulePaths.map(moduleFileName => getLocalModuleSpecifier(moduleFileName, info, compilerOptions, preferences));
|
||||
}
|
||||
|
||||
interface Info {
|
||||
readonly moduleResolutionKind: ModuleResolutionKind;
|
||||
readonly addJsExtension: boolean;
|
||||
readonly getCanonicalFileName: GetCanonicalFileName;
|
||||
readonly sourceDirectory: Path;
|
||||
}
|
||||
// importingSourceFileName is separate because getEditsForFileRename may need to specify an updated path
|
||||
function getInfo(compilerOptions: CompilerOptions, importingSourceFile: SourceFile, importingSourceFileName: Path, host: ModuleSpecifierResolutionHost): Info {
|
||||
const moduleResolutionKind = getEmitModuleResolutionKind(compilerOptions);
|
||||
const addJsExtension = usesJsExtensionOnImports(importingSourceFile);
|
||||
function getInfo(importingSourceFileName: Path, host: ModuleSpecifierResolutionHost): Info {
|
||||
const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : true);
|
||||
const sourceDirectory = getDirectoryPath(importingSourceFileName);
|
||||
return { moduleResolutionKind, addJsExtension, getCanonicalFileName, sourceDirectory };
|
||||
return { getCanonicalFileName, sourceDirectory };
|
||||
}
|
||||
|
||||
function getGlobalModuleSpecifier(
|
||||
moduleFileName: string,
|
||||
{ addJsExtension, getCanonicalFileName, sourceDirectory }: Info,
|
||||
host: ModuleSpecifierResolutionHost,
|
||||
compilerOptions: CompilerOptions,
|
||||
) {
|
||||
return tryGetModuleNameFromTypeRoots(compilerOptions, host, getCanonicalFileName, moduleFileName, addJsExtension)
|
||||
|| tryGetModuleNameAsNodeModule(compilerOptions, moduleFileName, host, getCanonicalFileName, sourceDirectory);
|
||||
}
|
||||
|
||||
function getLocalModuleSpecifiers(
|
||||
moduleFileName: string,
|
||||
{ moduleResolutionKind, addJsExtension, getCanonicalFileName, sourceDirectory }: Info,
|
||||
compilerOptions: CompilerOptions,
|
||||
preferences: ModuleSpecifierPreferences,
|
||||
): ReadonlyArray<string> {
|
||||
function getLocalModuleSpecifier(moduleFileName: string, { getCanonicalFileName, sourceDirectory }: Info, compilerOptions: CompilerOptions, { ending, relativePreference }: Preferences): string {
|
||||
const { baseUrl, paths, rootDirs } = compilerOptions;
|
||||
|
||||
const relativePath = rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) ||
|
||||
removeExtensionAndIndexPostFix(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), moduleResolutionKind, addJsExtension);
|
||||
if (!baseUrl || preferences.importModuleSpecifierPreference === "relative") {
|
||||
return [relativePath];
|
||||
removeExtensionAndIndexPostFix(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), ending, compilerOptions);
|
||||
if (!baseUrl || relativePreference === RelativePreference.Relative) {
|
||||
return relativePath;
|
||||
}
|
||||
|
||||
const relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseUrl, getCanonicalFileName);
|
||||
if (!relativeToBaseUrl) {
|
||||
return [relativePath];
|
||||
return relativePath;
|
||||
}
|
||||
|
||||
const importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, moduleResolutionKind, addJsExtension);
|
||||
if (paths) {
|
||||
const fromPaths = tryGetModuleNameFromPaths(removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths);
|
||||
if (fromPaths) {
|
||||
return [fromPaths];
|
||||
}
|
||||
const importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, ending, compilerOptions);
|
||||
const fromPaths = paths && tryGetModuleNameFromPaths(removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths);
|
||||
const nonRelative = fromPaths === undefined ? importRelativeToBaseUrl : fromPaths;
|
||||
|
||||
if (relativePreference === RelativePreference.NonRelative) {
|
||||
return nonRelative;
|
||||
}
|
||||
|
||||
if (preferences.importModuleSpecifierPreference === "non-relative") {
|
||||
return [importRelativeToBaseUrl];
|
||||
if (relativePreference !== RelativePreference.Auto) Debug.assertNever(relativePreference);
|
||||
|
||||
// Prefer a relative import over a baseUrl import if it has fewer components.
|
||||
return isPathRelativeToParent(nonRelative) || countPathComponents(relativePath) < countPathComponents(nonRelative) ? relativePath : nonRelative;
|
||||
}
|
||||
|
||||
export function countPathComponents(path: string): number {
|
||||
let count = 0;
|
||||
for (let i = startsWith(path, "./") ? 2 : 0; i < path.length; i++) {
|
||||
if (path.charCodeAt(i) === CharacterCodes.slash) count++;
|
||||
}
|
||||
|
||||
if (preferences.importModuleSpecifierPreference !== undefined) Debug.assertNever(preferences.importModuleSpecifierPreference);
|
||||
|
||||
if (isPathRelativeToParent(relativeToBaseUrl)) {
|
||||
return [relativePath];
|
||||
}
|
||||
|
||||
/*
|
||||
Prefer a relative import over a baseUrl import if it doesn't traverse up to baseUrl.
|
||||
|
||||
Suppose we have:
|
||||
baseUrl = /base
|
||||
sourceDirectory = /base/a/b
|
||||
moduleFileName = /base/foo/bar
|
||||
Then:
|
||||
relativePath = ../../foo/bar
|
||||
getRelativePathNParents(relativePath) = 2
|
||||
pathFromSourceToBaseUrl = ../../
|
||||
getRelativePathNParents(pathFromSourceToBaseUrl) = 2
|
||||
2 < 2 = false
|
||||
In this case we should prefer using the baseUrl path "/a/b" instead of the relative path "../../foo/bar".
|
||||
|
||||
Suppose we have:
|
||||
baseUrl = /base
|
||||
sourceDirectory = /base/foo/a
|
||||
moduleFileName = /base/foo/bar
|
||||
Then:
|
||||
relativePath = ../a
|
||||
getRelativePathNParents(relativePath) = 1
|
||||
pathFromSourceToBaseUrl = ../../
|
||||
getRelativePathNParents(pathFromSourceToBaseUrl) = 2
|
||||
1 < 2 = true
|
||||
In this case we should prefer using the relative path "../a" instead of the baseUrl path "foo/a".
|
||||
*/
|
||||
const pathFromSourceToBaseUrl = ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, baseUrl, getCanonicalFileName));
|
||||
const relativeFirst = getRelativePathNParents(relativePath) < getRelativePathNParents(pathFromSourceToBaseUrl);
|
||||
return relativeFirst ? [relativePath, importRelativeToBaseUrl] : [importRelativeToBaseUrl, relativePath];
|
||||
return count;
|
||||
}
|
||||
|
||||
function usesJsExtensionOnImports({ imports }: SourceFile): boolean {
|
||||
return firstDefined(imports, ({ text }) => pathIsRelative(text) ? fileExtensionIs(text, Extension.Js) : undefined) || false;
|
||||
return firstDefined(imports, ({ text }) => pathIsRelative(text) ? hasJSOrJsonFileExtension(text) : undefined) || false;
|
||||
}
|
||||
|
||||
function stringsEqual(a: string, b: string, getCanonicalFileName: GetCanonicalFileName): boolean {
|
||||
@@ -209,7 +203,7 @@ namespace ts.moduleSpecifiers {
|
||||
return; // Don't want to a package to globally import from itself
|
||||
}
|
||||
|
||||
const target = targets.find(t => compareStrings(t.slice(0, resolved.length + 1), resolved + "/") === Comparison.EqualTo);
|
||||
const target = find(targets, t => compareStrings(t.slice(0, resolved.length + 1), resolved + "/") === Comparison.EqualTo);
|
||||
if (target === undefined) return;
|
||||
|
||||
const relative = getRelativePathFromDirectory(resolved, target, getCanonicalFileName);
|
||||
@@ -222,18 +216,11 @@ namespace ts.moduleSpecifiers {
|
||||
return result;
|
||||
}
|
||||
|
||||
function getRelativePathNParents(relativePath: string): number {
|
||||
const components = getPathComponents(relativePath);
|
||||
if (components[0] || components.length === 1) return 0;
|
||||
for (let i = 1; i < components.length; i++) {
|
||||
if (components[i] !== "..") return i - 1;
|
||||
}
|
||||
return components.length - 1;
|
||||
}
|
||||
|
||||
function tryGetModuleNameFromAmbientModule(moduleSymbol: Symbol): string | undefined {
|
||||
const decl = moduleSymbol.valueDeclaration;
|
||||
if (isModuleDeclaration(decl) && isStringLiteral(decl.name)) {
|
||||
const decl = find(moduleSymbol.declarations,
|
||||
d => isNonGlobalAmbientModule(d) && (!isExternalModuleAugmentation(d) || !isExternalModuleNameRelative(getTextOfIdentifierOrLiteral(d.name)))
|
||||
) as (ModuleDeclaration & { name: StringLiteral }) | undefined;
|
||||
if (decl) {
|
||||
return decl.name.text;
|
||||
}
|
||||
}
|
||||
@@ -248,7 +235,8 @@ namespace ts.moduleSpecifiers {
|
||||
const suffix = pattern.substr(indexOfStar + 1);
|
||||
if (relativeToBaseUrl.length >= prefix.length + suffix.length &&
|
||||
startsWith(relativeToBaseUrl, prefix) &&
|
||||
endsWith(relativeToBaseUrl, suffix)) {
|
||||
endsWith(relativeToBaseUrl, suffix) ||
|
||||
!suffix && relativeToBaseUrl === removeTrailingDirectorySeparator(prefix)) {
|
||||
const matchedStar = relativeToBaseUrl.substr(prefix.length, relativeToBaseUrl.length - suffix.length);
|
||||
return key.replace("*", matchedStar);
|
||||
}
|
||||
@@ -271,39 +259,33 @@ namespace ts.moduleSpecifiers {
|
||||
return removeFileExtension(relativePath);
|
||||
}
|
||||
|
||||
function tryGetModuleNameFromTypeRoots(
|
||||
options: CompilerOptions,
|
||||
host: GetEffectiveTypeRootsHost,
|
||||
getCanonicalFileName: (file: string) => string,
|
||||
moduleFileName: string,
|
||||
addJsExtension: boolean,
|
||||
): string | undefined {
|
||||
const roots = getEffectiveTypeRoots(options, host);
|
||||
return firstDefined(roots, unNormalizedTypeRoot => {
|
||||
const typeRoot = toPath(unNormalizedTypeRoot, /*basePath*/ undefined, getCanonicalFileName);
|
||||
if (startsWith(moduleFileName, typeRoot)) {
|
||||
// For a type definition, we can strip `/index` even with classic resolution.
|
||||
return removeExtensionAndIndexPostFix(moduleFileName.substring(typeRoot.length + 1), ModuleResolutionKind.NodeJs, addJsExtension);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function tryGetModuleNameAsNodeModule(
|
||||
options: CompilerOptions,
|
||||
moduleFileName: string,
|
||||
host: ModuleSpecifierResolutionHost,
|
||||
getCanonicalFileName: (file: string) => string,
|
||||
sourceDirectory: Path,
|
||||
): string | undefined {
|
||||
if (getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeJs) {
|
||||
// nothing to do here
|
||||
function tryGetModuleNameAsNodeModule(moduleFileName: string, { getCanonicalFileName, sourceDirectory }: Info, host: ModuleSpecifierResolutionHost, options: CompilerOptions): string | undefined {
|
||||
if (!host.fileExists || !host.readFile) {
|
||||
return undefined;
|
||||
}
|
||||
const parts: NodeModulePathParts = getNodeModulePathParts(moduleFileName)!;
|
||||
if (!parts) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const parts: NodeModulePathParts = getNodeModulePathParts(moduleFileName)!;
|
||||
|
||||
if (!parts) {
|
||||
return undefined;
|
||||
const packageRootPath = moduleFileName.substring(0, parts.packageRootIndex);
|
||||
const packageJsonPath = combinePaths(packageRootPath, "package.json");
|
||||
const packageJsonContent = host.fileExists(packageJsonPath)
|
||||
? JSON.parse(host.readFile(packageJsonPath)!)
|
||||
: undefined;
|
||||
const versionPaths = packageJsonContent && packageJsonContent.typesVersions
|
||||
? getPackageJsonTypesVersionsPaths(packageJsonContent.typesVersions)
|
||||
: undefined;
|
||||
if (versionPaths) {
|
||||
const subModuleName = moduleFileName.slice(parts.packageRootIndex + 1);
|
||||
const fromPaths = tryGetModuleNameFromPaths(
|
||||
removeFileExtension(subModuleName),
|
||||
removeExtensionAndIndexPostFix(subModuleName, Ending.Minimal, options),
|
||||
versionPaths.paths
|
||||
);
|
||||
if (fromPaths !== undefined) {
|
||||
moduleFileName = combinePaths(moduleFileName.slice(0, parts.packageRootIndex), fromPaths);
|
||||
}
|
||||
}
|
||||
|
||||
// Simplify the full file path to something that can be resolved by Node.
|
||||
@@ -313,22 +295,21 @@ namespace ts.moduleSpecifiers {
|
||||
// Get a path that's relative to node_modules or the importing file's path
|
||||
// if node_modules folder is in this folder or any of its parent folders, no need to keep it.
|
||||
if (!startsWith(sourceDirectory, getCanonicalFileName(moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex)))) return undefined;
|
||||
|
||||
// If the module was found in @types, get the actual Node package name
|
||||
return getPackageNameFromAtTypesDirectory(moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1));
|
||||
const nodeModulesDirectoryName = moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1);
|
||||
const packageName = getPackageNameFromTypesPackageName(nodeModulesDirectoryName);
|
||||
// For classic resolution, only allow importing from node_modules/@types, not other node_modules
|
||||
return getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeJs && packageName === nodeModulesDirectoryName ? undefined : packageName;
|
||||
|
||||
function getDirectoryOrExtensionlessFileName(path: string): string {
|
||||
// If the file is the main module, it can be imported by the package name
|
||||
const packageRootPath = path.substring(0, parts.packageRootIndex);
|
||||
const packageJsonPath = combinePaths(packageRootPath, "package.json");
|
||||
if (host.fileExists!(packageJsonPath)) { // TODO: GH#18217
|
||||
const packageJsonContent = JSON.parse(host.readFile!(packageJsonPath)!);
|
||||
if (packageJsonContent) {
|
||||
const mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main;
|
||||
if (mainFileRelative) {
|
||||
const mainExportFile = toPath(mainFileRelative, packageRootPath, getCanonicalFileName);
|
||||
if (removeFileExtension(mainExportFile) === removeFileExtension(getCanonicalFileName(path))) {
|
||||
return packageRootPath;
|
||||
}
|
||||
if (packageJsonContent) {
|
||||
const mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main;
|
||||
if (mainFileRelative) {
|
||||
const mainExportFile = toPath(mainFileRelative, packageRootPath, getCanonicalFileName);
|
||||
if (removeFileExtension(mainExportFile) === removeFileExtension(getCanonicalFileName(path))) {
|
||||
return packageRootPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -347,11 +328,12 @@ namespace ts.moduleSpecifiers {
|
||||
}
|
||||
|
||||
function tryGetAnyFileFromPath(host: ModuleSpecifierResolutionHost, path: string) {
|
||||
if (!host.fileExists) return;
|
||||
// We check all js, `node` and `json` extensions in addition to TS, since node module resolution would also choose those over the directory
|
||||
const extensions = getSupportedExtensions({ allowJs: true }, [{ extension: "node", isMixedContent: false }, { extension: "json", isMixedContent: false, scriptKind: ScriptKind.JSON }]);
|
||||
for (const e of extensions) {
|
||||
const fullPath = path + e;
|
||||
if (host.fileExists!(fullPath)) { // TODO: GH#18217
|
||||
if (host.fileExists(fullPath)) {
|
||||
return fullPath;
|
||||
}
|
||||
}
|
||||
@@ -389,7 +371,7 @@ namespace ts.moduleSpecifiers {
|
||||
partEnd = fullPath.indexOf("/", partStart + 1);
|
||||
switch (state) {
|
||||
case States.BeforeNodeModules:
|
||||
if (fullPath.indexOf("/node_modules/", partStart) === partStart) {
|
||||
if (fullPath.indexOf(nodeModulesPathPart, partStart) === partStart) {
|
||||
topLevelNodeModulesIndex = partStart;
|
||||
topLevelPackageNameIndex = partEnd;
|
||||
state = States.NodeModules;
|
||||
@@ -406,7 +388,7 @@ namespace ts.moduleSpecifiers {
|
||||
}
|
||||
break;
|
||||
case States.PackageContent:
|
||||
if (fullPath.indexOf("/node_modules/", partStart) === partStart) {
|
||||
if (fullPath.indexOf(nodeModulesPathPart, partStart) === partStart) {
|
||||
state = States.NodeModules;
|
||||
}
|
||||
else {
|
||||
@@ -428,13 +410,36 @@ namespace ts.moduleSpecifiers {
|
||||
});
|
||||
}
|
||||
|
||||
function removeExtensionAndIndexPostFix(fileName: string, moduleResolutionKind: ModuleResolutionKind, addJsExtension: boolean): string {
|
||||
function removeExtensionAndIndexPostFix(fileName: string, ending: Ending, options: CompilerOptions): string {
|
||||
if (fileExtensionIs(fileName, Extension.Json)) return fileName;
|
||||
const noExtension = removeFileExtension(fileName);
|
||||
return addJsExtension
|
||||
? noExtension + ".js"
|
||||
: moduleResolutionKind === ModuleResolutionKind.NodeJs
|
||||
? removeSuffix(noExtension, "/index")
|
||||
: noExtension;
|
||||
switch (ending) {
|
||||
case Ending.Minimal:
|
||||
return removeSuffix(noExtension, "/index");
|
||||
case Ending.Index:
|
||||
return noExtension;
|
||||
case Ending.JsExtension:
|
||||
return noExtension + getJSExtensionForFile(fileName, options);
|
||||
default:
|
||||
return Debug.assertNever(ending);
|
||||
}
|
||||
}
|
||||
|
||||
function getJSExtensionForFile(fileName: string, options: CompilerOptions): Extension {
|
||||
const ext = extensionFromPath(fileName);
|
||||
switch (ext) {
|
||||
case Extension.Ts:
|
||||
case Extension.Dts:
|
||||
return Extension.Js;
|
||||
case Extension.Tsx:
|
||||
return options.jsx === JsxEmit.Preserve ? Extension.Jsx : Extension.Js;
|
||||
case Extension.Js:
|
||||
case Extension.Jsx:
|
||||
case Extension.Json:
|
||||
return ext;
|
||||
default:
|
||||
return Debug.assertNever(ext);
|
||||
}
|
||||
}
|
||||
|
||||
function getRelativePathIfInDirectory(path: string, directoryPath: string, getCanonicalFileName: GetCanonicalFileName): string | undefined {
|
||||
|
||||
+191
-176
@@ -86,6 +86,7 @@ namespace ts {
|
||||
visitNodes(cbNode, cbNodes, node.modifiers) ||
|
||||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).name) ||
|
||||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).questionToken) ||
|
||||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).exclamationToken) ||
|
||||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).equalsToken) ||
|
||||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).objectAssignmentInitializer);
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
@@ -156,6 +157,7 @@ namespace ts {
|
||||
visitNode(cbNode, (<FunctionLikeDeclaration>node).asteriskToken) ||
|
||||
visitNode(cbNode, (<FunctionLikeDeclaration>node).name) ||
|
||||
visitNode(cbNode, (<FunctionLikeDeclaration>node).questionToken) ||
|
||||
visitNode(cbNode, (<FunctionLikeDeclaration>node).exclamationToken) ||
|
||||
visitNodes(cbNode, cbNodes, (<FunctionLikeDeclaration>node).typeParameters) ||
|
||||
visitNodes(cbNode, cbNodes, (<FunctionLikeDeclaration>node).parameters) ||
|
||||
visitNode(cbNode, (<FunctionLikeDeclaration>node).type) ||
|
||||
@@ -460,52 +462,46 @@ namespace ts {
|
||||
return visitNodes(cbNode, cbNodes, (<JSDoc>node).tags);
|
||||
case SyntaxKind.JSDocParameterTag:
|
||||
case SyntaxKind.JSDocPropertyTag:
|
||||
if ((node as JSDocPropertyLikeTag).isNameFirst) {
|
||||
return visitNode(cbNode, (<JSDocPropertyLikeTag>node).name) ||
|
||||
visitNode(cbNode, (<JSDocPropertyLikeTag>node).typeExpression);
|
||||
}
|
||||
else {
|
||||
return visitNode(cbNode, (<JSDocPropertyLikeTag>node).typeExpression) ||
|
||||
visitNode(cbNode, (<JSDocPropertyLikeTag>node).name);
|
||||
}
|
||||
case SyntaxKind.JSDocReturnTag:
|
||||
return visitNode(cbNode, (<JSDocReturnTag>node).typeExpression);
|
||||
case SyntaxKind.JSDocTypeTag:
|
||||
return visitNode(cbNode, (<JSDocTypeTag>node).typeExpression);
|
||||
return visitNode(cbNode, (node as JSDocTag).tagName) ||
|
||||
((node as JSDocPropertyLikeTag).isNameFirst
|
||||
? visitNode(cbNode, (<JSDocPropertyLikeTag>node).name) ||
|
||||
visitNode(cbNode, (<JSDocPropertyLikeTag>node).typeExpression)
|
||||
: visitNode(cbNode, (<JSDocPropertyLikeTag>node).typeExpression) ||
|
||||
visitNode(cbNode, (<JSDocPropertyLikeTag>node).name));
|
||||
case SyntaxKind.JSDocAugmentsTag:
|
||||
return visitNode(cbNode, (<JSDocAugmentsTag>node).class);
|
||||
return visitNode(cbNode, (node as JSDocTag).tagName) ||
|
||||
visitNode(cbNode, (<JSDocAugmentsTag>node).class);
|
||||
case SyntaxKind.JSDocTemplateTag:
|
||||
return visitNodes(cbNode, cbNodes, (<JSDocTemplateTag>node).typeParameters);
|
||||
return visitNode(cbNode, (node as JSDocTag).tagName) ||
|
||||
visitNode(cbNode, (<JSDocTemplateTag>node).constraint) ||
|
||||
visitNodes(cbNode, cbNodes, (<JSDocTemplateTag>node).typeParameters);
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
if ((node as JSDocTypedefTag).typeExpression &&
|
||||
(node as JSDocTypedefTag).typeExpression!.kind === SyntaxKind.JSDocTypeExpression) {
|
||||
return visitNode(cbNode, (<JSDocTypedefTag>node).typeExpression) ||
|
||||
visitNode(cbNode, (<JSDocTypedefTag>node).fullName);
|
||||
}
|
||||
else {
|
||||
return visitNode(cbNode, (<JSDocTypedefTag>node).fullName) ||
|
||||
visitNode(cbNode, (<JSDocTypedefTag>node).typeExpression);
|
||||
}
|
||||
return visitNode(cbNode, (node as JSDocTag).tagName) ||
|
||||
((node as JSDocTypedefTag).typeExpression &&
|
||||
(node as JSDocTypedefTag).typeExpression!.kind === SyntaxKind.JSDocTypeExpression
|
||||
? visitNode(cbNode, (<JSDocTypedefTag>node).typeExpression) ||
|
||||
visitNode(cbNode, (<JSDocTypedefTag>node).fullName)
|
||||
: visitNode(cbNode, (<JSDocTypedefTag>node).fullName) ||
|
||||
visitNode(cbNode, (<JSDocTypedefTag>node).typeExpression));
|
||||
case SyntaxKind.JSDocCallbackTag:
|
||||
return visitNode(cbNode, (node as JSDocCallbackTag).fullName) ||
|
||||
return visitNode(cbNode, (node as JSDocTag).tagName) ||
|
||||
visitNode(cbNode, (node as JSDocCallbackTag).fullName) ||
|
||||
visitNode(cbNode, (node as JSDocCallbackTag).typeExpression);
|
||||
case SyntaxKind.JSDocReturnTag:
|
||||
case SyntaxKind.JSDocTypeTag:
|
||||
case SyntaxKind.JSDocThisTag:
|
||||
return visitNode(cbNode, (node as JSDocThisTag).typeExpression);
|
||||
case SyntaxKind.JSDocEnumTag:
|
||||
return visitNode(cbNode, (node as JSDocEnumTag).typeExpression);
|
||||
return visitNode(cbNode, (node as JSDocTag).tagName) ||
|
||||
visitNode(cbNode, (node as JSDocReturnTag | JSDocTypeTag | JSDocThisTag | JSDocEnumTag).typeExpression);
|
||||
case SyntaxKind.JSDocSignature:
|
||||
return visitNodes(cbNode, cbNodes, node.decorators) ||
|
||||
visitNodes(cbNode, cbNodes, node.modifiers) ||
|
||||
forEach((<JSDocSignature>node).typeParameters, cbNode) ||
|
||||
return forEach((<JSDocSignature>node).typeParameters, cbNode) ||
|
||||
forEach((<JSDocSignature>node).parameters, cbNode) ||
|
||||
visitNode(cbNode, (<JSDocSignature>node).type);
|
||||
case SyntaxKind.JSDocTypeLiteral:
|
||||
if ((node as JSDocTypeLiteral).jsDocPropertyTags) {
|
||||
for (const tag of (node as JSDocTypeLiteral).jsDocPropertyTags!) {
|
||||
visitNode(cbNode, tag);
|
||||
}
|
||||
}
|
||||
return;
|
||||
return forEach((node as JSDocTypeLiteral).jsDocPropertyTags, cbNode);
|
||||
case SyntaxKind.JSDocTag:
|
||||
case SyntaxKind.JSDocClassTag:
|
||||
return visitNode(cbNode, (node as JSDocTag).tagName);
|
||||
case SyntaxKind.PartiallyEmittedExpression:
|
||||
return visitNode(cbNode, (<PartiallyEmittedExpression>node).expression);
|
||||
}
|
||||
@@ -515,7 +511,7 @@ namespace ts {
|
||||
performance.mark("beforeParse");
|
||||
let result: SourceFile;
|
||||
if (languageVersion === ScriptTarget.JSON) {
|
||||
result = Parser.parseJsonText(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes);
|
||||
result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, ScriptKind.JSON);
|
||||
}
|
||||
else {
|
||||
result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, scriptKind);
|
||||
@@ -689,8 +685,12 @@ namespace ts {
|
||||
if (scriptKind === ScriptKind.JSON) {
|
||||
const result = parseJsonText(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes);
|
||||
convertToObjectWorker(result, result.parseDiagnostics, /*returnValue*/ false, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined);
|
||||
result.referencedFiles = emptyArray;
|
||||
result.typeReferenceDirectives = emptyArray;
|
||||
result.libReferenceDirectives = emptyArray;
|
||||
result.amdDependencies = emptyArray;
|
||||
result.hasNoDefaultLib = false;
|
||||
result.pragmas = emptyMap;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1476,7 +1476,15 @@ namespace ts {
|
||||
// which would be a candidate for improved error reporting.
|
||||
return token() === SyntaxKind.OpenBracketToken || isLiteralPropertyName();
|
||||
case ParsingContext.ObjectLiteralMembers:
|
||||
return token() === SyntaxKind.OpenBracketToken || token() === SyntaxKind.AsteriskToken || token() === SyntaxKind.DotDotDotToken || isLiteralPropertyName();
|
||||
switch (token()) {
|
||||
case SyntaxKind.OpenBracketToken:
|
||||
case SyntaxKind.AsteriskToken:
|
||||
case SyntaxKind.DotDotDotToken:
|
||||
case SyntaxKind.DotToken: // Not an object literal member, but don't want to close the object (see `tests/cases/fourslash/completionsDotInObjectLiteral.ts`)
|
||||
return true;
|
||||
default:
|
||||
return isLiteralPropertyName();
|
||||
}
|
||||
case ParsingContext.RestProperties:
|
||||
return isLiteralPropertyName();
|
||||
case ParsingContext.ObjectBindingElements:
|
||||
@@ -1504,8 +1512,10 @@ namespace ts {
|
||||
case ParsingContext.TypeParameters:
|
||||
return isIdentifier();
|
||||
case ParsingContext.ArrayLiteralMembers:
|
||||
if (token() === SyntaxKind.CommaToken) {
|
||||
return true;
|
||||
switch (token()) {
|
||||
case SyntaxKind.CommaToken:
|
||||
case SyntaxKind.DotToken: // Not an array literal member, but don't want to close the array (see `tests/cases/fourslash/completionsDotInArrayLiteralInObjectLiteral.ts`)
|
||||
return true;
|
||||
}
|
||||
// falls through
|
||||
case ParsingContext.ArgumentExpressions:
|
||||
@@ -1707,6 +1717,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function currentNode(parsingContext: ParsingContext): Node | undefined {
|
||||
// If we don't have a cursor or the parsing context isn't reusable, there's nothing to reuse.
|
||||
//
|
||||
// If there is an outstanding parse error that we've encountered, but not attached to
|
||||
// some node, then we cannot get a node from the old source tree. This is because we
|
||||
// want to mark the next node we encounter as being unusable.
|
||||
@@ -1714,30 +1726,17 @@ namespace ts {
|
||||
// Note: This may be too conservative. Perhaps we could reuse the node and set the bit
|
||||
// on it (or its leftmost child) as having the error. For now though, being conservative
|
||||
// is nice and likely won't ever affect perf.
|
||||
if (parseErrorBeforeNextFinishedNode) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (!syntaxCursor) {
|
||||
// if we don't have a cursor, we could never return a node from the old tree.
|
||||
if (!syntaxCursor || !isReusableParsingContext(parsingContext) || parseErrorBeforeNextFinishedNode) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const node = syntaxCursor.currentNode(scanner.getStartPos());
|
||||
|
||||
// Can't reuse a missing node.
|
||||
if (nodeIsMissing(node)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Can't reuse a node that intersected the change range.
|
||||
if (node.intersectsChange) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Can't reuse a node that contains a parse error. This is necessary so that we
|
||||
// produce the same set of errors again.
|
||||
if (containsParseError(node)) {
|
||||
if (nodeIsMissing(node) || node.intersectsChange || containsParseError(node)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -1778,6 +1777,23 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
function isReusableParsingContext(parsingContext: ParsingContext): boolean {
|
||||
switch (parsingContext) {
|
||||
case ParsingContext.ClassMembers:
|
||||
case ParsingContext.SwitchClauses:
|
||||
case ParsingContext.SourceElements:
|
||||
case ParsingContext.BlockStatements:
|
||||
case ParsingContext.SwitchClauseStatements:
|
||||
case ParsingContext.EnumMembers:
|
||||
case ParsingContext.TypeMembers:
|
||||
case ParsingContext.VariableDeclarations:
|
||||
case ParsingContext.JSDocParameters:
|
||||
case ParsingContext.Parameters:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function canReuseNode(node: Node, parsingContext: ParsingContext): boolean {
|
||||
switch (parsingContext) {
|
||||
case ParsingContext.ClassMembers:
|
||||
@@ -1804,25 +1820,23 @@ namespace ts {
|
||||
case ParsingContext.Parameters:
|
||||
return isReusableParameter(node);
|
||||
|
||||
case ParsingContext.RestProperties:
|
||||
return false;
|
||||
|
||||
// Any other lists we do not care about reusing nodes in. But feel free to add if
|
||||
// you can do so safely. Danger areas involve nodes that may involve speculative
|
||||
// parsing. If speculative parsing is involved with the node, then the range the
|
||||
// parser reached while looking ahead might be in the edited range (see the example
|
||||
// in canReuseVariableDeclaratorNode for a good case of this).
|
||||
case ParsingContext.HeritageClauses:
|
||||
|
||||
// case ParsingContext.HeritageClauses:
|
||||
// This would probably be safe to reuse. There is no speculative parsing with
|
||||
// heritage clauses.
|
||||
|
||||
case ParsingContext.TypeParameters:
|
||||
// case ParsingContext.TypeParameters:
|
||||
// This would probably be safe to reuse. There is no speculative parsing with
|
||||
// type parameters. Note that that's because type *parameters* only occur in
|
||||
// unambiguous *type* contexts. While type *arguments* occur in very ambiguous
|
||||
// *expression* contexts.
|
||||
|
||||
case ParsingContext.TupleElementTypes:
|
||||
// case ParsingContext.TupleElementTypes:
|
||||
// This would probably be safe to reuse. There is no speculative parsing with
|
||||
// tuple types.
|
||||
|
||||
@@ -1831,28 +1845,28 @@ namespace ts {
|
||||
// produced from speculative parsing a < as a type argument list), we only have
|
||||
// the types because speculative parsing succeeded. Thus, the lookahead never
|
||||
// went past the end of the list and rewound.
|
||||
case ParsingContext.TypeArguments:
|
||||
// case ParsingContext.TypeArguments:
|
||||
|
||||
// Note: these are almost certainly not safe to ever reuse. Expressions commonly
|
||||
// need a large amount of lookahead, and we should not reuse them as they may
|
||||
// have actually intersected the edit.
|
||||
case ParsingContext.ArgumentExpressions:
|
||||
// case ParsingContext.ArgumentExpressions:
|
||||
|
||||
// This is not safe to reuse for the same reason as the 'AssignmentExpression'
|
||||
// cases. i.e. a property assignment may end with an expression, and thus might
|
||||
// have lookahead far beyond it's old node.
|
||||
case ParsingContext.ObjectLiteralMembers:
|
||||
// case ParsingContext.ObjectLiteralMembers:
|
||||
|
||||
// This is probably not safe to reuse. There can be speculative parsing with
|
||||
// type names in a heritage clause. There can be generic names in the type
|
||||
// name list, and there can be left hand side expressions (which can have type
|
||||
// arguments.)
|
||||
case ParsingContext.HeritageClauseElement:
|
||||
// case ParsingContext.HeritageClauseElement:
|
||||
|
||||
// Perhaps safe to reuse, but it's unlikely we'd see more than a dozen attributes
|
||||
// on any given element. Same for children.
|
||||
case ParsingContext.JsxAttributes:
|
||||
case ParsingContext.JsxChildren:
|
||||
// case ParsingContext.JsxAttributes:
|
||||
// case ParsingContext.JsxChildren:
|
||||
|
||||
}
|
||||
|
||||
@@ -2231,8 +2245,7 @@ namespace ts {
|
||||
|
||||
function parseLiteralLikeNode(kind: SyntaxKind): LiteralExpression | LiteralLikeNode {
|
||||
const node = <LiteralExpression>createNode(kind);
|
||||
const text = scanner.getTokenValue();
|
||||
node.text = text;
|
||||
node.text = scanner.getTokenValue();
|
||||
|
||||
if (scanner.hasExtendedUnicodeEscape()) {
|
||||
node.hasExtendedUnicodeEscape = true;
|
||||
@@ -2373,8 +2386,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
function parseJSDocType(): TypeNode {
|
||||
scanner.setInJSDocType(true);
|
||||
const dotdotdot = parseOptionalToken(SyntaxKind.DotDotDotToken);
|
||||
let type = parseType();
|
||||
let type = parseTypeOrTypePredicate();
|
||||
scanner.setInJSDocType(false);
|
||||
if (dotdotdot) {
|
||||
const variadic = createNode(SyntaxKind.JSDocVariadicType, dotdotdot.pos) as JSDocVariadicType;
|
||||
variadic.type = type;
|
||||
@@ -2874,8 +2889,9 @@ namespace ts {
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function nextTokenIsNumericLiteral() {
|
||||
return nextToken() === SyntaxKind.NumericLiteral;
|
||||
function nextTokenIsNumericOrBigIntLiteral() {
|
||||
nextToken();
|
||||
return token() === SyntaxKind.NumericLiteral || token() === SyntaxKind.BigIntLiteral;
|
||||
}
|
||||
|
||||
function parseNonArrayType(): TypeNode {
|
||||
@@ -2884,6 +2900,7 @@ namespace ts {
|
||||
case SyntaxKind.UnknownKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
case SyntaxKind.NumberKeyword:
|
||||
case SyntaxKind.BigIntKeyword:
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
case SyntaxKind.BooleanKeyword:
|
||||
case SyntaxKind.UndefinedKeyword:
|
||||
@@ -2904,11 +2921,12 @@ namespace ts {
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
return parseLiteralTypeNode();
|
||||
case SyntaxKind.MinusToken:
|
||||
return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode(/*negative*/ true) : parseTypeReference();
|
||||
return lookAhead(nextTokenIsNumericOrBigIntLiteral) ? parseLiteralTypeNode(/*negative*/ true) : parseTypeReference();
|
||||
case SyntaxKind.VoidKeyword:
|
||||
case SyntaxKind.NullKeyword:
|
||||
return parseTokenNode<TypeNode>();
|
||||
@@ -2942,6 +2960,7 @@ namespace ts {
|
||||
case SyntaxKind.UnknownKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
case SyntaxKind.NumberKeyword:
|
||||
case SyntaxKind.BigIntKeyword:
|
||||
case SyntaxKind.BooleanKeyword:
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
case SyntaxKind.UniqueKeyword:
|
||||
@@ -2959,6 +2978,7 @@ namespace ts {
|
||||
case SyntaxKind.NewKeyword:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
case SyntaxKind.ObjectKeyword:
|
||||
@@ -2972,7 +2992,7 @@ namespace ts {
|
||||
case SyntaxKind.FunctionKeyword:
|
||||
return !inStartOfParameter;
|
||||
case SyntaxKind.MinusToken:
|
||||
return !inStartOfParameter && lookAhead(nextTokenIsNumericLiteral);
|
||||
return !inStartOfParameter && lookAhead(nextTokenIsNumericOrBigIntLiteral);
|
||||
case SyntaxKind.OpenParenToken:
|
||||
// Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier,
|
||||
// or something that starts a type. We don't want to consider things like '(1)' a type.
|
||||
@@ -3197,6 +3217,7 @@ namespace ts {
|
||||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
case SyntaxKind.TemplateHead:
|
||||
@@ -4465,7 +4486,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
const argument = allowInAnd(parseExpression);
|
||||
if (isStringOrNumericLiteral(argument)) {
|
||||
if (isStringOrNumericLiteralLike(argument)) {
|
||||
argument.text = internIdentifier(argument.text);
|
||||
}
|
||||
indexedAccess.argumentExpression = argument;
|
||||
@@ -4606,6 +4627,7 @@ namespace ts {
|
||||
function parsePrimaryExpression(): PrimaryExpression {
|
||||
switch (token()) {
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
return parseLiteralNode();
|
||||
@@ -4707,8 +4729,10 @@ namespace ts {
|
||||
const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken);
|
||||
const tokenIsIdentifier = isIdentifier();
|
||||
node.name = parsePropertyName();
|
||||
// Disallowing of optional property assignments happens in the grammar checker.
|
||||
// Disallowing of optional property assignments and definite assignment assertion happens in the grammar checker.
|
||||
(<MethodDeclaration>node).questionToken = parseOptionalToken(SyntaxKind.QuestionToken);
|
||||
(<MethodDeclaration>node).exclamationToken = parseOptionalToken(SyntaxKind.ExclamationToken);
|
||||
|
||||
if (asteriskToken || token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) {
|
||||
return parseMethodDeclaration(<MethodDeclaration>node, asteriskToken);
|
||||
}
|
||||
@@ -4718,8 +4742,7 @@ namespace ts {
|
||||
// CoverInitializedName[Yield] :
|
||||
// IdentifierReference[?Yield] Initializer[In, ?Yield]
|
||||
// this is necessary because ObjectLiteral productions are also used to cover grammar for ObjectAssignmentPattern
|
||||
const isShorthandPropertyAssignment =
|
||||
tokenIsIdentifier && (token() === SyntaxKind.CommaToken || token() === SyntaxKind.CloseBraceToken || token() === SyntaxKind.EqualsToken);
|
||||
const isShorthandPropertyAssignment = tokenIsIdentifier && (token() !== SyntaxKind.ColonToken);
|
||||
if (isShorthandPropertyAssignment) {
|
||||
node.kind = SyntaxKind.ShorthandPropertyAssignment;
|
||||
const equalsToken = parseOptionalToken(SyntaxKind.EqualsToken);
|
||||
@@ -5120,7 +5143,7 @@ namespace ts {
|
||||
|
||||
function nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine() {
|
||||
nextToken();
|
||||
return (tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.NumericLiteral || token() === SyntaxKind.StringLiteral) && !scanner.hasPrecedingLineBreak();
|
||||
return (tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.NumericLiteral || token() === SyntaxKind.BigIntLiteral || token() === SyntaxKind.StringLiteral) && !scanner.hasPrecedingLineBreak();
|
||||
}
|
||||
|
||||
function isDeclaration(): boolean {
|
||||
@@ -6298,7 +6321,7 @@ namespace ts {
|
||||
|
||||
// Parses out a JSDoc type expression.
|
||||
export function parseJSDocTypeExpression(mayOmitBraces?: boolean): JSDocTypeExpression {
|
||||
const result = <JSDocTypeExpression>createNode(SyntaxKind.JSDocTypeExpression, scanner.getTokenPos());
|
||||
const result = <JSDocTypeExpression>createNode(SyntaxKind.JSDocTypeExpression);
|
||||
|
||||
const hasBrace = (mayOmitBraces ? parseOptional : parseExpected)(SyntaxKind.OpenBraceToken);
|
||||
result.type = doInsideOfContext(NodeFlags.JSDoc, parseJSDocType);
|
||||
@@ -6431,13 +6454,6 @@ namespace ts {
|
||||
indent += asterisk.length;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.Identifier:
|
||||
// Anything else is doc comment text. We just save it. Because it
|
||||
// wasn't a tag, we can no longer parse a tag on this line until we hit the next
|
||||
// line break.
|
||||
pushComment(scanner.getTokenText());
|
||||
state = JSDocState.SavingComments;
|
||||
break;
|
||||
case SyntaxKind.WhitespaceTrivia:
|
||||
// only collect whitespace if we're already saving comments or have just crossed the comment indent margin
|
||||
const whitespace = scanner.getTokenText();
|
||||
@@ -6452,7 +6468,9 @@ namespace ts {
|
||||
case SyntaxKind.EndOfFileToken:
|
||||
break loop;
|
||||
default:
|
||||
// anything other than whitespace or asterisk at the beginning of the line starts the comment text
|
||||
// Anything else is doc comment text. We just save it. Because it
|
||||
// wasn't a tag, we can no longer parse a tag on this line until we hit the next
|
||||
// line break.
|
||||
state = JSDocState.SavingComments;
|
||||
pushComment(scanner.getTokenText());
|
||||
break;
|
||||
@@ -6507,53 +6525,71 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function skipWhitespaceOrAsterisk(): void {
|
||||
if (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) {
|
||||
if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) {
|
||||
return; // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range
|
||||
}
|
||||
}
|
||||
|
||||
let precedingLineBreak = scanner.hasPrecedingLineBreak();
|
||||
while ((precedingLineBreak && token() === SyntaxKind.AsteriskToken) || token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) {
|
||||
if (token() === SyntaxKind.NewLineTrivia) {
|
||||
precedingLineBreak = true;
|
||||
}
|
||||
else if (token() === SyntaxKind.AsteriskToken) {
|
||||
precedingLineBreak = false;
|
||||
}
|
||||
nextJSDocToken();
|
||||
}
|
||||
}
|
||||
|
||||
function parseTag(indent: number) {
|
||||
Debug.assert(token() === SyntaxKind.AtToken);
|
||||
const atToken = <AtToken>createNode(SyntaxKind.AtToken, scanner.getTokenPos());
|
||||
atToken.end = scanner.getTextPos();
|
||||
const start = scanner.getTokenPos();
|
||||
nextJSDocToken();
|
||||
|
||||
const tagName = parseJSDocIdentifierName();
|
||||
skipWhitespace();
|
||||
const tagName = parseJSDocIdentifierName(/*message*/ undefined);
|
||||
skipWhitespaceOrAsterisk();
|
||||
|
||||
let tag: JSDocTag | undefined;
|
||||
switch (tagName.escapedText) {
|
||||
case "augments":
|
||||
case "extends":
|
||||
tag = parseAugmentsTag(atToken, tagName);
|
||||
tag = parseAugmentsTag(start, tagName);
|
||||
break;
|
||||
case "class":
|
||||
case "constructor":
|
||||
tag = parseClassTag(atToken, tagName);
|
||||
tag = parseClassTag(start, tagName);
|
||||
break;
|
||||
case "this":
|
||||
tag = parseThisTag(atToken, tagName);
|
||||
tag = parseThisTag(start, tagName);
|
||||
break;
|
||||
case "enum":
|
||||
tag = parseEnumTag(atToken, tagName);
|
||||
tag = parseEnumTag(start, tagName);
|
||||
break;
|
||||
case "arg":
|
||||
case "argument":
|
||||
case "param":
|
||||
return parseParameterOrPropertyTag(atToken, tagName, PropertyLikeParse.Parameter, indent);
|
||||
return parseParameterOrPropertyTag(start, tagName, PropertyLikeParse.Parameter, indent);
|
||||
case "return":
|
||||
case "returns":
|
||||
tag = parseReturnTag(atToken, tagName);
|
||||
tag = parseReturnTag(start, tagName);
|
||||
break;
|
||||
case "template":
|
||||
tag = parseTemplateTag(atToken, tagName);
|
||||
tag = parseTemplateTag(start, tagName);
|
||||
break;
|
||||
case "type":
|
||||
tag = parseTypeTag(atToken, tagName);
|
||||
tag = parseTypeTag(start, tagName);
|
||||
break;
|
||||
case "typedef":
|
||||
tag = parseTypedefTag(atToken, tagName, indent);
|
||||
tag = parseTypedefTag(start, tagName, indent);
|
||||
break;
|
||||
case "callback":
|
||||
tag = parseCallbackTag(atToken, tagName, indent);
|
||||
tag = parseCallbackTag(start, tagName, indent);
|
||||
break;
|
||||
default:
|
||||
tag = parseUnknownTag(atToken, tagName);
|
||||
tag = parseUnknownTag(start, tagName);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -6636,9 +6672,8 @@ namespace ts {
|
||||
return comments.length === 0 ? undefined : comments.join("");
|
||||
}
|
||||
|
||||
function parseUnknownTag(atToken: AtToken, tagName: Identifier) {
|
||||
const result = <JSDocTag>createNode(SyntaxKind.JSDocTag, atToken.pos);
|
||||
result.atToken = atToken;
|
||||
function parseUnknownTag(start: number, tagName: Identifier) {
|
||||
const result = <JSDocTag>createNode(SyntaxKind.JSDocTag, start);
|
||||
result.tagName = tagName;
|
||||
return finishNode(result);
|
||||
}
|
||||
@@ -6658,7 +6693,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function tryParseTypeExpression(): JSDocTypeExpression | undefined {
|
||||
skipWhitespace();
|
||||
skipWhitespaceOrAsterisk();
|
||||
return token() === SyntaxKind.OpenBraceToken ? parseJSDocTypeExpression() : undefined;
|
||||
}
|
||||
|
||||
@@ -6695,10 +6730,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function parseParameterOrPropertyTag(atToken: AtToken, tagName: Identifier, target: PropertyLikeParse, indent: number | undefined): JSDocParameterTag | JSDocPropertyTag {
|
||||
function parseParameterOrPropertyTag(start: number, tagName: Identifier, target: PropertyLikeParse, indent: number): JSDocParameterTag | JSDocPropertyTag {
|
||||
let typeExpression = tryParseTypeExpression();
|
||||
let isNameFirst = !typeExpression;
|
||||
skipWhitespace();
|
||||
skipWhitespaceOrAsterisk();
|
||||
|
||||
const { name, isBracketed } = parseBracketNameInPropertyAndParamTag();
|
||||
skipWhitespace();
|
||||
@@ -6708,16 +6743,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
const result = target === PropertyLikeParse.Property ?
|
||||
<JSDocPropertyTag>createNode(SyntaxKind.JSDocPropertyTag, atToken.pos) :
|
||||
<JSDocParameterTag>createNode(SyntaxKind.JSDocParameterTag, atToken.pos);
|
||||
let comment: string | undefined;
|
||||
if (indent !== undefined) comment = parseTagComments(indent + scanner.getStartPos() - atToken.pos);
|
||||
const nestedTypeLiteral = target !== PropertyLikeParse.CallbackParameter && parseNestedTypeLiteral(typeExpression, name, target);
|
||||
<JSDocPropertyTag>createNode(SyntaxKind.JSDocPropertyTag, start) :
|
||||
<JSDocParameterTag>createNode(SyntaxKind.JSDocParameterTag, start);
|
||||
const comment = parseTagComments(indent + scanner.getStartPos() - start);
|
||||
const nestedTypeLiteral = target !== PropertyLikeParse.CallbackParameter && parseNestedTypeLiteral(typeExpression, name, target, indent);
|
||||
if (nestedTypeLiteral) {
|
||||
typeExpression = nestedTypeLiteral;
|
||||
isNameFirst = true;
|
||||
}
|
||||
result.atToken = atToken;
|
||||
result.tagName = tagName;
|
||||
result.typeExpression = typeExpression;
|
||||
result.name = name;
|
||||
@@ -6727,14 +6760,14 @@ namespace ts {
|
||||
return finishNode(result);
|
||||
}
|
||||
|
||||
function parseNestedTypeLiteral(typeExpression: JSDocTypeExpression | undefined, name: EntityName, target: PropertyLikeParse) {
|
||||
function parseNestedTypeLiteral(typeExpression: JSDocTypeExpression | undefined, name: EntityName, target: PropertyLikeParse, indent: number) {
|
||||
if (typeExpression && isObjectOrObjectArrayTypeReference(typeExpression.type)) {
|
||||
const typeLiteralExpression = <JSDocTypeExpression>createNode(SyntaxKind.JSDocTypeExpression, scanner.getTokenPos());
|
||||
let child: JSDocPropertyLikeTag | JSDocTypeTag | false;
|
||||
let jsdocTypeLiteral: JSDocTypeLiteral;
|
||||
const start = scanner.getStartPos();
|
||||
let children: JSDocPropertyLikeTag[] | undefined;
|
||||
while (child = tryParse(() => parseChildParameterOrPropertyTag(target, name))) {
|
||||
while (child = tryParse(() => parseChildParameterOrPropertyTag(target, indent, name))) {
|
||||
if (child.kind === SyntaxKind.JSDocParameterTag || child.kind === SyntaxKind.JSDocPropertyTag) {
|
||||
children = append(children, child);
|
||||
}
|
||||
@@ -6751,33 +6784,30 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function parseReturnTag(atToken: AtToken, tagName: Identifier): JSDocReturnTag {
|
||||
function parseReturnTag(start: number, tagName: Identifier): JSDocReturnTag {
|
||||
if (forEach(tags, t => t.kind === SyntaxKind.JSDocReturnTag)) {
|
||||
parseErrorAt(tagName.pos, scanner.getTokenPos(), Diagnostics._0_tag_already_specified, tagName.escapedText);
|
||||
}
|
||||
|
||||
const result = <JSDocReturnTag>createNode(SyntaxKind.JSDocReturnTag, atToken.pos);
|
||||
result.atToken = atToken;
|
||||
const result = <JSDocReturnTag>createNode(SyntaxKind.JSDocReturnTag, start);
|
||||
result.tagName = tagName;
|
||||
result.typeExpression = tryParseTypeExpression();
|
||||
return finishNode(result);
|
||||
}
|
||||
|
||||
function parseTypeTag(atToken: AtToken, tagName: Identifier): JSDocTypeTag {
|
||||
function parseTypeTag(start: number, tagName: Identifier): JSDocTypeTag {
|
||||
if (forEach(tags, t => t.kind === SyntaxKind.JSDocTypeTag)) {
|
||||
parseErrorAt(tagName.pos, scanner.getTokenPos(), Diagnostics._0_tag_already_specified, tagName.escapedText);
|
||||
}
|
||||
|
||||
const result = <JSDocTypeTag>createNode(SyntaxKind.JSDocTypeTag, atToken.pos);
|
||||
result.atToken = atToken;
|
||||
const result = <JSDocTypeTag>createNode(SyntaxKind.JSDocTypeTag, start);
|
||||
result.tagName = tagName;
|
||||
result.typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true);
|
||||
return finishNode(result);
|
||||
}
|
||||
|
||||
function parseAugmentsTag(atToken: AtToken, tagName: Identifier): JSDocAugmentsTag {
|
||||
const result = <JSDocAugmentsTag>createNode(SyntaxKind.JSDocAugmentsTag, atToken.pos);
|
||||
result.atToken = atToken;
|
||||
function parseAugmentsTag(start: number, tagName: Identifier): JSDocAugmentsTag {
|
||||
const result = <JSDocAugmentsTag>createNode(SyntaxKind.JSDocAugmentsTag, start);
|
||||
result.tagName = tagName;
|
||||
result.class = parseExpressionWithTypeArgumentsForAugments();
|
||||
return finishNode(result);
|
||||
@@ -6806,37 +6836,33 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
function parseClassTag(atToken: AtToken, tagName: Identifier): JSDocClassTag {
|
||||
const tag = <JSDocClassTag>createNode(SyntaxKind.JSDocClassTag, atToken.pos);
|
||||
tag.atToken = atToken;
|
||||
function parseClassTag(start: number, tagName: Identifier): JSDocClassTag {
|
||||
const tag = <JSDocClassTag>createNode(SyntaxKind.JSDocClassTag, start);
|
||||
tag.tagName = tagName;
|
||||
return finishNode(tag);
|
||||
}
|
||||
|
||||
function parseThisTag(atToken: AtToken, tagName: Identifier): JSDocThisTag {
|
||||
const tag = <JSDocThisTag>createNode(SyntaxKind.JSDocThisTag, atToken.pos);
|
||||
tag.atToken = atToken;
|
||||
function parseThisTag(start: number, tagName: Identifier): JSDocThisTag {
|
||||
const tag = <JSDocThisTag>createNode(SyntaxKind.JSDocThisTag, start);
|
||||
tag.tagName = tagName;
|
||||
tag.typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true);
|
||||
skipWhitespace();
|
||||
return finishNode(tag);
|
||||
}
|
||||
|
||||
function parseEnumTag(atToken: AtToken, tagName: Identifier): JSDocEnumTag {
|
||||
const tag = <JSDocEnumTag>createNode(SyntaxKind.JSDocEnumTag, atToken.pos);
|
||||
tag.atToken = atToken;
|
||||
function parseEnumTag(start: number, tagName: Identifier): JSDocEnumTag {
|
||||
const tag = <JSDocEnumTag>createNode(SyntaxKind.JSDocEnumTag, start);
|
||||
tag.tagName = tagName;
|
||||
tag.typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true);
|
||||
skipWhitespace();
|
||||
return finishNode(tag);
|
||||
}
|
||||
|
||||
function parseTypedefTag(atToken: AtToken, tagName: Identifier, indent: number): JSDocTypedefTag {
|
||||
function parseTypedefTag(start: number, tagName: Identifier, indent: number): JSDocTypedefTag {
|
||||
const typeExpression = tryParseTypeExpression();
|
||||
skipWhitespace();
|
||||
skipWhitespaceOrAsterisk();
|
||||
|
||||
const typedefTag = <JSDocTypedefTag>createNode(SyntaxKind.JSDocTypedefTag, atToken.pos);
|
||||
typedefTag.atToken = atToken;
|
||||
const typedefTag = <JSDocTypedefTag>createNode(SyntaxKind.JSDocTypedefTag, start);
|
||||
typedefTag.tagName = tagName;
|
||||
typedefTag.fullName = parseJSDocTypeNameWithNamespace();
|
||||
typedefTag.name = getJSDocTypeAliasName(typedefTag.fullName);
|
||||
@@ -6849,8 +6875,7 @@ namespace ts {
|
||||
let child: JSDocTypeTag | JSDocPropertyTag | false;
|
||||
let jsdocTypeLiteral: JSDocTypeLiteral | undefined;
|
||||
let childTypeTag: JSDocTypeTag | undefined;
|
||||
const start = atToken.pos;
|
||||
while (child = tryParse(() => parseChildPropertyTag())) {
|
||||
while (child = tryParse(() => parseChildPropertyTag(indent))) {
|
||||
if (!jsdocTypeLiteral) {
|
||||
jsdocTypeLiteral = <JSDocTypeLiteral>createNode(SyntaxKind.JSDocTypeLiteral, start);
|
||||
}
|
||||
@@ -6903,9 +6928,8 @@ namespace ts {
|
||||
return typeNameOrNamespaceName;
|
||||
}
|
||||
|
||||
function parseCallbackTag(atToken: AtToken, tagName: Identifier, indent: number): JSDocCallbackTag {
|
||||
const callbackTag = createNode(SyntaxKind.JSDocCallbackTag, atToken.pos) as JSDocCallbackTag;
|
||||
callbackTag.atToken = atToken;
|
||||
function parseCallbackTag(start: number, tagName: Identifier, indent: number): JSDocCallbackTag {
|
||||
const callbackTag = createNode(SyntaxKind.JSDocCallbackTag, start) as JSDocCallbackTag;
|
||||
callbackTag.tagName = tagName;
|
||||
callbackTag.fullName = parseJSDocTypeNameWithNamespace();
|
||||
callbackTag.name = getJSDocTypeAliasName(callbackTag.fullName);
|
||||
@@ -6913,10 +6937,9 @@ namespace ts {
|
||||
callbackTag.comment = parseTagComments(indent);
|
||||
|
||||
let child: JSDocParameterTag | false;
|
||||
const start = scanner.getStartPos();
|
||||
const jsdocSignature = createNode(SyntaxKind.JSDocSignature, start) as JSDocSignature;
|
||||
jsdocSignature.parameters = [];
|
||||
while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.CallbackParameter) as JSDocParameterTag)) {
|
||||
while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.CallbackParameter, indent) as JSDocParameterTag)) {
|
||||
jsdocSignature.parameters = append(jsdocSignature.parameters as MutableNodeArray<JSDocParameterTag>, child);
|
||||
}
|
||||
const returnTag = tryParse(() => {
|
||||
@@ -6959,18 +6982,18 @@ namespace ts {
|
||||
return a.escapedText === b.escapedText;
|
||||
}
|
||||
|
||||
function parseChildPropertyTag() {
|
||||
return parseChildParameterOrPropertyTag(PropertyLikeParse.Property) as JSDocTypeTag | JSDocPropertyTag | false;
|
||||
function parseChildPropertyTag(indent: number) {
|
||||
return parseChildParameterOrPropertyTag(PropertyLikeParse.Property, indent) as JSDocTypeTag | JSDocPropertyTag | false;
|
||||
}
|
||||
|
||||
function parseChildParameterOrPropertyTag(target: PropertyLikeParse, name?: EntityName): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | false {
|
||||
function parseChildParameterOrPropertyTag(target: PropertyLikeParse, indent: number, name?: EntityName): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | false {
|
||||
let canParseTag = true;
|
||||
let seenAsterisk = false;
|
||||
while (true) {
|
||||
switch (nextJSDocToken()) {
|
||||
case SyntaxKind.AtToken:
|
||||
if (canParseTag) {
|
||||
const child = tryParseChildTag(target);
|
||||
const child = tryParseChildTag(target, indent);
|
||||
if (child && (child.kind === SyntaxKind.JSDocParameterTag || child.kind === SyntaxKind.JSDocPropertyTag) &&
|
||||
target !== PropertyLikeParse.CallbackParameter &&
|
||||
name && (ts.isIdentifier(child.name) || !escapedTextsEqual(name, child.name.left))) {
|
||||
@@ -6999,10 +7022,9 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function tryParseChildTag(target: PropertyLikeParse): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | false {
|
||||
function tryParseChildTag(target: PropertyLikeParse, indent: number): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | false {
|
||||
Debug.assert(token() === SyntaxKind.AtToken);
|
||||
const atToken = <AtToken>createNode(SyntaxKind.AtToken);
|
||||
atToken.end = scanner.getTextPos();
|
||||
const start = scanner.getStartPos();
|
||||
nextJSDocToken();
|
||||
|
||||
const tagName = parseJSDocIdentifierName();
|
||||
@@ -7010,7 +7032,7 @@ namespace ts {
|
||||
let t: PropertyLikeParse;
|
||||
switch (tagName.escapedText) {
|
||||
case "type":
|
||||
return target === PropertyLikeParse.Property && parseTypeTag(atToken, tagName);
|
||||
return target === PropertyLikeParse.Property && parseTypeTag(start, tagName);
|
||||
case "prop":
|
||||
case "property":
|
||||
t = PropertyLikeParse.Property;
|
||||
@@ -7026,12 +7048,10 @@ namespace ts {
|
||||
if (!(target & t)) {
|
||||
return false;
|
||||
}
|
||||
const tag = parseParameterOrPropertyTag(atToken, tagName, target, /*indent*/ undefined);
|
||||
tag.comment = parseTagComments(tag.end - tag.pos);
|
||||
return tag;
|
||||
return parseParameterOrPropertyTag(start, tagName, target, indent);
|
||||
}
|
||||
|
||||
function parseTemplateTag(atToken: AtToken, tagName: Identifier): JSDocTemplateTag {
|
||||
function parseTemplateTag(start: number, tagName: Identifier): JSDocTemplateTag {
|
||||
// the template tag looks like '@template {Constraint} T,U,V'
|
||||
let constraint: JSDocTypeExpression | undefined;
|
||||
if (token() === SyntaxKind.OpenBraceToken) {
|
||||
@@ -7049,13 +7069,9 @@ namespace ts {
|
||||
typeParameters.push(typeParameter);
|
||||
} while (parseOptionalJsdoc(SyntaxKind.CommaToken));
|
||||
|
||||
if (constraint) {
|
||||
first(typeParameters).constraint = constraint.type;
|
||||
}
|
||||
|
||||
const result = <JSDocTemplateTag>createNode(SyntaxKind.JSDocTemplateTag, atToken.pos);
|
||||
result.atToken = atToken;
|
||||
const result = <JSDocTemplateTag>createNode(SyntaxKind.JSDocTemplateTag, start);
|
||||
result.tagName = tagName;
|
||||
result.constraint = constraint;
|
||||
result.typeParameters = createNodeArray(typeParameters, typeParametersPos);
|
||||
finishNode(result);
|
||||
return result;
|
||||
@@ -7701,7 +7717,7 @@ namespace ts {
|
||||
/*@internal*/
|
||||
export function processCommentPragmas(context: PragmaContext, sourceText: string): void {
|
||||
const triviaScanner = createScanner(context.languageVersion, /*skipTrivia*/ false, LanguageVariant.Standard, sourceText);
|
||||
const pragmas: PragmaPsuedoMapEntry[] = [];
|
||||
const pragmas: PragmaPseudoMapEntry[] = [];
|
||||
|
||||
// Keep scanning all the leading trivia in the file until we get to something that
|
||||
// isn't trivia. Any single line comment will be analyzed to see if it is a
|
||||
@@ -7738,7 +7754,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
type PragmaDiagnosticReporter = (pos: number, length: number, message: DiagnosticMessage) => void;
|
||||
|
||||
/*@internal*/
|
||||
@@ -7757,7 +7772,7 @@ namespace ts {
|
||||
const referencedFiles = context.referencedFiles;
|
||||
const typeReferenceDirectives = context.typeReferenceDirectives;
|
||||
const libReferenceDirectives = context.libReferenceDirectives;
|
||||
forEach(toArray(entryOrList), (arg: PragmaPsuedoMap["reference"]) => {
|
||||
forEach(toArray(entryOrList), (arg: PragmaPseudoMap["reference"]) => {
|
||||
// TODO: GH#18217
|
||||
if (arg!.arguments["no-default-lib"]) {
|
||||
context.hasNoDefaultLib = true;
|
||||
@@ -7780,7 +7795,7 @@ namespace ts {
|
||||
case "amd-dependency": {
|
||||
context.amdDependencies = map(
|
||||
toArray(entryOrList),
|
||||
(x: PragmaPsuedoMap["amd-dependency"]) => ({ name: x!.arguments.name!, path: x!.arguments.path })); // TODO: GH#18217
|
||||
(x: PragmaPseudoMap["amd-dependency"]) => ({ name: x!.arguments.name!, path: x!.arguments.path })); // TODO: GH#18217
|
||||
break;
|
||||
}
|
||||
case "amd-module": {
|
||||
@@ -7790,11 +7805,11 @@ namespace ts {
|
||||
// TODO: It's probably fine to issue this diagnostic on all instances of the pragma
|
||||
reportDiagnostic(entry!.range.pos, entry!.range.end - entry!.range.pos, Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments);
|
||||
}
|
||||
context.moduleName = (entry as PragmaPsuedoMap["amd-module"])!.arguments.name;
|
||||
context.moduleName = (entry as PragmaPseudoMap["amd-module"])!.arguments.name;
|
||||
}
|
||||
}
|
||||
else {
|
||||
context.moduleName = (entryOrList as PragmaPsuedoMap["amd-module"])!.arguments.name;
|
||||
context.moduleName = (entryOrList as PragmaPseudoMap["amd-module"])!.arguments.name;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -7830,10 +7845,10 @@ namespace ts {
|
||||
|
||||
const tripleSlashXMLCommentStartRegEx = /^\/\/\/\s*<(\S+)\s.*?\/>/im;
|
||||
const singleLinePragmaRegEx = /^\/\/\/?\s*@(\S+)\s*(.*)\s*$/im;
|
||||
function extractPragmas(pragmas: PragmaPsuedoMapEntry[], range: CommentRange, text: string) {
|
||||
function extractPragmas(pragmas: PragmaPseudoMapEntry[], range: CommentRange, text: string) {
|
||||
const tripleSlash = range.kind === SyntaxKind.SingleLineCommentTrivia && tripleSlashXMLCommentStartRegEx.exec(text);
|
||||
if (tripleSlash) {
|
||||
const name = tripleSlash[1].toLowerCase() as keyof PragmaPsuedoMap; // Technically unsafe cast, but we do it so the below check to make it safe typechecks
|
||||
const name = tripleSlash[1].toLowerCase() as keyof PragmaPseudoMap; // Technically unsafe cast, but we do it so the below check to make it safe typechecks
|
||||
const pragma = commentPragmas[name] as PragmaDefinition;
|
||||
if (!pragma || !(pragma.kind! & PragmaKindFlags.TripleSlashXML)) {
|
||||
return;
|
||||
@@ -7860,10 +7875,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
pragmas.push({ name, args: { arguments: argument, range } } as PragmaPsuedoMapEntry);
|
||||
pragmas.push({ name, args: { arguments: argument, range } } as PragmaPseudoMapEntry);
|
||||
}
|
||||
else {
|
||||
pragmas.push({ name, args: { arguments: {}, range } } as PragmaPsuedoMapEntry);
|
||||
pragmas.push({ name, args: { arguments: {}, range } } as PragmaPseudoMapEntry);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -7882,9 +7897,9 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function addPragmaForMatch(pragmas: PragmaPsuedoMapEntry[], range: CommentRange, kind: PragmaKindFlags, match: RegExpExecArray) {
|
||||
function addPragmaForMatch(pragmas: PragmaPseudoMapEntry[], range: CommentRange, kind: PragmaKindFlags, match: RegExpExecArray) {
|
||||
if (!match) return;
|
||||
const name = match[1].toLowerCase() as keyof PragmaPsuedoMap; // Technically unsafe cast, but we do it so they below check to make it safe typechecks
|
||||
const name = match[1].toLowerCase() as keyof PragmaPseudoMap; // Technically unsafe cast, but we do it so they below check to make it safe typechecks
|
||||
const pragma = commentPragmas[name] as PragmaDefinition;
|
||||
if (!pragma || !(pragma.kind! & kind)) {
|
||||
return;
|
||||
@@ -7892,7 +7907,7 @@ namespace ts {
|
||||
const args = match[2]; // Split on spaces and match up positionally with definition
|
||||
const argument = getNamedPragmaArguments(pragma, args);
|
||||
if (argument === "fail") return; // Missing required argument, fail to parse it
|
||||
pragmas.push({ name, args: { arguments: argument, range } } as PragmaPsuedoMapEntry);
|
||||
pragmas.push({ name, args: { arguments: argument, range } } as PragmaPseudoMapEntry);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,41 @@ namespace ts.performance {
|
||||
let marks: Map<number>;
|
||||
let measures: Map<number>;
|
||||
|
||||
export interface Timer {
|
||||
enter(): void;
|
||||
exit(): void;
|
||||
}
|
||||
|
||||
export function createTimerIf(condition: boolean, measureName: string, startMarkName: string, endMarkName: string) {
|
||||
return condition ? createTimer(measureName, startMarkName, endMarkName) : nullTimer;
|
||||
}
|
||||
|
||||
export function createTimer(measureName: string, startMarkName: string, endMarkName: string): Timer {
|
||||
let enterCount = 0;
|
||||
return {
|
||||
enter,
|
||||
exit
|
||||
};
|
||||
|
||||
function enter() {
|
||||
if (++enterCount === 1) {
|
||||
mark(startMarkName);
|
||||
}
|
||||
}
|
||||
|
||||
function exit() {
|
||||
if (--enterCount === 0) {
|
||||
mark(endMarkName);
|
||||
measure(measureName, startMarkName, endMarkName);
|
||||
}
|
||||
else if (enterCount < 0) {
|
||||
Debug.fail("enter/exit count does not match.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const nullTimer: Timer = { enter: noop, exit: noop };
|
||||
|
||||
/**
|
||||
* Marks a performance event.
|
||||
*
|
||||
|
||||
+620
-322
File diff suppressed because it is too large
Load Diff
@@ -5,12 +5,13 @@ namespace ts {
|
||||
startRecordingFilesWithChangedResolutions(): void;
|
||||
finishRecordingFilesWithChangedResolutions(): Path[] | undefined;
|
||||
|
||||
resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined): ResolvedModuleFull[];
|
||||
resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference?: ResolvedProjectReference): (ResolvedModuleFull | undefined)[];
|
||||
getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): CachedResolvedModuleWithFailedLookupLocations | undefined;
|
||||
resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): (ResolvedTypeReferenceDirective | undefined)[];
|
||||
|
||||
invalidateResolutionOfFile(filePath: Path): void;
|
||||
removeResolutionsOfFile(filePath: Path): void;
|
||||
removeResolutionsFromProjectReferenceRedirects(filePath: Path): void;
|
||||
setFilesWithInvalidatedNonRelativeUnresolvedImports(filesWithUnresolvedImports: Map<ReadonlyArray<string>>): void;
|
||||
createHasInvalidatedResolution(forceAllFilesAsInvalidated?: boolean): HasInvalidatedResolution;
|
||||
|
||||
@@ -68,7 +69,10 @@ namespace ts {
|
||||
dir: string;
|
||||
dirPath: Path;
|
||||
nonRecursive?: boolean;
|
||||
ignore?: true;
|
||||
}
|
||||
|
||||
export function isPathInNodeModulesStartingWithDot(path: Path) {
|
||||
return stringContains(path, "/node_modules/.");
|
||||
}
|
||||
|
||||
export const maxNumberOfFilesToIterateForInvalidation = 256;
|
||||
@@ -79,7 +83,7 @@ namespace ts {
|
||||
export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootDirForResolution: string | undefined, logChangesWhenResolvingModule: boolean): ResolutionCache {
|
||||
let filesWithChangedSetOfUnresolvedImports: Path[] | undefined;
|
||||
let filesWithInvalidatedResolutions: Map<true> | undefined;
|
||||
let filesWithInvalidatedNonRelativeUnresolvedImports: Map<ReadonlyArray<string>> | undefined;
|
||||
let filesWithInvalidatedNonRelativeUnresolvedImports: ReadonlyMap<ReadonlyArray<string>> | undefined;
|
||||
let allFilesHaveInvalidatedResolution = false;
|
||||
const nonRelativeExternalModuleResolutions = createMultiMap<ResolutionWithFailedLookupLocations>();
|
||||
|
||||
@@ -90,17 +94,17 @@ namespace ts {
|
||||
// The key in the map is source file's path.
|
||||
// The values are Map of resolutions with key being name lookedup.
|
||||
const resolvedModuleNames = createMap<Map<CachedResolvedModuleWithFailedLookupLocations>>();
|
||||
const perDirectoryResolvedModuleNames = createMap<Map<CachedResolvedModuleWithFailedLookupLocations>>();
|
||||
const nonRelaticeModuleNameCache = createMap<PerModuleNameCache>();
|
||||
const perDirectoryResolvedModuleNames: CacheWithRedirects<Map<CachedResolvedModuleWithFailedLookupLocations>> = createCacheWithRedirects();
|
||||
const nonRelativeModuleNameCache: CacheWithRedirects<PerModuleNameCache> = createCacheWithRedirects();
|
||||
const moduleResolutionCache = createModuleResolutionCacheWithMaps(
|
||||
perDirectoryResolvedModuleNames,
|
||||
nonRelaticeModuleNameCache,
|
||||
nonRelativeModuleNameCache,
|
||||
getCurrentDirectory(),
|
||||
resolutionHost.getCanonicalFileName
|
||||
);
|
||||
|
||||
const resolvedTypeReferenceDirectives = createMap<Map<CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations>>();
|
||||
const perDirectoryResolvedTypeReferenceDirectives = createMap<Map<CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations>>();
|
||||
const perDirectoryResolvedTypeReferenceDirectives: CacheWithRedirects<Map<CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations>> = createCacheWithRedirects();
|
||||
|
||||
/**
|
||||
* These are the extensions that failed lookup files will have by default,
|
||||
@@ -128,6 +132,7 @@ namespace ts {
|
||||
resolveModuleNames,
|
||||
getResolvedModuleWithFailedLookupLocationsFromCache,
|
||||
resolveTypeReferenceDirectives,
|
||||
removeResolutionsFromProjectReferenceRedirects,
|
||||
removeResolutionsOfFile,
|
||||
invalidateResolutionOfFile,
|
||||
setFilesWithInvalidatedNonRelativeUnresolvedImports,
|
||||
@@ -199,7 +204,7 @@ namespace ts {
|
||||
|
||||
function clearPerDirectoryResolutions() {
|
||||
perDirectoryResolvedModuleNames.clear();
|
||||
nonRelaticeModuleNameCache.clear();
|
||||
nonRelativeModuleNameCache.clear();
|
||||
perDirectoryResolvedTypeReferenceDirectives.clear();
|
||||
nonRelativeExternalModuleResolutions.forEach(watchFailedLookupLocationOfNonRelativeModuleResolutions);
|
||||
nonRelativeExternalModuleResolutions.clear();
|
||||
@@ -217,8 +222,8 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): CachedResolvedModuleWithFailedLookupLocations {
|
||||
const primaryResult = ts.resolveModuleName(moduleName, containingFile, compilerOptions, host, moduleResolutionCache);
|
||||
function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference): CachedResolvedModuleWithFailedLookupLocations {
|
||||
const primaryResult = ts.resolveModuleName(moduleName, containingFile, compilerOptions, host, moduleResolutionCache, redirectedReference);
|
||||
// return result immediately only if global cache support is not enabled or if it is .ts, .tsx or .d.ts
|
||||
if (!resolutionHost.getGlobalCache) {
|
||||
return primaryResult;
|
||||
@@ -226,7 +231,7 @@ namespace ts {
|
||||
|
||||
// otherwise try to load typings from @types
|
||||
const globalCache = resolutionHost.getGlobalCache();
|
||||
if (globalCache !== undefined && !isExternalModuleNameRelative(moduleName) && !(primaryResult.resolvedModule && extensionIsTypeScript(primaryResult.resolvedModule.extension))) {
|
||||
if (globalCache !== undefined && !isExternalModuleNameRelative(moduleName) && !(primaryResult.resolvedModule && extensionIsTS(primaryResult.resolvedModule.extension))) {
|
||||
// create different collection of failed lookup locations for second pass
|
||||
// if it will fail and we've already found something during the first pass - we don't want to pollute its results
|
||||
const { resolvedModule, failedLookupLocations } = loadModuleFromGlobalCache(moduleName, resolutionHost.projectName, compilerOptions, host, globalCache);
|
||||
@@ -240,41 +245,52 @@ namespace ts {
|
||||
}
|
||||
|
||||
function resolveNamesWithLocalCache<T extends ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName>(
|
||||
names: string[],
|
||||
names: ReadonlyArray<string>,
|
||||
containingFile: string,
|
||||
redirectedReference: ResolvedProjectReference | undefined,
|
||||
cache: Map<Map<T>>,
|
||||
perDirectoryCache: Map<Map<T>>,
|
||||
loader: (name: string, containingFile: string, options: CompilerOptions, host: ModuleResolutionHost) => T,
|
||||
perDirectoryCacheWithRedirects: CacheWithRedirects<Map<T>>,
|
||||
loader: (name: string, containingFile: string, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference) => T,
|
||||
getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName<T, R>,
|
||||
reusedNames: string[] | undefined,
|
||||
logChanges: boolean): R[] {
|
||||
shouldRetryResolution: (t: T) => boolean,
|
||||
reusedNames: ReadonlyArray<string> | undefined,
|
||||
logChanges: boolean): (R | undefined)[] {
|
||||
|
||||
const path = resolutionHost.toPath(containingFile);
|
||||
const resolutionsInFile = cache.get(path) || cache.set(path, createMap()).get(path)!;
|
||||
const dirPath = getDirectoryPath(path);
|
||||
const perDirectoryCache = perDirectoryCacheWithRedirects.getOrCreateMapOfCacheRedirects(redirectedReference);
|
||||
let perDirectoryResolution = perDirectoryCache.get(dirPath);
|
||||
if (!perDirectoryResolution) {
|
||||
perDirectoryResolution = createMap();
|
||||
perDirectoryCache.set(dirPath, perDirectoryResolution);
|
||||
}
|
||||
const resolvedModules: R[] = [];
|
||||
const resolvedModules: (R | undefined)[] = [];
|
||||
const compilerOptions = resolutionHost.getCompilationSettings();
|
||||
const hasInvalidatedNonRelativeUnresolvedImport = logChanges && isFileWithInvalidatedNonRelativeUnresolvedImports(path);
|
||||
|
||||
// All the resolutions in this file are invalidated if this file wasnt resolved using same redirect
|
||||
const program = resolutionHost.getCurrentProgram();
|
||||
const oldRedirect = program && program.getResolvedProjectReferenceToRedirect(containingFile);
|
||||
const unmatchedRedirects = oldRedirect ?
|
||||
!redirectedReference || redirectedReference.sourceFile.path !== oldRedirect.sourceFile.path :
|
||||
!!redirectedReference;
|
||||
|
||||
const seenNamesInFile = createMap<true>();
|
||||
for (const name of names) {
|
||||
let resolution = resolutionsInFile.get(name);
|
||||
// Resolution is valid if it is present and not invalidated
|
||||
if (!seenNamesInFile.has(name) &&
|
||||
allFilesHaveInvalidatedResolution || !resolution || resolution.isInvalidated ||
|
||||
allFilesHaveInvalidatedResolution || unmatchedRedirects || !resolution || resolution.isInvalidated ||
|
||||
// If the name is unresolved import that was invalidated, recalculate
|
||||
(hasInvalidatedNonRelativeUnresolvedImport && !isExternalModuleNameRelative(name) && !getResolutionWithResolvedFileName(resolution))) {
|
||||
(hasInvalidatedNonRelativeUnresolvedImport && !isExternalModuleNameRelative(name) && shouldRetryResolution(resolution))) {
|
||||
const existingResolution = resolution;
|
||||
const resolutionInDirectory = perDirectoryResolution.get(name);
|
||||
if (resolutionInDirectory) {
|
||||
resolution = resolutionInDirectory;
|
||||
}
|
||||
else {
|
||||
resolution = loader(name, containingFile, compilerOptions, resolutionHost);
|
||||
resolution = loader(name, containingFile, compilerOptions, resolutionHost, redirectedReference);
|
||||
perDirectoryResolution.set(name, resolution);
|
||||
}
|
||||
resolutionsInFile.set(name, resolution);
|
||||
@@ -291,7 +307,7 @@ namespace ts {
|
||||
}
|
||||
Debug.assert(resolution !== undefined && !resolution.isInvalidated);
|
||||
seenNamesInFile.set(name, true);
|
||||
resolvedModules.push(getResolutionWithResolvedFileName(resolution)!); // TODO: GH#18217
|
||||
resolvedModules.push(getResolutionWithResolvedFileName(resolution));
|
||||
}
|
||||
|
||||
// Stop watching and remove the unused name
|
||||
@@ -323,20 +339,22 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[] {
|
||||
function resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): (ResolvedTypeReferenceDirective | undefined)[] {
|
||||
return resolveNamesWithLocalCache<CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations, ResolvedTypeReferenceDirective>(
|
||||
typeDirectiveNames, containingFile,
|
||||
typeDirectiveNames, containingFile, redirectedReference,
|
||||
resolvedTypeReferenceDirectives, perDirectoryResolvedTypeReferenceDirectives,
|
||||
resolveTypeReferenceDirective, getResolvedTypeReferenceDirective,
|
||||
/*shouldRetryResolution*/ resolution => resolution.resolvedTypeReferenceDirective === undefined,
|
||||
/*reusedNames*/ undefined, /*logChanges*/ false
|
||||
);
|
||||
}
|
||||
|
||||
function resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined): ResolvedModuleFull[] {
|
||||
function resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference?: ResolvedProjectReference): (ResolvedModuleFull | undefined)[] {
|
||||
return resolveNamesWithLocalCache<CachedResolvedModuleWithFailedLookupLocations, ResolvedModuleFull>(
|
||||
moduleNames, containingFile,
|
||||
moduleNames, containingFile, redirectedReference,
|
||||
resolvedModuleNames, perDirectoryResolvedModuleNames,
|
||||
resolveModuleName, getResolvedModule,
|
||||
/*shouldRetryResolution*/ resolution => !resolution.resolvedModule || !resolutionExtensionIsTSOrJson(resolution.resolvedModule.extension),
|
||||
reusedNames, logChangesWhenResolvingModule
|
||||
);
|
||||
}
|
||||
@@ -389,16 +407,10 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
|
||||
function filterFSRootDirectoriesToWatch(watchPath: DirectoryOfFailedLookupWatch, dirPath: Path): DirectoryOfFailedLookupWatch {
|
||||
if (!canWatchDirectory(dirPath)) {
|
||||
watchPath.ignore = true;
|
||||
}
|
||||
return watchPath;
|
||||
}
|
||||
|
||||
function getDirectoryToWatchFailedLookupLocation(failedLookupLocation: string, failedLookupLocationPath: Path): DirectoryOfFailedLookupWatch {
|
||||
function getDirectoryToWatchFailedLookupLocation(failedLookupLocation: string, failedLookupLocationPath: Path): DirectoryOfFailedLookupWatch | undefined {
|
||||
if (isInDirectoryPath(rootPath, failedLookupLocationPath)) {
|
||||
failedLookupLocation = isRootedDiskPath(failedLookupLocation) ? failedLookupLocation : getNormalizedAbsolutePath(failedLookupLocation, getCurrentDirectory());
|
||||
// Ensure failed look up is normalized path
|
||||
failedLookupLocation = isRootedDiskPath(failedLookupLocation) ? normalizePath(failedLookupLocation) : getNormalizedAbsolutePath(failedLookupLocation, getCurrentDirectory());
|
||||
Debug.assert(failedLookupLocation.length === failedLookupLocationPath.length, `FailedLookup: ${failedLookupLocation} failedLookupLocationPath: ${failedLookupLocationPath}`); // tslint:disable-line
|
||||
const subDirectoryInRoot = failedLookupLocationPath.indexOf(directorySeparator, rootPath.length + 1);
|
||||
if (subDirectoryInRoot !== -1) {
|
||||
@@ -417,16 +429,16 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
function getDirectoryToWatchFromFailedLookupLocationDirectory(dir: string, dirPath: Path) {
|
||||
function getDirectoryToWatchFromFailedLookupLocationDirectory(dir: string, dirPath: Path): DirectoryOfFailedLookupWatch | undefined {
|
||||
// If directory path contains node module, get the most parent node_modules directory for watching
|
||||
while (stringContains(dirPath, "/node_modules/")) {
|
||||
while (pathContainsNodeModules(dirPath)) {
|
||||
dir = getDirectoryPath(dir);
|
||||
dirPath = getDirectoryPath(dirPath);
|
||||
}
|
||||
|
||||
// If the directory is node_modules use it to watch, always watch it recursively
|
||||
if (isNodeModulesDirectory(dirPath)) {
|
||||
return filterFSRootDirectoriesToWatch({ dir, dirPath }, getDirectoryPath(dirPath));
|
||||
return canWatchDirectory(getDirectoryPath(dirPath)) ? { dir, dirPath } : undefined;
|
||||
}
|
||||
|
||||
let nonRecursive = true;
|
||||
@@ -446,7 +458,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
return filterFSRootDirectoriesToWatch({ dir: subDirectory || dir, dirPath: subDirectoryPath || dirPath, nonRecursive }, dirPath);
|
||||
return canWatchDirectory(dirPath) ? { dir: subDirectory || dir, dirPath: subDirectoryPath || dirPath, nonRecursive } : undefined;
|
||||
}
|
||||
|
||||
function isPathWithDefaultFailedLookupExtension(path: Path) {
|
||||
@@ -478,8 +490,9 @@ namespace ts {
|
||||
let setAtRoot = false;
|
||||
for (const failedLookupLocation of failedLookupLocations) {
|
||||
const failedLookupLocationPath = resolutionHost.toPath(failedLookupLocation);
|
||||
const { dir, dirPath, nonRecursive, ignore } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
|
||||
if (!ignore) {
|
||||
const toWatch = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
|
||||
if (toWatch) {
|
||||
const { dir, dirPath, nonRecursive } = toWatch;
|
||||
// If the failed lookup location path is not one of the supported extensions,
|
||||
// store it in the custom path
|
||||
if (!isPathWithDefaultFailedLookupExtension(failedLookupLocationPath)) {
|
||||
@@ -538,8 +551,9 @@ namespace ts {
|
||||
let removeAtRoot = false;
|
||||
for (const failedLookupLocation of failedLookupLocations) {
|
||||
const failedLookupLocationPath = resolutionHost.toPath(failedLookupLocation);
|
||||
const { dirPath, ignore } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
|
||||
if (!ignore) {
|
||||
const toWatch = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
|
||||
if (toWatch) {
|
||||
const { dirPath } = toWatch;
|
||||
const refCount = customFailedLookupPaths.get(failedLookupLocationPath);
|
||||
if (refCount) {
|
||||
if (refCount === 1) {
|
||||
@@ -593,6 +607,20 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function removeResolutionsFromProjectReferenceRedirects(filePath: Path) {
|
||||
if (!fileExtensionIs(filePath, Extension.Json)) { return; }
|
||||
|
||||
const program = resolutionHost.getCurrentProgram();
|
||||
if (!program) { return; }
|
||||
|
||||
// If this file is input file for the referenced project, get it
|
||||
const resolvedProjectReference = program.getResolvedProjectReferenceByPath(filePath);
|
||||
if (!resolvedProjectReference) { return; }
|
||||
|
||||
// filePath is for the projectReference and the containing file is from this project reference, invalidate the resolution
|
||||
resolvedProjectReference.commandLine.fileNames.forEach(f => removeResolutionsOfFile(resolutionHost.toPath(f)));
|
||||
}
|
||||
|
||||
function removeResolutionsOfFile(filePath: Path) {
|
||||
removeResolutionsOfFileFromCache(resolvedModuleNames, filePath);
|
||||
removeResolutionsOfFileFromCache(resolvedTypeReferenceDirectives, filePath);
|
||||
@@ -654,7 +682,7 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
function setFilesWithInvalidatedNonRelativeUnresolvedImports(filesMap: Map<ReadonlyArray<string>>) {
|
||||
function setFilesWithInvalidatedNonRelativeUnresolvedImports(filesMap: ReadonlyMap<ReadonlyArray<string>>) {
|
||||
Debug.assert(filesWithInvalidatedNonRelativeUnresolvedImports === filesMap || filesWithInvalidatedNonRelativeUnresolvedImports === undefined);
|
||||
filesWithInvalidatedNonRelativeUnresolvedImports = filesMap;
|
||||
}
|
||||
@@ -667,6 +695,9 @@ namespace ts {
|
||||
isChangedFailedLookupLocation = location => isInDirectoryPath(fileOrDirectoryPath, resolutionHost.toPath(location));
|
||||
}
|
||||
else {
|
||||
// If something to do with folder/file starting with "." in node_modules folder, skip it
|
||||
if (isPathInNodeModulesStartingWithDot(fileOrDirectoryPath)) return false;
|
||||
|
||||
// Some file or directory in the watching directory is created
|
||||
// Return early if it does not have any of the watching extension or not the custom failed lookup path
|
||||
const dirOfFileOrDirectory = getDirectoryPath(fileOrDirectoryPath);
|
||||
@@ -711,8 +742,8 @@ namespace ts {
|
||||
if (isInDirectoryPath(rootPath, typeRootPath)) {
|
||||
return rootPath;
|
||||
}
|
||||
const { dirPath, ignore } = getDirectoryToWatchFromFailedLookupLocationDirectory(typeRoot, typeRootPath);
|
||||
return !ignore && directoryWatchesOfFailedLookups.has(dirPath) ? dirPath : undefined;
|
||||
const toWatch = getDirectoryToWatchFromFailedLookupLocationDirectory(typeRoot, typeRootPath);
|
||||
return toWatch && directoryWatchesOfFailedLookups.has(toWatch.dirPath) ? toWatch.dirPath : undefined;
|
||||
}
|
||||
|
||||
function createTypeRootsWatch(typeRootPath: Path, typeRoot: string): FileWatcher {
|
||||
|
||||
+247
-142
@@ -42,6 +42,8 @@ namespace ts {
|
||||
setScriptTarget(scriptTarget: ScriptTarget): void;
|
||||
setLanguageVariant(variant: LanguageVariant): void;
|
||||
setTextPos(textPos: number): void;
|
||||
/* @internal */
|
||||
setInJSDocType(inType: boolean): void;
|
||||
// Invokes the provided callback then unconditionally restores the scanner to the state it
|
||||
// was in immediately prior to invoking the callback. The result of invoking the callback
|
||||
// is returned from this function.
|
||||
@@ -58,81 +60,88 @@ namespace ts {
|
||||
tryScan<T>(callback: () => T): T;
|
||||
}
|
||||
|
||||
const textToToken = createMapFromTemplate({
|
||||
"abstract": SyntaxKind.AbstractKeyword,
|
||||
"any": SyntaxKind.AnyKeyword,
|
||||
"as": SyntaxKind.AsKeyword,
|
||||
"boolean": SyntaxKind.BooleanKeyword,
|
||||
"break": SyntaxKind.BreakKeyword,
|
||||
"case": SyntaxKind.CaseKeyword,
|
||||
"catch": SyntaxKind.CatchKeyword,
|
||||
"class": SyntaxKind.ClassKeyword,
|
||||
"continue": SyntaxKind.ContinueKeyword,
|
||||
"const": SyntaxKind.ConstKeyword,
|
||||
"constructor": SyntaxKind.ConstructorKeyword,
|
||||
"debugger": SyntaxKind.DebuggerKeyword,
|
||||
"declare": SyntaxKind.DeclareKeyword,
|
||||
"default": SyntaxKind.DefaultKeyword,
|
||||
"delete": SyntaxKind.DeleteKeyword,
|
||||
"do": SyntaxKind.DoKeyword,
|
||||
"else": SyntaxKind.ElseKeyword,
|
||||
"enum": SyntaxKind.EnumKeyword,
|
||||
"export": SyntaxKind.ExportKeyword,
|
||||
"extends": SyntaxKind.ExtendsKeyword,
|
||||
"false": SyntaxKind.FalseKeyword,
|
||||
"finally": SyntaxKind.FinallyKeyword,
|
||||
"for": SyntaxKind.ForKeyword,
|
||||
"from": SyntaxKind.FromKeyword,
|
||||
"function": SyntaxKind.FunctionKeyword,
|
||||
"get": SyntaxKind.GetKeyword,
|
||||
"if": SyntaxKind.IfKeyword,
|
||||
"implements": SyntaxKind.ImplementsKeyword,
|
||||
"import": SyntaxKind.ImportKeyword,
|
||||
"in": SyntaxKind.InKeyword,
|
||||
"infer": SyntaxKind.InferKeyword,
|
||||
"instanceof": SyntaxKind.InstanceOfKeyword,
|
||||
"interface": SyntaxKind.InterfaceKeyword,
|
||||
"is": SyntaxKind.IsKeyword,
|
||||
"keyof": SyntaxKind.KeyOfKeyword,
|
||||
"let": SyntaxKind.LetKeyword,
|
||||
"module": SyntaxKind.ModuleKeyword,
|
||||
"namespace": SyntaxKind.NamespaceKeyword,
|
||||
"never": SyntaxKind.NeverKeyword,
|
||||
"new": SyntaxKind.NewKeyword,
|
||||
"null": SyntaxKind.NullKeyword,
|
||||
"number": SyntaxKind.NumberKeyword,
|
||||
"object": SyntaxKind.ObjectKeyword,
|
||||
"package": SyntaxKind.PackageKeyword,
|
||||
"private": SyntaxKind.PrivateKeyword,
|
||||
"protected": SyntaxKind.ProtectedKeyword,
|
||||
"public": SyntaxKind.PublicKeyword,
|
||||
"readonly": SyntaxKind.ReadonlyKeyword,
|
||||
"require": SyntaxKind.RequireKeyword,
|
||||
"global": SyntaxKind.GlobalKeyword,
|
||||
"return": SyntaxKind.ReturnKeyword,
|
||||
"set": SyntaxKind.SetKeyword,
|
||||
"static": SyntaxKind.StaticKeyword,
|
||||
"string": SyntaxKind.StringKeyword,
|
||||
"super": SyntaxKind.SuperKeyword,
|
||||
"switch": SyntaxKind.SwitchKeyword,
|
||||
"symbol": SyntaxKind.SymbolKeyword,
|
||||
"this": SyntaxKind.ThisKeyword,
|
||||
"throw": SyntaxKind.ThrowKeyword,
|
||||
"true": SyntaxKind.TrueKeyword,
|
||||
"try": SyntaxKind.TryKeyword,
|
||||
"type": SyntaxKind.TypeKeyword,
|
||||
"typeof": SyntaxKind.TypeOfKeyword,
|
||||
"undefined": SyntaxKind.UndefinedKeyword,
|
||||
"unique": SyntaxKind.UniqueKeyword,
|
||||
"unknown": SyntaxKind.UnknownKeyword,
|
||||
"var": SyntaxKind.VarKeyword,
|
||||
"void": SyntaxKind.VoidKeyword,
|
||||
"while": SyntaxKind.WhileKeyword,
|
||||
"with": SyntaxKind.WithKeyword,
|
||||
"yield": SyntaxKind.YieldKeyword,
|
||||
"async": SyntaxKind.AsyncKeyword,
|
||||
"await": SyntaxKind.AwaitKeyword,
|
||||
"of": SyntaxKind.OfKeyword,
|
||||
const textToKeywordObj: MapLike<KeywordSyntaxKind> = {
|
||||
abstract: SyntaxKind.AbstractKeyword,
|
||||
any: SyntaxKind.AnyKeyword,
|
||||
as: SyntaxKind.AsKeyword,
|
||||
bigint: SyntaxKind.BigIntKeyword,
|
||||
boolean: SyntaxKind.BooleanKeyword,
|
||||
break: SyntaxKind.BreakKeyword,
|
||||
case: SyntaxKind.CaseKeyword,
|
||||
catch: SyntaxKind.CatchKeyword,
|
||||
class: SyntaxKind.ClassKeyword,
|
||||
continue: SyntaxKind.ContinueKeyword,
|
||||
const: SyntaxKind.ConstKeyword,
|
||||
["" + "constructor"]: SyntaxKind.ConstructorKeyword,
|
||||
debugger: SyntaxKind.DebuggerKeyword,
|
||||
declare: SyntaxKind.DeclareKeyword,
|
||||
default: SyntaxKind.DefaultKeyword,
|
||||
delete: SyntaxKind.DeleteKeyword,
|
||||
do: SyntaxKind.DoKeyword,
|
||||
else: SyntaxKind.ElseKeyword,
|
||||
enum: SyntaxKind.EnumKeyword,
|
||||
export: SyntaxKind.ExportKeyword,
|
||||
extends: SyntaxKind.ExtendsKeyword,
|
||||
false: SyntaxKind.FalseKeyword,
|
||||
finally: SyntaxKind.FinallyKeyword,
|
||||
for: SyntaxKind.ForKeyword,
|
||||
from: SyntaxKind.FromKeyword,
|
||||
function: SyntaxKind.FunctionKeyword,
|
||||
get: SyntaxKind.GetKeyword,
|
||||
if: SyntaxKind.IfKeyword,
|
||||
implements: SyntaxKind.ImplementsKeyword,
|
||||
import: SyntaxKind.ImportKeyword,
|
||||
in: SyntaxKind.InKeyword,
|
||||
infer: SyntaxKind.InferKeyword,
|
||||
instanceof: SyntaxKind.InstanceOfKeyword,
|
||||
interface: SyntaxKind.InterfaceKeyword,
|
||||
is: SyntaxKind.IsKeyword,
|
||||
keyof: SyntaxKind.KeyOfKeyword,
|
||||
let: SyntaxKind.LetKeyword,
|
||||
module: SyntaxKind.ModuleKeyword,
|
||||
namespace: SyntaxKind.NamespaceKeyword,
|
||||
never: SyntaxKind.NeverKeyword,
|
||||
new: SyntaxKind.NewKeyword,
|
||||
null: SyntaxKind.NullKeyword,
|
||||
number: SyntaxKind.NumberKeyword,
|
||||
object: SyntaxKind.ObjectKeyword,
|
||||
package: SyntaxKind.PackageKeyword,
|
||||
private: SyntaxKind.PrivateKeyword,
|
||||
protected: SyntaxKind.ProtectedKeyword,
|
||||
public: SyntaxKind.PublicKeyword,
|
||||
readonly: SyntaxKind.ReadonlyKeyword,
|
||||
require: SyntaxKind.RequireKeyword,
|
||||
global: SyntaxKind.GlobalKeyword,
|
||||
return: SyntaxKind.ReturnKeyword,
|
||||
set: SyntaxKind.SetKeyword,
|
||||
static: SyntaxKind.StaticKeyword,
|
||||
string: SyntaxKind.StringKeyword,
|
||||
super: SyntaxKind.SuperKeyword,
|
||||
switch: SyntaxKind.SwitchKeyword,
|
||||
symbol: SyntaxKind.SymbolKeyword,
|
||||
this: SyntaxKind.ThisKeyword,
|
||||
throw: SyntaxKind.ThrowKeyword,
|
||||
true: SyntaxKind.TrueKeyword,
|
||||
try: SyntaxKind.TryKeyword,
|
||||
type: SyntaxKind.TypeKeyword,
|
||||
typeof: SyntaxKind.TypeOfKeyword,
|
||||
undefined: SyntaxKind.UndefinedKeyword,
|
||||
unique: SyntaxKind.UniqueKeyword,
|
||||
unknown: SyntaxKind.UnknownKeyword,
|
||||
var: SyntaxKind.VarKeyword,
|
||||
void: SyntaxKind.VoidKeyword,
|
||||
while: SyntaxKind.WhileKeyword,
|
||||
with: SyntaxKind.WithKeyword,
|
||||
yield: SyntaxKind.YieldKeyword,
|
||||
async: SyntaxKind.AsyncKeyword,
|
||||
await: SyntaxKind.AwaitKeyword,
|
||||
of: SyntaxKind.OfKeyword,
|
||||
};
|
||||
|
||||
const textToKeyword = createMapFromTemplate(textToKeywordObj);
|
||||
|
||||
const textToToken = createMapFromTemplate<SyntaxKind>({
|
||||
...textToKeywordObj,
|
||||
"{": SyntaxKind.OpenBraceToken,
|
||||
"}": SyntaxKind.CloseBraceToken,
|
||||
"(": SyntaxKind.OpenParenToken,
|
||||
@@ -328,17 +337,35 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: number, character: number): number {
|
||||
return computePositionOfLineAndCharacter(getLineStarts(sourceFile), line, character, sourceFile.text);
|
||||
export function getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: number, character: number): number;
|
||||
/* @internal */
|
||||
// tslint:disable-next-line:unified-signatures
|
||||
export function getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: number, character: number, allowEdits?: true): number;
|
||||
export function getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: number, character: number, allowEdits?: true): number {
|
||||
return sourceFile.getPositionOfLineAndCharacter ?
|
||||
sourceFile.getPositionOfLineAndCharacter(line, character, allowEdits) :
|
||||
computePositionOfLineAndCharacter(getLineStarts(sourceFile), line, character, sourceFile.text, allowEdits);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function computePositionOfLineAndCharacter(lineStarts: ReadonlyArray<number>, line: number, character: number, debugText?: string): number {
|
||||
export function computePositionOfLineAndCharacter(lineStarts: ReadonlyArray<number>, line: number, character: number, debugText?: string, allowEdits?: true): number {
|
||||
if (line < 0 || line >= lineStarts.length) {
|
||||
Debug.fail(`Bad line number. Line: ${line}, lineStarts.length: ${lineStarts.length} , line map is correct? ${debugText !== undefined ? arraysEqual(lineStarts, computeLineStarts(debugText)) : "unknown"}`);
|
||||
if (allowEdits) {
|
||||
// Clamp line to nearest allowable value
|
||||
line = line < 0 ? 0 : line >= lineStarts.length ? lineStarts.length - 1 : line;
|
||||
}
|
||||
else {
|
||||
Debug.fail(`Bad line number. Line: ${line}, lineStarts.length: ${lineStarts.length} , line map is correct? ${debugText !== undefined ? arraysEqual(lineStarts, computeLineStarts(debugText)) : "unknown"}`);
|
||||
}
|
||||
}
|
||||
|
||||
const res = lineStarts[line] + character;
|
||||
if (allowEdits) {
|
||||
// Clamp to nearest allowable values to allow the underlying to be edited without crashing (accuracy is lost, instead)
|
||||
// TODO: Somehow track edits between file as it was during the creation of sourcemap we have and the current file and
|
||||
// apply them to the computed position to improve accuracy
|
||||
return res > lineStarts[line + 1] ? lineStarts[line + 1] : typeof debugText === "string" && res > debugText.length ? debugText.length : res;
|
||||
}
|
||||
if (line < lineStarts.length - 1) {
|
||||
Debug.assert(res < lineStarts[line + 1]);
|
||||
}
|
||||
@@ -824,6 +851,8 @@ namespace ts {
|
||||
let tokenValue!: string;
|
||||
let tokenFlags: TokenFlags;
|
||||
|
||||
let inJSDocType = 0;
|
||||
|
||||
setText(text, start, length);
|
||||
|
||||
return {
|
||||
@@ -854,6 +883,7 @@ namespace ts {
|
||||
setLanguageVariant,
|
||||
setOnError,
|
||||
setTextPos,
|
||||
setInJSDocType,
|
||||
tryScan,
|
||||
lookAhead,
|
||||
scanRange,
|
||||
@@ -908,7 +938,7 @@ namespace ts {
|
||||
return result + text.substring(start, pos);
|
||||
}
|
||||
|
||||
function scanNumber(): string {
|
||||
function scanNumber(): {type: SyntaxKind, value: string} {
|
||||
const start = pos;
|
||||
const mainFragment = scanNumberFragment();
|
||||
let decimalFragment: string | undefined;
|
||||
@@ -932,18 +962,54 @@ namespace ts {
|
||||
end = pos;
|
||||
}
|
||||
}
|
||||
let result: string;
|
||||
if (tokenFlags & TokenFlags.ContainsSeparator) {
|
||||
let result = mainFragment;
|
||||
result = mainFragment;
|
||||
if (decimalFragment) {
|
||||
result += "." + decimalFragment;
|
||||
}
|
||||
if (scientificFragment) {
|
||||
result += scientificFragment;
|
||||
}
|
||||
return "" + +result;
|
||||
}
|
||||
else {
|
||||
return "" + +(text.substring(start, end)); // No need to use all the fragments; no _ removal needed
|
||||
result = text.substring(start, end); // No need to use all the fragments; no _ removal needed
|
||||
}
|
||||
|
||||
if (decimalFragment !== undefined || tokenFlags & TokenFlags.Scientific) {
|
||||
checkForIdentifierStartAfterNumericLiteral(start, decimalFragment === undefined && !!(tokenFlags & TokenFlags.Scientific));
|
||||
return {
|
||||
type: SyntaxKind.NumericLiteral,
|
||||
value: "" + +result // if value is not an integer, it can be safely coerced to a number
|
||||
};
|
||||
}
|
||||
else {
|
||||
tokenValue = result;
|
||||
const type = checkBigIntSuffix(); // if value is an integer, check whether it is a bigint
|
||||
checkForIdentifierStartAfterNumericLiteral(start);
|
||||
return { type, value: tokenValue };
|
||||
}
|
||||
}
|
||||
|
||||
function checkForIdentifierStartAfterNumericLiteral(numericStart: number, isScientific?: boolean) {
|
||||
if (!isIdentifierStart(text.charCodeAt(pos), languageVersion)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const identifierStart = pos;
|
||||
const { length } = scanIdentifierParts();
|
||||
|
||||
if (length === 1 && text[identifierStart] === "n") {
|
||||
if (isScientific) {
|
||||
error(Diagnostics.A_bigint_literal_cannot_use_exponential_notation, numericStart, identifierStart - numericStart + 1);
|
||||
}
|
||||
else {
|
||||
error(Diagnostics.A_bigint_literal_must_be_an_integer, numericStart, identifierStart - numericStart + 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
error(Diagnostics.An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal, identifierStart, length);
|
||||
pos = identifierStart;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -960,24 +1026,24 @@ namespace ts {
|
||||
* returning -1 if the given number is unavailable.
|
||||
*/
|
||||
function scanExactNumberOfHexDigits(count: number, canHaveSeparators: boolean): number {
|
||||
return scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ false, canHaveSeparators);
|
||||
const valueString = scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ false, canHaveSeparators);
|
||||
return valueString ? parseInt(valueString, 16) : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans as many hexadecimal digits as are available in the text,
|
||||
* returning -1 if the given number of digits was unavailable.
|
||||
* returning "" if the given number of digits was unavailable.
|
||||
*/
|
||||
function scanMinimumNumberOfHexDigits(count: number, canHaveSeparators: boolean): number {
|
||||
function scanMinimumNumberOfHexDigits(count: number, canHaveSeparators: boolean): string {
|
||||
return scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ true, canHaveSeparators);
|
||||
}
|
||||
|
||||
function scanHexDigits(minCount: number, scanAsManyAsPossible: boolean, canHaveSeparators: boolean): number {
|
||||
let digits = 0;
|
||||
let value = 0;
|
||||
function scanHexDigits(minCount: number, scanAsManyAsPossible: boolean, canHaveSeparators: boolean): string {
|
||||
let valueChars: number[] = [];
|
||||
let allowSeparator = false;
|
||||
let isPreviousTokenSeparator = false;
|
||||
while (digits < minCount || scanAsManyAsPossible) {
|
||||
const ch = text.charCodeAt(pos);
|
||||
while (valueChars.length < minCount || scanAsManyAsPossible) {
|
||||
let ch = text.charCodeAt(pos);
|
||||
if (canHaveSeparators && ch === CharacterCodes._) {
|
||||
tokenFlags |= TokenFlags.ContainsSeparator;
|
||||
if (allowSeparator) {
|
||||
@@ -994,29 +1060,25 @@ namespace ts {
|
||||
continue;
|
||||
}
|
||||
allowSeparator = canHaveSeparators;
|
||||
if (ch >= CharacterCodes._0 && ch <= CharacterCodes._9) {
|
||||
value = value * 16 + ch - CharacterCodes._0;
|
||||
if (ch >= CharacterCodes.A && ch <= CharacterCodes.F) {
|
||||
ch += CharacterCodes.a - CharacterCodes.A; // standardize hex literals to lowercase
|
||||
}
|
||||
else if (ch >= CharacterCodes.A && ch <= CharacterCodes.F) {
|
||||
value = value * 16 + ch - CharacterCodes.A + 10;
|
||||
}
|
||||
else if (ch >= CharacterCodes.a && ch <= CharacterCodes.f) {
|
||||
value = value * 16 + ch - CharacterCodes.a + 10;
|
||||
}
|
||||
else {
|
||||
else if (!((ch >= CharacterCodes._0 && ch <= CharacterCodes._9) ||
|
||||
(ch >= CharacterCodes.a && ch <= CharacterCodes.f)
|
||||
)) {
|
||||
break;
|
||||
}
|
||||
valueChars.push(ch);
|
||||
pos++;
|
||||
digits++;
|
||||
isPreviousTokenSeparator = false;
|
||||
}
|
||||
if (digits < minCount) {
|
||||
value = -1;
|
||||
if (valueChars.length < minCount) {
|
||||
valueChars = [];
|
||||
}
|
||||
if (text.charCodeAt(pos - 1) === CharacterCodes._) {
|
||||
error(Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1);
|
||||
}
|
||||
return value;
|
||||
return String.fromCharCode(...valueChars);
|
||||
}
|
||||
|
||||
function scanString(jsxAttributeString = false): string {
|
||||
@@ -1196,7 +1258,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function scanExtendedUnicodeEscape(): string {
|
||||
const escapedValue = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ false);
|
||||
const escapedValueString = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ false);
|
||||
const escapedValue = escapedValueString ? parseInt(escapedValueString, 16) : -1;
|
||||
let isInvalidExtendedEscape = false;
|
||||
|
||||
// Validate the value of the digit
|
||||
@@ -1283,28 +1346,25 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function getIdentifierToken(): SyntaxKind {
|
||||
function getIdentifierToken(): SyntaxKind.Identifier | KeywordSyntaxKind {
|
||||
// Reserved words are between 2 and 11 characters long and start with a lowercase letter
|
||||
const len = tokenValue.length;
|
||||
if (len >= 2 && len <= 11) {
|
||||
const ch = tokenValue.charCodeAt(0);
|
||||
if (ch >= CharacterCodes.a && ch <= CharacterCodes.z) {
|
||||
token = textToToken.get(tokenValue)!;
|
||||
if (token !== undefined) {
|
||||
return token;
|
||||
const keyword = textToKeyword.get(tokenValue);
|
||||
if (keyword !== undefined) {
|
||||
return token = keyword;
|
||||
}
|
||||
}
|
||||
}
|
||||
return token = SyntaxKind.Identifier;
|
||||
}
|
||||
|
||||
function scanBinaryOrOctalDigits(base: number): number {
|
||||
Debug.assert(base === 2 || base === 8, "Expected either base 2 or base 8");
|
||||
|
||||
let value = 0;
|
||||
function scanBinaryOrOctalDigits(base: 2 | 8): string {
|
||||
let value = "";
|
||||
// For counting number of digits; Valid binaryIntegerLiteral must have at least one binary digit following B or b.
|
||||
// Similarly valid octalIntegerLiteral must have at least one octal digit following o or O.
|
||||
let numberOfDigits = 0;
|
||||
let separatorAllowed = false;
|
||||
let isPreviousTokenSeparator = false;
|
||||
while (true) {
|
||||
@@ -1326,30 +1386,46 @@ namespace ts {
|
||||
continue;
|
||||
}
|
||||
separatorAllowed = true;
|
||||
const valueOfCh = ch - CharacterCodes._0;
|
||||
if (!isDigit(ch) || valueOfCh >= base) {
|
||||
if (!isDigit(ch) || ch - CharacterCodes._0 >= base) {
|
||||
break;
|
||||
}
|
||||
value = value * base + valueOfCh;
|
||||
value += text[pos];
|
||||
pos++;
|
||||
numberOfDigits++;
|
||||
isPreviousTokenSeparator = false;
|
||||
}
|
||||
// Invalid binaryIntegerLiteral or octalIntegerLiteral
|
||||
if (numberOfDigits === 0) {
|
||||
return -1;
|
||||
}
|
||||
if (text.charCodeAt(pos - 1) === CharacterCodes._) {
|
||||
// Literal ends with underscore - not allowed
|
||||
error(Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1);
|
||||
return value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function checkBigIntSuffix(): SyntaxKind {
|
||||
if (text.charCodeAt(pos) === CharacterCodes.n) {
|
||||
tokenValue += "n";
|
||||
// Use base 10 instead of base 2 or base 8 for shorter literals
|
||||
if (tokenFlags & TokenFlags.BinaryOrOctalSpecifier) {
|
||||
tokenValue = parsePseudoBigInt(tokenValue) + "n";
|
||||
}
|
||||
pos++;
|
||||
return SyntaxKind.BigIntLiteral;
|
||||
}
|
||||
else { // not a bigint, so can convert to number in simplified form
|
||||
// Number() may not support 0b or 0o, so use parseInt() instead
|
||||
const numericValue = tokenFlags & TokenFlags.BinarySpecifier
|
||||
? parseInt(tokenValue.slice(2), 2) // skip "0b"
|
||||
: tokenFlags & TokenFlags.OctalSpecifier
|
||||
? parseInt(tokenValue.slice(2), 8) // skip "0o"
|
||||
: +tokenValue;
|
||||
tokenValue = "" + numericValue;
|
||||
return SyntaxKind.NumericLiteral;
|
||||
}
|
||||
}
|
||||
|
||||
function scan(): SyntaxKind {
|
||||
startPos = pos;
|
||||
tokenFlags = 0;
|
||||
let asteriskSeen = false;
|
||||
while (true) {
|
||||
tokenPos = pos;
|
||||
if (pos >= end) {
|
||||
@@ -1390,6 +1466,24 @@ namespace ts {
|
||||
case CharacterCodes.verticalTab:
|
||||
case CharacterCodes.formFeed:
|
||||
case CharacterCodes.space:
|
||||
case CharacterCodes.nonBreakingSpace:
|
||||
case CharacterCodes.ogham:
|
||||
case CharacterCodes.enQuad:
|
||||
case CharacterCodes.emQuad:
|
||||
case CharacterCodes.enSpace:
|
||||
case CharacterCodes.emSpace:
|
||||
case CharacterCodes.threePerEmSpace:
|
||||
case CharacterCodes.fourPerEmSpace:
|
||||
case CharacterCodes.sixPerEmSpace:
|
||||
case CharacterCodes.figureSpace:
|
||||
case CharacterCodes.punctuationSpace:
|
||||
case CharacterCodes.thinSpace:
|
||||
case CharacterCodes.hairSpace:
|
||||
case CharacterCodes.zeroWidthSpace:
|
||||
case CharacterCodes.narrowNoBreakSpace:
|
||||
case CharacterCodes.mathematicalSpace:
|
||||
case CharacterCodes.ideographicSpace:
|
||||
case CharacterCodes.byteOrderMark:
|
||||
if (skipTrivia) {
|
||||
pos++;
|
||||
continue;
|
||||
@@ -1447,6 +1541,11 @@ namespace ts {
|
||||
return pos += 2, token = SyntaxKind.AsteriskAsteriskToken;
|
||||
}
|
||||
pos++;
|
||||
if (inJSDocType && !asteriskSeen && (tokenFlags & TokenFlags.PrecedingLineBreak)) {
|
||||
// decoration at the start of a JSDoc comment line
|
||||
asteriskSeen = true;
|
||||
continue;
|
||||
}
|
||||
return token = SyntaxKind.AsteriskToken;
|
||||
case CharacterCodes.plus:
|
||||
if (text.charCodeAt(pos + 1) === CharacterCodes.plus) {
|
||||
@@ -1471,7 +1570,7 @@ namespace ts {
|
||||
return token = SyntaxKind.MinusToken;
|
||||
case CharacterCodes.dot:
|
||||
if (isDigit(text.charCodeAt(pos + 1))) {
|
||||
tokenValue = scanNumber();
|
||||
tokenValue = scanNumber().value;
|
||||
return token = SyntaxKind.NumericLiteral;
|
||||
}
|
||||
if (text.charCodeAt(pos + 1) === CharacterCodes.dot && text.charCodeAt(pos + 2) === CharacterCodes.dot) {
|
||||
@@ -1547,36 +1646,36 @@ namespace ts {
|
||||
case CharacterCodes._0:
|
||||
if (pos + 2 < end && (text.charCodeAt(pos + 1) === CharacterCodes.X || text.charCodeAt(pos + 1) === CharacterCodes.x)) {
|
||||
pos += 2;
|
||||
let value = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ true);
|
||||
if (value < 0) {
|
||||
tokenValue = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ true);
|
||||
if (!tokenValue) {
|
||||
error(Diagnostics.Hexadecimal_digit_expected);
|
||||
value = 0;
|
||||
tokenValue = "0";
|
||||
}
|
||||
tokenValue = "" + value;
|
||||
tokenValue = "0x" + tokenValue;
|
||||
tokenFlags |= TokenFlags.HexSpecifier;
|
||||
return token = SyntaxKind.NumericLiteral;
|
||||
return token = checkBigIntSuffix();
|
||||
}
|
||||
else if (pos + 2 < end && (text.charCodeAt(pos + 1) === CharacterCodes.B || text.charCodeAt(pos + 1) === CharacterCodes.b)) {
|
||||
pos += 2;
|
||||
let value = scanBinaryOrOctalDigits(/* base */ 2);
|
||||
if (value < 0) {
|
||||
tokenValue = scanBinaryOrOctalDigits(/* base */ 2);
|
||||
if (!tokenValue) {
|
||||
error(Diagnostics.Binary_digit_expected);
|
||||
value = 0;
|
||||
tokenValue = "0";
|
||||
}
|
||||
tokenValue = "" + value;
|
||||
tokenValue = "0b" + tokenValue;
|
||||
tokenFlags |= TokenFlags.BinarySpecifier;
|
||||
return token = SyntaxKind.NumericLiteral;
|
||||
return token = checkBigIntSuffix();
|
||||
}
|
||||
else if (pos + 2 < end && (text.charCodeAt(pos + 1) === CharacterCodes.O || text.charCodeAt(pos + 1) === CharacterCodes.o)) {
|
||||
pos += 2;
|
||||
let value = scanBinaryOrOctalDigits(/* base */ 8);
|
||||
if (value < 0) {
|
||||
tokenValue = scanBinaryOrOctalDigits(/* base */ 8);
|
||||
if (!tokenValue) {
|
||||
error(Diagnostics.Octal_digit_expected);
|
||||
value = 0;
|
||||
tokenValue = "0";
|
||||
}
|
||||
tokenValue = "" + value;
|
||||
tokenValue = "0o" + tokenValue;
|
||||
tokenFlags |= TokenFlags.OctalSpecifier;
|
||||
return token = SyntaxKind.NumericLiteral;
|
||||
return token = checkBigIntSuffix();
|
||||
}
|
||||
// Try to parse as an octal
|
||||
if (pos + 1 < end && isOctalDigit(text.charCodeAt(pos + 1))) {
|
||||
@@ -1597,8 +1696,8 @@ namespace ts {
|
||||
case CharacterCodes._7:
|
||||
case CharacterCodes._8:
|
||||
case CharacterCodes._9:
|
||||
tokenValue = scanNumber();
|
||||
return token = SyntaxKind.NumericLiteral;
|
||||
({ type: token, value: tokenValue } = scanNumber());
|
||||
return token;
|
||||
case CharacterCodes.colon:
|
||||
pos++;
|
||||
return token = SyntaxKind.ColonToken;
|
||||
@@ -1933,6 +2032,7 @@ namespace ts {
|
||||
|
||||
function scanJSDocToken(): JsDocSyntaxKind {
|
||||
startPos = tokenPos = pos;
|
||||
tokenFlags = 0;
|
||||
if (pos >= end) {
|
||||
return token = SyntaxKind.EndOfFileToken;
|
||||
}
|
||||
@@ -1952,6 +2052,7 @@ namespace ts {
|
||||
return token = SyntaxKind.AtToken;
|
||||
case CharacterCodes.lineFeed:
|
||||
case CharacterCodes.carriageReturn:
|
||||
tokenFlags |= TokenFlags.PrecedingLineBreak;
|
||||
return token = SyntaxKind.NewLineTrivia;
|
||||
case CharacterCodes.asterisk:
|
||||
return token = SyntaxKind.AsteriskToken;
|
||||
@@ -1985,7 +2086,7 @@ namespace ts {
|
||||
pos++;
|
||||
}
|
||||
tokenValue = text.substring(tokenPos, pos);
|
||||
return token = SyntaxKind.Identifier;
|
||||
return token = getIdentifierToken();
|
||||
}
|
||||
else {
|
||||
return token = SyntaxKind.Unknown;
|
||||
@@ -2076,5 +2177,9 @@ namespace ts {
|
||||
tokenValue = undefined!;
|
||||
tokenFlags = 0;
|
||||
}
|
||||
|
||||
function setInJSDocType(inType: boolean) {
|
||||
inJSDocType += inType ? 1 : -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,391 @@
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
// https://semver.org/#spec-item-2
|
||||
// > A normal version number MUST take the form X.Y.Z where X, Y, and Z are non-negative
|
||||
// > integers, and MUST NOT contain leading zeroes. X is the major version, Y is the minor
|
||||
// > version, and Z is the patch version. Each element MUST increase numerically.
|
||||
//
|
||||
// NOTE: We differ here in that we allow X and X.Y, with missing parts having the default
|
||||
// value of `0`.
|
||||
const versionRegExp = /^(0|[1-9]\d*)(?:\.(0|[1-9]\d*)(?:\.(0|[1-9]\d*)(?:\-([a-z0-9-.]+))?(?:\+([a-z0-9-.]+))?)?)?$/i;
|
||||
|
||||
// https://semver.org/#spec-item-9
|
||||
// > A pre-release version MAY be denoted by appending a hyphen and a series of dot separated
|
||||
// > identifiers immediately following the patch version. Identifiers MUST comprise only ASCII
|
||||
// > alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. Numeric identifiers
|
||||
// > MUST NOT include leading zeroes.
|
||||
const prereleaseRegExp = /^(?:0|[1-9]\d*|[a-z-][a-z0-9-]*)(?:\.(?:0|[1-9]\d*|[a-z-][a-z0-9-]*))*$/i;
|
||||
|
||||
// https://semver.org/#spec-item-10
|
||||
// > Build metadata MAY be denoted by appending a plus sign and a series of dot separated
|
||||
// > identifiers immediately following the patch or pre-release version. Identifiers MUST
|
||||
// > comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty.
|
||||
const buildRegExp = /^[a-z0-9-]+(?:\.[a-z0-9-]+)*$/i;
|
||||
|
||||
// https://semver.org/#spec-item-9
|
||||
// > Numeric identifiers MUST NOT include leading zeroes.
|
||||
const numericIdentifierRegExp = /^(0|[1-9]\d*)$/;
|
||||
|
||||
/**
|
||||
* Describes a precise semantic version number, https://semver.org
|
||||
*/
|
||||
export class Version {
|
||||
static readonly zero = new Version(0, 0, 0);
|
||||
|
||||
readonly major: number;
|
||||
readonly minor: number;
|
||||
readonly patch: number;
|
||||
readonly prerelease: ReadonlyArray<string>;
|
||||
readonly build: ReadonlyArray<string>;
|
||||
|
||||
constructor(text: string);
|
||||
constructor(major: number, minor?: number, patch?: number, prerelease?: string, build?: string);
|
||||
constructor(major: number | string, minor = 0, patch = 0, prerelease = "", build = "") {
|
||||
if (typeof major === "string") {
|
||||
const result = Debug.assertDefined(tryParseComponents(major), "Invalid version");
|
||||
({ major, minor, patch, prerelease, build } = result);
|
||||
}
|
||||
|
||||
Debug.assert(major >= 0, "Invalid argument: major");
|
||||
Debug.assert(minor >= 0, "Invalid argument: minor");
|
||||
Debug.assert(patch >= 0, "Invalid argument: patch");
|
||||
Debug.assert(!prerelease || prereleaseRegExp.test(prerelease), "Invalid argument: prerelease");
|
||||
Debug.assert(!build || buildRegExp.test(build), "Invalid argument: build");
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
this.patch = patch;
|
||||
this.prerelease = prerelease ? prerelease.split(".") : emptyArray;
|
||||
this.build = build ? build.split(".") : emptyArray;
|
||||
}
|
||||
|
||||
static tryParse(text: string) {
|
||||
const result = tryParseComponents(text);
|
||||
if (!result) return undefined;
|
||||
|
||||
const { major, minor, patch, prerelease, build } = result;
|
||||
return new Version(major, minor, patch, prerelease, build);
|
||||
}
|
||||
|
||||
compareTo(other: Version | undefined) {
|
||||
// https://semver.org/#spec-item-11
|
||||
// > Precedence is determined by the first difference when comparing each of these
|
||||
// > identifiers from left to right as follows: Major, minor, and patch versions are
|
||||
// > always compared numerically.
|
||||
//
|
||||
// https://semver.org/#spec-item-11
|
||||
// > Precedence for two pre-release versions with the same major, minor, and patch version
|
||||
// > MUST be determined by comparing each dot separated identifier from left to right until
|
||||
// > a difference is found [...]
|
||||
//
|
||||
// https://semver.org/#spec-item-11
|
||||
// > Build metadata does not figure into precedence
|
||||
if (this === other) return Comparison.EqualTo;
|
||||
if (other === undefined) return Comparison.GreaterThan;
|
||||
return compareValues(this.major, other.major)
|
||||
|| compareValues(this.minor, other.minor)
|
||||
|| compareValues(this.patch, other.patch)
|
||||
|| comparePrerelaseIdentifiers(this.prerelease, other.prerelease);
|
||||
}
|
||||
|
||||
increment(field: "major" | "minor" | "patch") {
|
||||
switch (field) {
|
||||
case "major": return new Version(this.major + 1, 0, 0);
|
||||
case "minor": return new Version(this.major, this.minor + 1, 0);
|
||||
case "patch": return new Version(this.major, this.minor, this.patch + 1);
|
||||
default: return Debug.assertNever(field);
|
||||
}
|
||||
}
|
||||
|
||||
toString() {
|
||||
let result = `${this.major}.${this.minor}.${this.patch}`;
|
||||
if (some(this.prerelease)) result += `-${this.prerelease.join(".")}`;
|
||||
if (some(this.build)) result += `+${this.build.join(".")}`;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
function tryParseComponents(text: string) {
|
||||
const match = versionRegExp.exec(text);
|
||||
if (!match) return undefined;
|
||||
|
||||
const [, major, minor = "0", patch = "0", prerelease = "", build = ""] = match;
|
||||
if (prerelease && !prereleaseRegExp.test(prerelease)) return undefined;
|
||||
if (build && !buildRegExp.test(build)) return undefined;
|
||||
return {
|
||||
major: parseInt(major, 10),
|
||||
minor: parseInt(minor, 10),
|
||||
patch: parseInt(patch, 10),
|
||||
prerelease,
|
||||
build
|
||||
};
|
||||
}
|
||||
|
||||
function comparePrerelaseIdentifiers(left: ReadonlyArray<string>, right: ReadonlyArray<string>) {
|
||||
// https://semver.org/#spec-item-11
|
||||
// > When major, minor, and patch are equal, a pre-release version has lower precedence
|
||||
// > than a normal version.
|
||||
if (left === right) return Comparison.EqualTo;
|
||||
if (left.length === 0) return right.length === 0 ? Comparison.EqualTo : Comparison.GreaterThan;
|
||||
if (right.length === 0) return Comparison.LessThan;
|
||||
|
||||
// https://semver.org/#spec-item-11
|
||||
// > Precedence for two pre-release versions with the same major, minor, and patch version
|
||||
// > MUST be determined by comparing each dot separated identifier from left to right until
|
||||
// > a difference is found [...]
|
||||
const length = Math.min(left.length, right.length);
|
||||
for (let i = 0; i < length; i++) {
|
||||
const leftIdentifier = left[i];
|
||||
const rightIdentifier = right[i];
|
||||
if (leftIdentifier === rightIdentifier) continue;
|
||||
|
||||
const leftIsNumeric = numericIdentifierRegExp.test(leftIdentifier);
|
||||
const rightIsNumeric = numericIdentifierRegExp.test(rightIdentifier);
|
||||
if (leftIsNumeric || rightIsNumeric) {
|
||||
// https://semver.org/#spec-item-11
|
||||
// > Numeric identifiers always have lower precedence than non-numeric identifiers.
|
||||
if (leftIsNumeric !== rightIsNumeric) return leftIsNumeric ? Comparison.LessThan : Comparison.GreaterThan;
|
||||
|
||||
// https://semver.org/#spec-item-11
|
||||
// > identifiers consisting of only digits are compared numerically
|
||||
const result = compareValues(+leftIdentifier, +rightIdentifier);
|
||||
if (result) return result;
|
||||
}
|
||||
else {
|
||||
// https://semver.org/#spec-item-11
|
||||
// > identifiers with letters or hyphens are compared lexically in ASCII sort order.
|
||||
const result = compareStringsCaseSensitive(leftIdentifier, rightIdentifier);
|
||||
if (result) return result;
|
||||
}
|
||||
}
|
||||
|
||||
// https://semver.org/#spec-item-11
|
||||
// > A larger set of pre-release fields has a higher precedence than a smaller set, if all
|
||||
// > of the preceding identifiers are equal.
|
||||
return compareValues(left.length, right.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes a semantic version range, per https://github.com/npm/node-semver#ranges
|
||||
*/
|
||||
export class VersionRange {
|
||||
private _alternatives: ReadonlyArray<ReadonlyArray<Comparator>>;
|
||||
|
||||
constructor(spec: string) {
|
||||
this._alternatives = spec ? Debug.assertDefined(parseRange(spec), "Invalid range spec.") : emptyArray;
|
||||
}
|
||||
|
||||
static tryParse(text: string) {
|
||||
const sets = parseRange(text);
|
||||
if (sets) {
|
||||
const range = new VersionRange("");
|
||||
range._alternatives = sets;
|
||||
return range;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
test(version: Version | string) {
|
||||
if (typeof version === "string") version = new Version(version);
|
||||
return testDisjunction(version, this._alternatives);
|
||||
}
|
||||
|
||||
toString() {
|
||||
return formatDisjunction(this._alternatives);
|
||||
}
|
||||
}
|
||||
|
||||
interface Comparator {
|
||||
readonly operator: "<" | "<=" | ">" | ">=" | "=";
|
||||
readonly operand: Version;
|
||||
}
|
||||
|
||||
// https://github.com/npm/node-semver#range-grammar
|
||||
//
|
||||
// range-set ::= range ( logical-or range ) *
|
||||
// range ::= hyphen | simple ( ' ' simple ) * | ''
|
||||
// logical-or ::= ( ' ' ) * '||' ( ' ' ) *
|
||||
const logicalOrRegExp = /\s*\|\|\s*/g;
|
||||
const whitespaceRegExp = /\s+/g;
|
||||
|
||||
// https://github.com/npm/node-semver#range-grammar
|
||||
//
|
||||
// partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )?
|
||||
// xr ::= 'x' | 'X' | '*' | nr
|
||||
// nr ::= '0' | ['1'-'9'] ( ['0'-'9'] ) *
|
||||
// qualifier ::= ( '-' pre )? ( '+' build )?
|
||||
// pre ::= parts
|
||||
// build ::= parts
|
||||
// parts ::= part ( '.' part ) *
|
||||
// part ::= nr | [-0-9A-Za-z]+
|
||||
const partialRegExp = /^([xX*0]|[1-9]\d*)(?:\.([xX*0]|[1-9]\d*)(?:\.([xX*0]|[1-9]\d*)(?:-([a-z0-9-.]+))?(?:\+([a-z0-9-.]+))?)?)?$/i;
|
||||
|
||||
// https://github.com/npm/node-semver#range-grammar
|
||||
//
|
||||
// hyphen ::= partial ' - ' partial
|
||||
const hyphenRegExp = /^\s*([a-z0-9-+.*]+)\s+-\s+([a-z0-9-+.*]+)\s*$/i;
|
||||
|
||||
// https://github.com/npm/node-semver#range-grammar
|
||||
//
|
||||
// simple ::= primitive | partial | tilde | caret
|
||||
// primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial
|
||||
// tilde ::= '~' partial
|
||||
// caret ::= '^' partial
|
||||
const rangeRegExp = /^\s*(~|\^|<|<=|>|>=|=)?\s*([a-z0-9-+.*]+)$/i;
|
||||
|
||||
function parseRange(text: string) {
|
||||
const alternatives: Comparator[][] = [];
|
||||
for (const range of text.trim().split(logicalOrRegExp)) {
|
||||
if (!range) continue;
|
||||
const comparators: Comparator[] = [];
|
||||
const match = hyphenRegExp.exec(range);
|
||||
if (match) {
|
||||
if (!parseHyphen(match[1], match[2], comparators)) return undefined;
|
||||
}
|
||||
else {
|
||||
for (const simple of range.split(whitespaceRegExp)) {
|
||||
const match = rangeRegExp.exec(simple);
|
||||
if (!match || !parseComparator(match[1], match[2], comparators)) return undefined;
|
||||
}
|
||||
}
|
||||
alternatives.push(comparators);
|
||||
}
|
||||
return alternatives;
|
||||
}
|
||||
|
||||
function parsePartial(text: string) {
|
||||
const match = partialRegExp.exec(text);
|
||||
if (!match) return undefined;
|
||||
|
||||
const [, major, minor = "*", patch = "*", prerelease, build] = match;
|
||||
const version = new Version(
|
||||
isWildcard(major) ? 0 : parseInt(major, 10),
|
||||
isWildcard(major) || isWildcard(minor) ? 0 : parseInt(minor, 10),
|
||||
isWildcard(major) || isWildcard(minor) || isWildcard(patch) ? 0 : parseInt(patch, 10),
|
||||
prerelease,
|
||||
build);
|
||||
|
||||
return { version, major, minor, patch };
|
||||
}
|
||||
|
||||
function parseHyphen(left: string, right: string, comparators: Comparator[]) {
|
||||
const leftResult = parsePartial(left);
|
||||
if (!leftResult) return false;
|
||||
|
||||
const rightResult = parsePartial(right);
|
||||
if (!rightResult) return false;
|
||||
|
||||
if (!isWildcard(leftResult.major)) {
|
||||
comparators.push(createComparator(">=", leftResult.version));
|
||||
}
|
||||
|
||||
if (!isWildcard(rightResult.major)) {
|
||||
comparators.push(
|
||||
isWildcard(rightResult.minor) ? createComparator("<", rightResult.version.increment("major")) :
|
||||
isWildcard(rightResult.patch) ? createComparator("<", rightResult.version.increment("minor")) :
|
||||
createComparator("<=", rightResult.version));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function parseComparator(operator: string, text: string, comparators: Comparator[]) {
|
||||
const result = parsePartial(text);
|
||||
if (!result) return false;
|
||||
|
||||
const { version, major, minor, patch } = result;
|
||||
if (!isWildcard(major)) {
|
||||
switch (operator) {
|
||||
case "~":
|
||||
comparators.push(createComparator(">=", version));
|
||||
comparators.push(createComparator("<", version.increment(
|
||||
isWildcard(minor) ? "major" :
|
||||
"minor")));
|
||||
break;
|
||||
case "^":
|
||||
comparators.push(createComparator(">=", version));
|
||||
comparators.push(createComparator("<", version.increment(
|
||||
version.major > 0 || isWildcard(minor) ? "major" :
|
||||
version.minor > 0 || isWildcard(patch) ? "minor" :
|
||||
"patch")));
|
||||
break;
|
||||
case "<":
|
||||
case ">=":
|
||||
comparators.push(createComparator(operator, version));
|
||||
break;
|
||||
case "<=":
|
||||
case ">":
|
||||
comparators.push(
|
||||
isWildcard(minor) ? createComparator(operator === "<=" ? "<" : ">=", version.increment("major")) :
|
||||
isWildcard(patch) ? createComparator(operator === "<=" ? "<" : ">=", version.increment("minor")) :
|
||||
createComparator(operator, version));
|
||||
break;
|
||||
case "=":
|
||||
case undefined:
|
||||
if (isWildcard(minor) || isWildcard(patch)) {
|
||||
comparators.push(createComparator(">=", version));
|
||||
comparators.push(createComparator("<", version.increment(isWildcard(minor) ? "major" : "minor")));
|
||||
}
|
||||
else {
|
||||
comparators.push(createComparator("=", version));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// unrecognized
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (operator === "<" || operator === ">") {
|
||||
comparators.push(createComparator("<", Version.zero));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function isWildcard(part: string) {
|
||||
return part === "*" || part === "x" || part === "X";
|
||||
}
|
||||
|
||||
function createComparator(operator: Comparator["operator"], operand: Version) {
|
||||
return { operator, operand };
|
||||
}
|
||||
|
||||
function testDisjunction(version: Version, alternatives: ReadonlyArray<ReadonlyArray<Comparator>>) {
|
||||
// an empty disjunction is treated as "*" (all versions)
|
||||
if (alternatives.length === 0) return true;
|
||||
for (const alternative of alternatives) {
|
||||
if (testAlternative(version, alternative)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function testAlternative(version: Version, comparators: ReadonlyArray<Comparator>) {
|
||||
for (const comparator of comparators) {
|
||||
if (!testComparator(version, comparator.operator, comparator.operand)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function testComparator(version: Version, operator: Comparator["operator"], operand: Version) {
|
||||
const cmp = version.compareTo(operand);
|
||||
switch (operator) {
|
||||
case "<": return cmp < 0;
|
||||
case "<=": return cmp <= 0;
|
||||
case ">": return cmp > 0;
|
||||
case ">=": return cmp >= 0;
|
||||
case "=": return cmp === 0;
|
||||
default: return Debug.assertNever(operator);
|
||||
}
|
||||
}
|
||||
|
||||
function formatDisjunction(alternatives: ReadonlyArray<ReadonlyArray<Comparator>>) {
|
||||
return map(alternatives, formatAlternative).join(" || ") || "*";
|
||||
}
|
||||
|
||||
function formatAlternative(comparators: ReadonlyArray<Comparator>) {
|
||||
return map(comparators, formatComparator).join(" ");
|
||||
}
|
||||
|
||||
function formatComparator(comparator: Comparator) {
|
||||
return `${comparator.operator}${comparator.operand}`;
|
||||
}
|
||||
}
|
||||
+652
-546
File diff suppressed because it is too large
Load Diff
@@ -1,376 +0,0 @@
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
export interface SourceFileLikeCache {
|
||||
get(path: Path): SourceFileLike | undefined;
|
||||
}
|
||||
|
||||
export function createSourceFileLikeCache(host: { readFile?: (path: string) => string | undefined, fileExists?: (path: string) => boolean }): SourceFileLikeCache {
|
||||
const cached = createMap<SourceFileLike>();
|
||||
return {
|
||||
get(path: Path) {
|
||||
if (cached.has(path)) {
|
||||
return cached.get(path);
|
||||
}
|
||||
if (!host.fileExists || !host.readFile || !host.fileExists(path)) return;
|
||||
// And failing that, check the disk
|
||||
const text = host.readFile(path)!; // TODO: GH#18217
|
||||
const file = {
|
||||
text,
|
||||
lineMap: undefined,
|
||||
getLineAndCharacterOfPosition(pos: number) {
|
||||
return computeLineAndCharacterOfPosition(getLineStarts(this), pos);
|
||||
}
|
||||
} as SourceFileLike;
|
||||
cached.set(path, file);
|
||||
return file;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
namespace ts.sourcemaps {
|
||||
export interface SourceMapData {
|
||||
version?: number;
|
||||
file?: string;
|
||||
sourceRoot?: string;
|
||||
sources: string[];
|
||||
sourcesContent?: (string | null)[];
|
||||
names?: string[];
|
||||
mappings: string;
|
||||
}
|
||||
|
||||
export interface SourceMappableLocation {
|
||||
fileName: string;
|
||||
position: number;
|
||||
}
|
||||
|
||||
export interface SourceMapper {
|
||||
getOriginalPosition(input: SourceMappableLocation): SourceMappableLocation;
|
||||
getGeneratedPosition(input: SourceMappableLocation): SourceMappableLocation;
|
||||
}
|
||||
|
||||
export const identitySourceMapper = { getOriginalPosition: identity, getGeneratedPosition: identity };
|
||||
|
||||
export interface SourceMapDecodeHost {
|
||||
readFile(path: string): string | undefined;
|
||||
fileExists(path: string): boolean;
|
||||
getCanonicalFileName(path: string): string;
|
||||
log(text: string): void;
|
||||
}
|
||||
|
||||
export function decode(host: SourceMapDecodeHost, mapPath: string, map: SourceMapData, program?: Program, fallbackCache = createSourceFileLikeCache(host)): SourceMapper {
|
||||
const currentDirectory = getDirectoryPath(mapPath);
|
||||
const sourceRoot = map.sourceRoot ? getNormalizedAbsolutePath(map.sourceRoot, currentDirectory) : currentDirectory;
|
||||
let decodedMappings: ProcessedSourceMapPosition[];
|
||||
let generatedOrderedMappings: ProcessedSourceMapPosition[];
|
||||
let sourceOrderedMappings: ProcessedSourceMapPosition[];
|
||||
|
||||
return {
|
||||
getOriginalPosition,
|
||||
getGeneratedPosition
|
||||
};
|
||||
|
||||
function getGeneratedPosition(loc: SourceMappableLocation): SourceMappableLocation {
|
||||
const maps = getSourceOrderedMappings();
|
||||
if (!length(maps)) return loc;
|
||||
let targetIndex = binarySearch(maps, { sourcePath: loc.fileName, sourcePosition: loc.position }, identity, compareProcessedPositionSourcePositions);
|
||||
if (targetIndex < 0 && maps.length > 0) {
|
||||
// if no exact match, closest is 2's compliment of result
|
||||
targetIndex = ~targetIndex;
|
||||
}
|
||||
if (!maps[targetIndex] || comparePaths(loc.fileName, maps[targetIndex].sourcePath, sourceRoot) !== 0) {
|
||||
return loc;
|
||||
}
|
||||
return { fileName: toPath(map.file!, sourceRoot, host.getCanonicalFileName), position: maps[targetIndex].emittedPosition }; // Closest pos
|
||||
}
|
||||
|
||||
function getOriginalPosition(loc: SourceMappableLocation): SourceMappableLocation {
|
||||
const maps = getGeneratedOrderedMappings();
|
||||
if (!length(maps)) return loc;
|
||||
let targetIndex = binarySearch(maps, { emittedPosition: loc.position }, identity, compareProcessedPositionEmittedPositions);
|
||||
if (targetIndex < 0 && maps.length > 0) {
|
||||
// if no exact match, closest is 2's compliment of result
|
||||
targetIndex = ~targetIndex;
|
||||
}
|
||||
return { fileName: toPath(maps[targetIndex].sourcePath, sourceRoot, host.getCanonicalFileName), position: maps[targetIndex].sourcePosition }; // Closest pos
|
||||
}
|
||||
|
||||
function getSourceFileLike(fileName: string, location: string): SourceFileLike | undefined {
|
||||
// Lookup file in program, if provided
|
||||
const path = toPath(fileName, location, host.getCanonicalFileName);
|
||||
const file = program && program.getSourceFile(path);
|
||||
if (!file) {
|
||||
// Otherwise check the cache (which may hit disk)
|
||||
return fallbackCache.get(path);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
function getPositionOfLineAndCharacterUsingName(fileName: string, directory: string, line: number, character: number) {
|
||||
const file = getSourceFileLike(fileName, directory);
|
||||
if (!file) {
|
||||
return -1;
|
||||
}
|
||||
return getPositionOfLineAndCharacter(file, line, character);
|
||||
}
|
||||
|
||||
function getDecodedMappings() {
|
||||
return decodedMappings || (decodedMappings = calculateDecodedMappings(map, processPosition, host));
|
||||
}
|
||||
|
||||
function getSourceOrderedMappings() {
|
||||
return sourceOrderedMappings || (sourceOrderedMappings = getDecodedMappings().slice().sort(compareProcessedPositionSourcePositions));
|
||||
}
|
||||
|
||||
function getGeneratedOrderedMappings() {
|
||||
return generatedOrderedMappings || (generatedOrderedMappings = getDecodedMappings().slice().sort(compareProcessedPositionEmittedPositions));
|
||||
}
|
||||
|
||||
function compareProcessedPositionSourcePositions(a: ProcessedSourceMapPosition, b: ProcessedSourceMapPosition) {
|
||||
return comparePaths(a.sourcePath, b.sourcePath, sourceRoot) ||
|
||||
compareValues(a.sourcePosition, b.sourcePosition);
|
||||
}
|
||||
|
||||
function compareProcessedPositionEmittedPositions(a: ProcessedSourceMapPosition, b: ProcessedSourceMapPosition) {
|
||||
return compareValues(a.emittedPosition, b.emittedPosition);
|
||||
}
|
||||
|
||||
function processPosition(position: RawSourceMapPosition): ProcessedSourceMapPosition {
|
||||
const sourcePath = map.sources[position.sourceIndex];
|
||||
return {
|
||||
emittedPosition: getPositionOfLineAndCharacterUsingName(map.file!, currentDirectory, position.emittedLine, position.emittedColumn),
|
||||
sourcePosition: getPositionOfLineAndCharacterUsingName(sourcePath, sourceRoot, position.sourceLine, position.sourceColumn),
|
||||
sourcePath,
|
||||
// TODO: Consider using `name` field to remap the expected identifier to scan for renames to handle another tool renaming oout output
|
||||
// name: position.nameIndex ? map.names[position.nameIndex] : undefined
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export interface MappingsDecoder extends Iterator<SourceMapSpan> {
|
||||
readonly decodingIndex: number;
|
||||
readonly error: string | undefined;
|
||||
readonly lastSpan: SourceMapSpan;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function decodeMappings(map: SourceMapData): MappingsDecoder {
|
||||
const state: DecoderState = {
|
||||
encodedText: map.mappings,
|
||||
currentNameIndex: undefined,
|
||||
sourceMapNamesLength: map.names ? map.names.length : undefined,
|
||||
currentEmittedColumn: 0,
|
||||
currentEmittedLine: 0,
|
||||
currentSourceColumn: 0,
|
||||
currentSourceLine: 0,
|
||||
currentSourceIndex: 0,
|
||||
decodingIndex: 0
|
||||
};
|
||||
function captureSpan(): SourceMapSpan {
|
||||
return {
|
||||
emittedColumn: state.currentEmittedColumn,
|
||||
emittedLine: state.currentEmittedLine,
|
||||
sourceColumn: state.currentSourceColumn,
|
||||
sourceIndex: state.currentSourceIndex,
|
||||
sourceLine: state.currentSourceLine,
|
||||
nameIndex: state.currentNameIndex
|
||||
};
|
||||
}
|
||||
return {
|
||||
get decodingIndex() { return state.decodingIndex; },
|
||||
get error() { return state.error; },
|
||||
get lastSpan() { return captureSpan(); },
|
||||
next() {
|
||||
if (hasCompletedDecoding(state) || state.error) return { done: true, value: undefined as never };
|
||||
if (!decodeSinglePosition(state)) return { done: true, value: undefined as never };
|
||||
return { done: false, value: captureSpan() };
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function calculateDecodedMappings<T>(map: SourceMapData, processPosition: (position: RawSourceMapPosition) => T, host?: { log?(s: string): void }): T[] {
|
||||
const decoder = decodeMappings(map);
|
||||
const positions = arrayFrom(decoder, processPosition);
|
||||
if (decoder.error) {
|
||||
if (host && host.log) {
|
||||
host.log(`Encountered error while decoding sourcemap: ${decoder.error}`);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
return positions;
|
||||
}
|
||||
|
||||
interface ProcessedSourceMapPosition {
|
||||
emittedPosition: number;
|
||||
sourcePosition: number;
|
||||
sourcePath: string;
|
||||
}
|
||||
|
||||
interface RawSourceMapPosition {
|
||||
emittedLine: number;
|
||||
emittedColumn: number;
|
||||
sourceLine: number;
|
||||
sourceColumn: number;
|
||||
sourceIndex: number;
|
||||
nameIndex?: number;
|
||||
}
|
||||
|
||||
interface DecoderState {
|
||||
decodingIndex: number;
|
||||
currentEmittedLine: number;
|
||||
currentEmittedColumn: number;
|
||||
currentSourceLine: number;
|
||||
currentSourceColumn: number;
|
||||
currentSourceIndex: number;
|
||||
currentNameIndex: number | undefined;
|
||||
encodedText: string;
|
||||
sourceMapNamesLength?: number;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
function hasCompletedDecoding(state: DecoderState) {
|
||||
return state.decodingIndex === state.encodedText.length;
|
||||
}
|
||||
|
||||
function decodeSinglePosition(state: DecoderState): boolean {
|
||||
while (state.decodingIndex < state.encodedText.length) {
|
||||
const char = state.encodedText.charCodeAt(state.decodingIndex);
|
||||
if (char === CharacterCodes.semicolon) {
|
||||
// New line
|
||||
state.currentEmittedLine++;
|
||||
state.currentEmittedColumn = 0;
|
||||
state.decodingIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (char === CharacterCodes.comma) {
|
||||
// Next entry is on same line - no action needed
|
||||
state.decodingIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Read the current position
|
||||
// 1. Column offset from prev read jsColumn
|
||||
state.currentEmittedColumn += base64VLQFormatDecode();
|
||||
// Incorrect emittedColumn dont support this map
|
||||
if (createErrorIfCondition(state.currentEmittedColumn < 0, "Invalid emittedColumn found")) {
|
||||
return false;
|
||||
}
|
||||
// Dont support reading mappings that dont have information about original source and its line numbers
|
||||
if (createErrorIfCondition(isSourceMappingSegmentEnd(state.encodedText, state.decodingIndex), "Unsupported Error Format: No entries after emitted column")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. Relative sourceIndex
|
||||
state.currentSourceIndex += base64VLQFormatDecode();
|
||||
// Incorrect sourceIndex dont support this map
|
||||
if (createErrorIfCondition(state.currentSourceIndex < 0, "Invalid sourceIndex found")) {
|
||||
return false;
|
||||
}
|
||||
// Dont support reading mappings that dont have information about original source position
|
||||
if (createErrorIfCondition(isSourceMappingSegmentEnd(state.encodedText, state.decodingIndex), "Unsupported Error Format: No entries after sourceIndex")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 3. Relative sourceLine 0 based
|
||||
state.currentSourceLine += base64VLQFormatDecode();
|
||||
// Incorrect sourceLine dont support this map
|
||||
if (createErrorIfCondition(state.currentSourceLine < 0, "Invalid sourceLine found")) {
|
||||
return false;
|
||||
}
|
||||
// Dont support reading mappings that dont have information about original source and its line numbers
|
||||
if (createErrorIfCondition(isSourceMappingSegmentEnd(state.encodedText, state.decodingIndex), "Unsupported Error Format: No entries after emitted Line")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 4. Relative sourceColumn 0 based
|
||||
state.currentSourceColumn += base64VLQFormatDecode();
|
||||
// Incorrect sourceColumn dont support this map
|
||||
if (createErrorIfCondition(state.currentSourceColumn < 0, "Invalid sourceLine found")) {
|
||||
return false;
|
||||
}
|
||||
// 5. Check if there is name:
|
||||
if (!isSourceMappingSegmentEnd(state.encodedText, state.decodingIndex)) {
|
||||
if (state.currentNameIndex === undefined) {
|
||||
state.currentNameIndex = 0;
|
||||
}
|
||||
state.currentNameIndex += base64VLQFormatDecode();
|
||||
// Incorrect nameIndex dont support this map
|
||||
// TODO: If we start using `name`s, issue errors when they aren't correct in the sourcemap
|
||||
// if (createErrorIfCondition(state.currentNameIndex < 0 || state.currentNameIndex >= state.sourceMapNamesLength, "Invalid name index for the source map entry")) {
|
||||
// return;
|
||||
// }
|
||||
}
|
||||
// Dont support reading mappings that dont have information about original source and its line numbers
|
||||
if (createErrorIfCondition(!isSourceMappingSegmentEnd(state.encodedText, state.decodingIndex), "Unsupported Error Format: There are more entries after " + (state.currentNameIndex === undefined ? "sourceColumn" : "nameIndex"))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Entry should be complete
|
||||
return true;
|
||||
}
|
||||
|
||||
createErrorIfCondition(/*condition*/ true, "No encoded entry found");
|
||||
return false;
|
||||
|
||||
function createErrorIfCondition(condition: boolean, errormsg: string) {
|
||||
if (state.error) {
|
||||
// An error was already reported
|
||||
return true;
|
||||
}
|
||||
|
||||
if (condition) {
|
||||
state.error = errormsg;
|
||||
}
|
||||
|
||||
return condition;
|
||||
}
|
||||
|
||||
function base64VLQFormatDecode(): number {
|
||||
let moreDigits = true;
|
||||
let shiftCount = 0;
|
||||
let value = 0;
|
||||
|
||||
for (; moreDigits; state.decodingIndex++) {
|
||||
if (createErrorIfCondition(state.decodingIndex >= state.encodedText.length, "Error in decoding base64VLQFormatDecode, past the mapping string")) {
|
||||
return undefined!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
// 6 digit number
|
||||
const currentByte = base64FormatDecode(state.encodedText.charAt(state.decodingIndex));
|
||||
|
||||
// If msb is set, we still have more bits to continue
|
||||
moreDigits = (currentByte & 32) !== 0;
|
||||
|
||||
// least significant 5 bits are the next msbs in the final value.
|
||||
value = value | ((currentByte & 31) << shiftCount);
|
||||
shiftCount += 5;
|
||||
}
|
||||
|
||||
// Least significant bit if 1 represents negative and rest of the msb is actual absolute value
|
||||
if ((value & 1) === 0) {
|
||||
// + number
|
||||
value = value >> 1;
|
||||
}
|
||||
else {
|
||||
// - number
|
||||
value = value >> 1;
|
||||
value = -value;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
function base64FormatDecode(char: string) {
|
||||
return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(char);
|
||||
}
|
||||
|
||||
function isSourceMappingSegmentEnd(encodedText: string, pos: number) {
|
||||
return (pos === encodedText.length ||
|
||||
encodedText.charCodeAt(pos) === CharacterCodes.comma ||
|
||||
encodedText.charCodeAt(pos) === CharacterCodes.semicolon);
|
||||
}
|
||||
}
|
||||
+15
-30
@@ -36,23 +36,6 @@ namespace ts {
|
||||
Low = 250
|
||||
}
|
||||
|
||||
function getPriorityValues(highPriorityValue: number): [number, number, number] {
|
||||
const mediumPriorityValue = highPriorityValue * 2;
|
||||
const lowPriorityValue = mediumPriorityValue * 4;
|
||||
return [highPriorityValue, mediumPriorityValue, lowPriorityValue];
|
||||
}
|
||||
|
||||
function pollingInterval(watchPriority: PollingInterval): number {
|
||||
return pollingIntervalsForPriority[watchPriority];
|
||||
}
|
||||
|
||||
const pollingIntervalsForPriority = getPriorityValues(250);
|
||||
|
||||
/* @internal */
|
||||
export function watchFileUsingPriorityPollingInterval(host: System, fileName: string, callback: FileWatcherCallback, watchPriority: PollingInterval): FileWatcher {
|
||||
return host.watchFile!(fileName, callback, pollingInterval(watchPriority));
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export type HostWatchFile = (fileName: string, callback: FileWatcherCallback, pollingInterval: PollingInterval | undefined) => FileWatcher;
|
||||
/* @internal */
|
||||
@@ -317,18 +300,22 @@ namespace ts {
|
||||
const newTime = modifiedTime.getTime();
|
||||
if (oldTime !== newTime) {
|
||||
watchedFile.mtime = modifiedTime;
|
||||
const eventKind = oldTime === 0
|
||||
? FileWatcherEventKind.Created
|
||||
: newTime === 0
|
||||
? FileWatcherEventKind.Deleted
|
||||
: FileWatcherEventKind.Changed;
|
||||
watchedFile.callback(watchedFile.fileName, eventKind);
|
||||
watchedFile.callback(watchedFile.fileName, getFileWatcherEventKind(oldTime, newTime));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function getFileWatcherEventKind(oldTime: number, newTime: number) {
|
||||
return oldTime === 0
|
||||
? FileWatcherEventKind.Created
|
||||
: newTime === 0
|
||||
? FileWatcherEventKind.Deleted
|
||||
: FileWatcherEventKind.Changed;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export interface RecursiveDirectoryWatcherHost {
|
||||
watchDirectory: HostWatchDirectory;
|
||||
@@ -756,8 +743,7 @@ namespace ts {
|
||||
if (recursive) {
|
||||
return watchDirectoryRecursively(directoryName, callback);
|
||||
}
|
||||
watchDirectory(directoryName, callback);
|
||||
return undefined!; // TODO: GH#18217
|
||||
return watchDirectory(directoryName, callback);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -793,11 +779,10 @@ namespace ts {
|
||||
dirName,
|
||||
(_eventName: string, relativeFileName) => {
|
||||
// When files are deleted from disk, the triggered "rename" event would have a relativefileName of "undefined"
|
||||
const fileName = !isString(relativeFileName)
|
||||
? undefined! // TODO: GH#18217
|
||||
: getNormalizedAbsolutePath(relativeFileName, dirName);
|
||||
if (!isString(relativeFileName)) { return; }
|
||||
const fileName = getNormalizedAbsolutePath(relativeFileName, dirName);
|
||||
// Some applications save a working file via rename operations
|
||||
const callbacks = fileWatcherCallbacks.get(toCanonicalName(fileName));
|
||||
const callbacks = fileName && fileWatcherCallbacks.get(toCanonicalName(fileName));
|
||||
if (callbacks) {
|
||||
for (const fileCallback of callbacks) {
|
||||
fileCallback(fileName, FileWatcherEventKind.Changed);
|
||||
@@ -844,7 +829,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
type FsWatchCallback = (eventName: "rename" | "change", relativeFileName: string) => void;
|
||||
type FsWatchCallback = (eventName: "rename" | "change", relativeFileName: string | undefined) => void;
|
||||
|
||||
function createFileWatcherCallback(callback: FsWatchCallback): FileWatcherCallback {
|
||||
return (_fileName, eventKind) => callback(eventKind === FileWatcherEventKind.Changed ? "change" : "rename", "");
|
||||
|
||||
@@ -68,6 +68,14 @@ namespace ts {
|
||||
return transformers;
|
||||
}
|
||||
|
||||
export function noEmitSubstitution(_hint: EmitHint, node: Node) {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function noEmitNotification(hint: EmitHint, node: Node, callback: (hint: EmitHint, node: Node) => void) {
|
||||
callback(hint, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms an array of SourceFiles by passing them through each transformer.
|
||||
*
|
||||
@@ -87,8 +95,8 @@ namespace ts {
|
||||
let lexicalEnvironmentStackOffset = 0;
|
||||
let lexicalEnvironmentSuspended = false;
|
||||
let emitHelpers: EmitHelper[] | undefined;
|
||||
let onSubstituteNode: TransformationContext["onSubstituteNode"] = (_, node) => node;
|
||||
let onEmitNode: TransformationContext["onEmitNode"] = (hint, node, callback) => callback(hint, node);
|
||||
let onSubstituteNode: TransformationContext["onSubstituteNode"] = noEmitSubstitution;
|
||||
let onEmitNode: TransformationContext["onEmitNode"] = noEmitNotification;
|
||||
let state = TransformationState.Uninitialized;
|
||||
const diagnostics: DiagnosticWithLocation[] = [];
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, file: SourceFile | undefined): DiagnosticWithLocation[] | undefined {
|
||||
if (file && isSourceFileJavaScript(file)) {
|
||||
if (file && isSourceFileJS(file)) {
|
||||
return []; // No declaration diagnostics for js for now
|
||||
}
|
||||
const compilerOptions = host.getCompilerOptions();
|
||||
const result = transformNodes(resolver, host, compilerOptions, file ? [file] : filter(host.getSourceFiles(), isSourceFileNotJavaScript), [transformDeclarations], /*allowDtsFiles*/ false);
|
||||
const result = transformNodes(resolver, host, compilerOptions, file ? [file] : filter(host.getSourceFiles(), isSourceFileNotJS), [transformDeclarations], /*allowDtsFiles*/ false);
|
||||
return result.diagnostics;
|
||||
}
|
||||
|
||||
@@ -33,10 +33,11 @@ namespace ts {
|
||||
let needsScopeFixMarker = false;
|
||||
let resultHasScopeMarker = false;
|
||||
let enclosingDeclaration: Node;
|
||||
let necessaryTypeRefernces: Map<true> | undefined;
|
||||
let necessaryTypeReferences: Map<true> | undefined;
|
||||
let lateMarkedStatements: LateVisibilityPaintedStatement[] | undefined;
|
||||
let lateStatementReplacementMap: Map<VisitResult<LateVisibilityPaintedStatement>>;
|
||||
let suppressNewDiagnosticContexts: boolean;
|
||||
let exportedModulesFromDeclarationEmit: Symbol[] | undefined;
|
||||
|
||||
const host = context.getEmitHost();
|
||||
const symbolTracker: SymbolTracker = {
|
||||
@@ -44,13 +45,16 @@ namespace ts {
|
||||
reportInaccessibleThisError,
|
||||
reportInaccessibleUniqueSymbolError,
|
||||
reportPrivateInBaseOfClassExpression,
|
||||
reportLikelyUnsafeImportRequiredError,
|
||||
moduleResolverHost: host,
|
||||
trackReferencedAmbientModule,
|
||||
trackExternalModuleSymbolOfImportTypeNode
|
||||
};
|
||||
let errorNameNode: DeclarationName | undefined;
|
||||
|
||||
let currentSourceFile: SourceFile;
|
||||
let refs: Map<SourceFile>;
|
||||
let libs: Map<boolean>;
|
||||
const resolver = context.getEmitResolver();
|
||||
const options = context.getCompilerOptions();
|
||||
const newLine = getNewLineCharacter(options);
|
||||
@@ -61,9 +65,9 @@ namespace ts {
|
||||
if (!typeReferenceDirectives) {
|
||||
return;
|
||||
}
|
||||
necessaryTypeRefernces = necessaryTypeRefernces || createMap<true>();
|
||||
necessaryTypeReferences = necessaryTypeReferences || createMap<true>();
|
||||
for (const ref of typeReferenceDirectives) {
|
||||
necessaryTypeRefernces.set(ref, true);
|
||||
necessaryTypeReferences.set(ref, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +119,12 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function trackExternalModuleSymbolOfImportTypeNode(symbol: Symbol) {
|
||||
if (!isBundledEmit) {
|
||||
(exportedModulesFromDeclarationEmit || (exportedModulesFromDeclarationEmit = [])).push(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
function trackSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags) {
|
||||
if (symbol.flags & SymbolFlags.TypeParameter) return;
|
||||
handleSymbolAccessibilityError(resolver.isSymbolAccessible(symbol, enclosingDeclaration, meaning, /*shouldComputeAliasesToMakeVisible*/ true));
|
||||
@@ -144,21 +154,30 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function reportLikelyUnsafeImportRequiredError(specifier: string) {
|
||||
if (errorNameNode) {
|
||||
context.addDiagnostic(createDiagnosticForNode(errorNameNode, Diagnostics.The_inferred_type_of_0_cannot_be_named_without_a_reference_to_1_This_is_likely_not_portable_A_type_annotation_is_necessary,
|
||||
declarationNameToString(errorNameNode),
|
||||
specifier));
|
||||
}
|
||||
}
|
||||
|
||||
function transformRoot(node: Bundle): Bundle;
|
||||
function transformRoot(node: SourceFile): SourceFile;
|
||||
function transformRoot(node: SourceFile | Bundle): SourceFile | Bundle;
|
||||
function transformRoot(node: SourceFile | Bundle) {
|
||||
if (node.kind === SyntaxKind.SourceFile && (node.isDeclarationFile || isSourceFileJavaScript(node))) {
|
||||
if (node.kind === SyntaxKind.SourceFile && (node.isDeclarationFile || isSourceFileJS(node))) {
|
||||
return node;
|
||||
}
|
||||
|
||||
if (node.kind === SyntaxKind.Bundle) {
|
||||
isBundledEmit = true;
|
||||
refs = createMap<SourceFile>();
|
||||
libs = createMap<boolean>();
|
||||
let hasNoDefaultLib = false;
|
||||
const bundle = createBundle(map(node.sourceFiles,
|
||||
sourceFile => {
|
||||
if (sourceFile.isDeclarationFile || isSourceFileJavaScript(sourceFile)) return undefined!; // Omit declaration files from bundle results, too // TODO: GH#18217
|
||||
if (sourceFile.isDeclarationFile || isSourceFileJS(sourceFile)) return undefined!; // Omit declaration files from bundle results, too // TODO: GH#18217
|
||||
hasNoDefaultLib = hasNoDefaultLib || sourceFile.hasNoDefaultLib;
|
||||
currentSourceFile = sourceFile;
|
||||
enclosingDeclaration = sourceFile;
|
||||
@@ -169,6 +188,7 @@ namespace ts {
|
||||
needsScopeFixMarker = false;
|
||||
resultHasScopeMarker = false;
|
||||
collectReferences(sourceFile, refs);
|
||||
collectLibs(sourceFile, libs);
|
||||
if (isExternalModule(sourceFile)) {
|
||||
resultHasExternalModuleIndicator = false; // unused in external module bundle emit (all external modules are within module blocks, therefore are known to be modules)
|
||||
needsDeclare = false;
|
||||
@@ -192,6 +212,7 @@ namespace ts {
|
||||
}));
|
||||
bundle.syntheticFileReferences = [];
|
||||
bundle.syntheticTypeReferences = getFileReferencesForUsedTypeReferences();
|
||||
bundle.syntheticLibReferences = getLibReferences();
|
||||
bundle.hasNoDefaultLib = hasNoDefaultLib;
|
||||
const outputFilePath = getDirectoryPath(normalizeSlashes(getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath!));
|
||||
const referenceVisitor = mapReferencesIntoArray(bundle.syntheticFileReferences as FileReference[], outputFilePath);
|
||||
@@ -211,8 +232,9 @@ namespace ts {
|
||||
suppressNewDiagnosticContexts = false;
|
||||
lateMarkedStatements = undefined;
|
||||
lateStatementReplacementMap = createMap();
|
||||
necessaryTypeRefernces = undefined;
|
||||
necessaryTypeReferences = undefined;
|
||||
refs = collectReferences(currentSourceFile, createMap());
|
||||
libs = collectLibs(currentSourceFile, createMap());
|
||||
const references: FileReference[] = [];
|
||||
const outputFilePath = getDirectoryPath(normalizeSlashes(getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath!));
|
||||
const referenceVisitor = mapReferencesIntoArray(references, outputFilePath);
|
||||
@@ -223,11 +245,16 @@ namespace ts {
|
||||
if (isExternalModule(node) && (!resultHasExternalModuleIndicator || (needsScopeFixMarker && !resultHasScopeMarker))) {
|
||||
combinedStatements = setTextRange(createNodeArray([...combinedStatements, createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([]), /*moduleSpecifier*/ undefined)]), combinedStatements);
|
||||
}
|
||||
const updated = updateSourceFileNode(node, combinedStatements, /*isDeclarationFile*/ true, references, getFileReferencesForUsedTypeReferences(), node.hasNoDefaultLib);
|
||||
const updated = updateSourceFileNode(node, combinedStatements, /*isDeclarationFile*/ true, references, getFileReferencesForUsedTypeReferences(), node.hasNoDefaultLib, getLibReferences());
|
||||
updated.exportedModulesFromDeclarationEmit = exportedModulesFromDeclarationEmit;
|
||||
return updated;
|
||||
|
||||
function getLibReferences() {
|
||||
return map(arrayFrom(libs.keys()), lib => ({ fileName: lib, pos: -1, end: -1 }));
|
||||
}
|
||||
|
||||
function getFileReferencesForUsedTypeReferences() {
|
||||
return necessaryTypeRefernces ? mapDefined(arrayFrom(necessaryTypeRefernces.keys()), getFileReferenceForTypeName) : [];
|
||||
return necessaryTypeReferences ? mapDefined(arrayFrom(necessaryTypeReferences.keys()), getFileReferenceForTypeName) : [];
|
||||
}
|
||||
|
||||
function getFileReferenceForTypeName(typeName: string): FileReference | undefined {
|
||||
@@ -257,7 +284,7 @@ namespace ts {
|
||||
else {
|
||||
if (isBundledEmit && contains((node as Bundle).sourceFiles, file)) return; // Omit references to files which are being merged
|
||||
const paths = getOutputPathsFor(file, host, /*forceDtsPaths*/ true);
|
||||
declFileName = paths.declarationFilePath || paths.jsFilePath;
|
||||
declFileName = paths.declarationFilePath || paths.jsFilePath || file.fileName;
|
||||
}
|
||||
|
||||
if (declFileName) {
|
||||
@@ -271,6 +298,13 @@ namespace ts {
|
||||
if (startsWith(fileName, "./") && hasExtension(fileName)) {
|
||||
fileName = fileName.substring(2);
|
||||
}
|
||||
|
||||
// omit references to files from node_modules (npm may disambiguate module
|
||||
// references when installing this package, making the path is unreliable).
|
||||
if (startsWith(fileName, "node_modules/") || fileName.indexOf("/node_modules/") !== -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
references.push({ pos: -1, end: -1, fileName });
|
||||
}
|
||||
};
|
||||
@@ -278,7 +312,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function collectReferences(sourceFile: SourceFile, ret: Map<SourceFile>) {
|
||||
if (noResolve || isSourceFileJavaScript(sourceFile)) return ret;
|
||||
if (noResolve || isSourceFileJS(sourceFile)) return ret;
|
||||
forEach(sourceFile.referencedFiles, f => {
|
||||
const elem = tryResolveScriptReference(host, sourceFile, f);
|
||||
if (elem) {
|
||||
@@ -288,6 +322,16 @@ namespace ts {
|
||||
return ret;
|
||||
}
|
||||
|
||||
function collectLibs(sourceFile: SourceFile, ret: Map<boolean>) {
|
||||
forEach(sourceFile.libReferenceDirectives, ref => {
|
||||
const lib = host.getLibFileFromReference(ref);
|
||||
if (lib) {
|
||||
ret.set(ref.fileName.toLocaleLowerCase(), true);
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
function filterBindingPatternInitializers(name: BindingName) {
|
||||
if (name.kind === SyntaxKind.Identifier) {
|
||||
return name;
|
||||
@@ -338,7 +382,7 @@ namespace ts {
|
||||
|
||||
function ensureNoInitializer(node: CanHaveLiteralInitializer) {
|
||||
if (shouldPrintWithInitializer(node)) {
|
||||
return resolver.createLiteralConstValue(getParseTreeNode(node) as CanHaveLiteralInitializer); // TODO: Make safe
|
||||
return resolver.createLiteralConstValue(getParseTreeNode(node) as CanHaveLiteralInitializer, symbolTracker); // TODO: Make safe
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@@ -483,10 +527,18 @@ namespace ts {
|
||||
function rewriteModuleSpecifier<T extends Node>(parent: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration | ImportTypeNode, input: T | undefined): T | StringLiteral {
|
||||
if (!input) return undefined!; // TODO: GH#18217
|
||||
resultHasExternalModuleIndicator = resultHasExternalModuleIndicator || (parent.kind !== SyntaxKind.ModuleDeclaration && parent.kind !== SyntaxKind.ImportType);
|
||||
if (input.kind === SyntaxKind.StringLiteral && isBundledEmit) {
|
||||
const newName = getExternalModuleNameFromDeclaration(context.getEmitHost(), resolver, parent);
|
||||
if (newName) {
|
||||
return createLiteral(newName);
|
||||
if (isStringLiteralLike(input)) {
|
||||
if (isBundledEmit) {
|
||||
const newName = getExternalModuleNameFromDeclaration(context.getEmitHost(), resolver, parent);
|
||||
if (newName) {
|
||||
return createLiteral(newName);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const symbol = resolver.getSymbolOfExternalModuleSpecifier(input);
|
||||
if (symbol) {
|
||||
(exportedModulesFromDeclarationEmit || (exportedModulesFromDeclarationEmit = [])).push(symbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
return input;
|
||||
@@ -935,7 +987,7 @@ namespace ts {
|
||||
}
|
||||
case SyntaxKind.FunctionDeclaration: {
|
||||
// Generators lose their generator-ness, excepting their return type
|
||||
return cleanup(updateFunctionDeclaration(
|
||||
const clean = cleanup(updateFunctionDeclaration(
|
||||
input,
|
||||
/*decorators*/ undefined,
|
||||
ensureModifiers(input, isPrivate),
|
||||
@@ -946,6 +998,21 @@ namespace ts {
|
||||
ensureType(input, input.type),
|
||||
/*body*/ undefined
|
||||
));
|
||||
if (clean && resolver.isExpandoFunctionDeclaration(input)) {
|
||||
const declarations = mapDefined(resolver.getPropertiesOfContainerFunction(input), p => {
|
||||
if (!isPropertyAccessExpression(p.valueDeclaration)) {
|
||||
return undefined;
|
||||
}
|
||||
const type = resolver.createTypeOfDeclaration(p.valueDeclaration, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker);
|
||||
const varDecl = createVariableDeclaration(unescapeLeadingUnderscores(p.escapedName), type, /*initializer*/ undefined);
|
||||
return createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([varDecl]));
|
||||
});
|
||||
const namespaceDecl = createModuleDeclaration(/*decorators*/ undefined, ensureModifiers(input, isPrivate), input.name!, createModuleBlock(declarations), NodeFlags.Namespace);
|
||||
return [clean, namespaceDecl];
|
||||
}
|
||||
else {
|
||||
return clean;
|
||||
}
|
||||
}
|
||||
case SyntaxKind.ModuleDeclaration: {
|
||||
needsDeclare = false;
|
||||
@@ -985,7 +1052,7 @@ namespace ts {
|
||||
const modifiers = createNodeArray(ensureModifiers(input, isPrivate));
|
||||
const typeParameters = ensureTypeParams(input, input.typeParameters);
|
||||
const ctor = getFirstConstructorWithBody(input);
|
||||
let parameterProperties: PropertyDeclaration[] | undefined;
|
||||
let parameterProperties: ReadonlyArray<PropertyDeclaration> | undefined;
|
||||
if (ctor) {
|
||||
const oldDiag = getSymbolAccessibilityDiagnostic;
|
||||
parameterProperties = compact(flatMap(ctor.parameters, param => {
|
||||
@@ -1033,7 +1100,8 @@ namespace ts {
|
||||
if (extendsClause && !isEntityNameExpression(extendsClause.expression) && extendsClause.expression.kind !== SyntaxKind.NullKeyword) {
|
||||
// We must add a temporary declaration for the extends clause expression
|
||||
|
||||
const newId = createOptimisticUniqueName(`${unescapeLeadingUnderscores(input.name!.escapedText)}_base`); // TODO: GH#18217
|
||||
const oldId = input.name ? unescapeLeadingUnderscores(input.name.escapedText) : "default";
|
||||
const newId = createOptimisticUniqueName(`${oldId}_base`);
|
||||
getSymbolAccessibilityDiagnostic = () => ({
|
||||
diagnosticMessage: Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1,
|
||||
errorNode: extendsClause,
|
||||
@@ -1273,12 +1341,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
type CanHaveLiteralInitializer = VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration;
|
||||
function canHaveLiteralInitializer(node: Node): node is CanHaveLiteralInitializer {
|
||||
function canHaveLiteralInitializer(node: Node): boolean {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.PropertySignature:
|
||||
return !hasModifier(node, ModifierFlags.Private);
|
||||
case SyntaxKind.Parameter:
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -389,6 +389,7 @@ namespace ts {
|
||||
diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1;
|
||||
break;
|
||||
|
||||
case SyntaxKind.ConstructorType:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
diagnosticMessage = Diagnostics.Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
|
||||
break;
|
||||
@@ -410,6 +411,7 @@ namespace ts {
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_function_has_or_is_using_private_name_1;
|
||||
break;
|
||||
@@ -434,7 +436,7 @@ namespace ts {
|
||||
// Heritage clause is written by user so it can always be named
|
||||
if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) {
|
||||
// Class or Interface implemented/extended is inaccessible
|
||||
diagnosticMessage = (node as ExpressionWithTypeArguments).parent.token === SyntaxKind.ImplementsKeyword ?
|
||||
diagnosticMessage = isHeritageClause(node.parent) && node.parent.token === SyntaxKind.ImplementsKeyword ?
|
||||
Diagnostics.Implements_clause_of_exported_class_0_has_or_is_using_private_name_1 :
|
||||
Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1;
|
||||
}
|
||||
@@ -446,7 +448,7 @@ namespace ts {
|
||||
return {
|
||||
diagnosticMessage,
|
||||
errorNode: node,
|
||||
typeName: getNameOfDeclaration((node as ExpressionWithTypeArguments).parent.parent)
|
||||
typeName: getNameOfDeclaration(node.parent.parent as Declaration)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -466,4 +468,4 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,8 +307,8 @@ namespace ts {
|
||||
if (!getRestIndicatorOfBindingOrAssignmentElement(element)) {
|
||||
const propertyName = getPropertyNameOfBindingOrAssignmentElement(element)!;
|
||||
if (flattenContext.level >= FlattenLevel.ObjectRest
|
||||
&& !(element.transformFlags & (TransformFlags.ContainsRest | TransformFlags.ContainsObjectRest))
|
||||
&& !(getTargetOfBindingOrAssignmentElement(element)!.transformFlags & (TransformFlags.ContainsRest | TransformFlags.ContainsObjectRest))
|
||||
&& !(element.transformFlags & (TransformFlags.ContainsRestOrSpread | TransformFlags.ContainsObjectRestOrSpread))
|
||||
&& !(getTargetOfBindingOrAssignmentElement(element)!.transformFlags & (TransformFlags.ContainsRestOrSpread | TransformFlags.ContainsObjectRestOrSpread))
|
||||
&& !isComputedPropertyName(propertyName)) {
|
||||
bindingElements = append(bindingElements, element);
|
||||
}
|
||||
@@ -384,7 +384,7 @@ namespace ts {
|
||||
if (flattenContext.level >= FlattenLevel.ObjectRest) {
|
||||
// If an array pattern contains an ObjectRest, we must cache the result so that we
|
||||
// can perform the ObjectRest destructuring in a different declaration
|
||||
if (element.transformFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (element.transformFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
const temp = createTempVariable(/*recordTempVariable*/ undefined);
|
||||
if (flattenContext.hoistTempVariables) {
|
||||
flattenContext.context.hoistVariableDeclaration(temp);
|
||||
@@ -447,7 +447,7 @@ namespace ts {
|
||||
const argumentExpression = ensureIdentifier(flattenContext, visitNode(propertyName.expression, flattenContext.visitor), /*reuseIdentifierExpressions*/ false, /*location*/ propertyName);
|
||||
return createElementAccess(value, argumentExpression);
|
||||
}
|
||||
else if (isStringOrNumericLiteral(propertyName)) {
|
||||
else if (isStringOrNumericLiteralLike(propertyName)) {
|
||||
const argumentExpression = getSynthesizedClone(propertyName);
|
||||
argumentExpression.text = argumentExpression.text;
|
||||
return createElementAccess(value, argumentExpression);
|
||||
|
||||
+472
-167
@@ -46,10 +46,16 @@ namespace ts {
|
||||
* so nobody can observe this new value.
|
||||
*/
|
||||
interface LoopOutParameter {
|
||||
flags: LoopOutParameterFlags;
|
||||
originalName: Identifier;
|
||||
outParamName: Identifier;
|
||||
}
|
||||
|
||||
const enum LoopOutParameterFlags {
|
||||
Body = 1 << 0, // Modified in the body of the iteration statement
|
||||
Initializer = 1 << 1, // Set in the initializer of a ForStatement
|
||||
}
|
||||
|
||||
const enum CopyDirection {
|
||||
ToOriginal,
|
||||
ToOutParameter
|
||||
@@ -129,10 +135,14 @@ namespace ts {
|
||||
*/
|
||||
hoistedLocalVariables?: Identifier[];
|
||||
|
||||
conditionVariable?: Identifier;
|
||||
|
||||
loopParameters: ParameterDeclaration[];
|
||||
|
||||
/**
|
||||
* List of loop out parameters - detailed descripion can be found in the comment to LoopOutParameter
|
||||
*/
|
||||
loopOutParameters?: LoopOutParameter[];
|
||||
loopOutParameters: LoopOutParameter[];
|
||||
}
|
||||
|
||||
const enum SuperCaptureResult {
|
||||
@@ -347,7 +357,7 @@ namespace ts {
|
||||
return (node.transformFlags & TransformFlags.ContainsES2015) !== 0
|
||||
|| convertedLoopState !== undefined
|
||||
|| (hierarchyFacts & HierarchyFacts.ConstructorWithCapturedSuper && (isStatement(node) || (node.kind === SyntaxKind.Block)))
|
||||
|| (isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(node))
|
||||
|| (isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatement(node))
|
||||
|| (getEmitFlags(node) & EmitFlags.TypeScriptClassWrapper) !== 0;
|
||||
}
|
||||
|
||||
@@ -646,8 +656,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
let returnExpression: Expression = createLiteral(labelMarker);
|
||||
if (convertedLoopState.loopOutParameters!.length) {
|
||||
const outParams = convertedLoopState.loopOutParameters!;
|
||||
if (convertedLoopState.loopOutParameters.length) {
|
||||
const outParams = convertedLoopState.loopOutParameters;
|
||||
let expr: Expression | undefined;
|
||||
for (let i = 0; i < outParams.length; i++) {
|
||||
const copyExpr = copyOutParameter(outParams[i], CopyDirection.ToOutParameter);
|
||||
@@ -2078,14 +2088,11 @@ namespace ts {
|
||||
setTextRange(declarationList, node);
|
||||
setCommentRange(declarationList, node);
|
||||
|
||||
// If the first or last declaration is a binding pattern, we need to modify
|
||||
// the source map range for the declaration list.
|
||||
if (node.transformFlags & TransformFlags.ContainsBindingPattern
|
||||
&& (isBindingPattern(node.declarations[0].name) || isBindingPattern(last(node.declarations).name))) {
|
||||
// If the first or last declaration is a binding pattern, we need to modify
|
||||
// the source map range for the declaration list.
|
||||
const firstDeclaration = firstOrUndefined(declarations);
|
||||
if (firstDeclaration) {
|
||||
setSourceMapRange(declarationList, createRange(firstDeclaration.pos, last(declarations).end));
|
||||
}
|
||||
setSourceMapRange(declarationList, getRangeUnion(declarations));
|
||||
}
|
||||
|
||||
return declarationList;
|
||||
@@ -2093,6 +2100,17 @@ namespace ts {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function getRangeUnion(declarations: ReadonlyArray<Node>): TextRange {
|
||||
// declarations may not be sorted by position.
|
||||
// pos should be the minimum* position over all nodes (that's not -1), end should be the maximum end over all nodes.
|
||||
let pos = -1, end = -1;
|
||||
for (const node of declarations) {
|
||||
pos = pos === -1 ? node.pos : node.pos === -1 ? pos : Math.min(pos, node.pos);
|
||||
end = Math.max(end, node.end);
|
||||
}
|
||||
return createRange(pos, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether we should emit an explicit initializer for a variable
|
||||
* declaration in a `let` declaration list.
|
||||
@@ -2620,7 +2638,40 @@ namespace ts {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function shouldConvertIterationStatementBody(node: IterationStatement): boolean {
|
||||
interface ForStatementWithConvertibleInitializer extends ForStatement {
|
||||
initializer: VariableDeclarationList;
|
||||
}
|
||||
|
||||
interface ForStatementWithConvertibleCondition extends ForStatement {
|
||||
condition: Expression;
|
||||
}
|
||||
|
||||
interface ForStatementWithConvertibleIncrementor extends ForStatement {
|
||||
incrementor: Expression;
|
||||
}
|
||||
|
||||
function shouldConvertPartOfIterationStatement(node: Node) {
|
||||
return (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ContainsCapturedBlockScopeBinding) !== 0;
|
||||
}
|
||||
|
||||
function shouldConvertInitializerOfForStatement(node: IterationStatement): node is ForStatementWithConvertibleInitializer {
|
||||
return isForStatement(node) && !!node.initializer && shouldConvertPartOfIterationStatement(node.initializer);
|
||||
}
|
||||
|
||||
function shouldConvertConditionOfForStatement(node: IterationStatement): node is ForStatementWithConvertibleCondition {
|
||||
return isForStatement(node) && !!node.condition && shouldConvertPartOfIterationStatement(node.condition);
|
||||
}
|
||||
|
||||
function shouldConvertIncrementorOfForStatement(node: IterationStatement): node is ForStatementWithConvertibleIncrementor {
|
||||
return isForStatement(node) && !!node.incrementor && shouldConvertPartOfIterationStatement(node.incrementor);
|
||||
}
|
||||
|
||||
function shouldConvertIterationStatement(node: IterationStatement) {
|
||||
return shouldConvertBodyOfIterationStatement(node)
|
||||
|| shouldConvertInitializerOfForStatement(node);
|
||||
}
|
||||
|
||||
function shouldConvertBodyOfIterationStatement(node: IterationStatement): boolean {
|
||||
return (resolver.getNodeCheckFlags(node) & NodeCheckFlags.LoopWithCapturedBlockScopedBinding) !== 0;
|
||||
}
|
||||
|
||||
@@ -2649,7 +2700,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function convertIterationStatementBodyIfNecessary(node: IterationStatement, outermostLabeledStatement: LabeledStatement | undefined, convert?: LoopConverter): VisitResult<Statement> {
|
||||
if (!shouldConvertIterationStatementBody(node)) {
|
||||
if (!shouldConvertIterationStatement(node)) {
|
||||
let saveAllowedNonLabeledJumps: Jump | undefined;
|
||||
if (convertedLoopState) {
|
||||
// we get here if we are trying to emit normal loop loop inside converted loop
|
||||
@@ -2668,7 +2719,102 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
const functionName = createUniqueName("_loop");
|
||||
const currentState = createConvertedLoopState(node);
|
||||
const statements: Statement[] = [];
|
||||
|
||||
const outerConvertedLoopState = convertedLoopState;
|
||||
convertedLoopState = currentState;
|
||||
|
||||
const initializerFunction = shouldConvertInitializerOfForStatement(node) ? createFunctionForInitializerOfForStatement(node, currentState) : undefined;
|
||||
const bodyFunction = shouldConvertBodyOfIterationStatement(node) ? createFunctionForBodyOfIterationStatement(node, currentState, outerConvertedLoopState) : undefined;
|
||||
|
||||
convertedLoopState = outerConvertedLoopState;
|
||||
|
||||
if (initializerFunction) statements.push(initializerFunction.functionDeclaration);
|
||||
if (bodyFunction) statements.push(bodyFunction.functionDeclaration);
|
||||
|
||||
addExtraDeclarationsForConvertedLoop(statements, currentState, outerConvertedLoopState);
|
||||
|
||||
if (initializerFunction) {
|
||||
statements.push(generateCallToConvertedLoopInitializer(initializerFunction.functionName, initializerFunction.containsYield));
|
||||
}
|
||||
|
||||
let loop: Statement;
|
||||
if (bodyFunction) {
|
||||
if (convert) {
|
||||
loop = convert(node, outermostLabeledStatement, bodyFunction.part);
|
||||
}
|
||||
else {
|
||||
const clone = convertIterationStatementCore(node, initializerFunction, createBlock(bodyFunction.part, /*multiLine*/ true));
|
||||
aggregateTransformFlags(clone);
|
||||
loop = restoreEnclosingLabel(clone, outermostLabeledStatement, convertedLoopState && resetLabel);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const clone = convertIterationStatementCore(node, initializerFunction, visitNode(node.statement, visitor, isStatement, liftToBlock));
|
||||
aggregateTransformFlags(clone);
|
||||
loop = restoreEnclosingLabel(clone, outermostLabeledStatement, convertedLoopState && resetLabel);
|
||||
}
|
||||
|
||||
statements.push(loop);
|
||||
return statements;
|
||||
}
|
||||
|
||||
function convertIterationStatementCore(node: IterationStatement, initializerFunction: IterationStatementPartFunction<VariableDeclarationList> | undefined, convertedLoopBody: Statement) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ForStatement: return convertForStatement(node as ForStatement, initializerFunction, convertedLoopBody);
|
||||
case SyntaxKind.ForInStatement: return convertForInStatement(node as ForInStatement, convertedLoopBody);
|
||||
case SyntaxKind.ForOfStatement: return convertForOfStatement(node as ForOfStatement, convertedLoopBody);
|
||||
case SyntaxKind.DoStatement: return convertDoStatement(node as DoStatement, convertedLoopBody);
|
||||
case SyntaxKind.WhileStatement: return convertWhileStatement(node as WhileStatement, convertedLoopBody);
|
||||
default: return Debug.failBadSyntaxKind(node, "IterationStatement expected");
|
||||
}
|
||||
}
|
||||
|
||||
function convertForStatement(node: ForStatement, initializerFunction: IterationStatementPartFunction<VariableDeclarationList> | undefined, convertedLoopBody: Statement) {
|
||||
const shouldConvertCondition = node.condition && shouldConvertPartOfIterationStatement(node.condition);
|
||||
const shouldConvertIncrementor = shouldConvertCondition || node.incrementor && shouldConvertPartOfIterationStatement(node.incrementor);
|
||||
return updateFor(
|
||||
node,
|
||||
visitNode(initializerFunction ? initializerFunction.part : node.initializer, visitor, isForInitializer),
|
||||
visitNode(shouldConvertCondition ? undefined : node.condition, visitor, isExpression),
|
||||
visitNode(shouldConvertIncrementor ? undefined : node.incrementor, visitor, isExpression),
|
||||
convertedLoopBody
|
||||
);
|
||||
}
|
||||
|
||||
function convertForOfStatement(node: ForOfStatement, convertedLoopBody: Statement) {
|
||||
return updateForOf(
|
||||
node,
|
||||
/*awaitModifier*/ undefined,
|
||||
visitNode(node.initializer, visitor, isForInitializer),
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
convertedLoopBody);
|
||||
}
|
||||
|
||||
function convertForInStatement(node: ForInStatement, convertedLoopBody: Statement) {
|
||||
return updateForIn(
|
||||
node,
|
||||
visitNode(node.initializer, visitor, isForInitializer),
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
convertedLoopBody);
|
||||
}
|
||||
|
||||
function convertDoStatement(node: DoStatement, convertedLoopBody: Statement) {
|
||||
return updateDo(
|
||||
node,
|
||||
convertedLoopBody,
|
||||
visitNode(node.expression, visitor, isExpression));
|
||||
}
|
||||
|
||||
function convertWhileStatement(node: WhileStatement, convertedLoopBody: Statement) {
|
||||
return updateWhile(
|
||||
node,
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
convertedLoopBody);
|
||||
}
|
||||
|
||||
function createConvertedLoopState(node: IterationStatement) {
|
||||
let loopInitializer: VariableDeclarationList | undefined;
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ForStatement:
|
||||
@@ -2680,74 +2826,311 @@ namespace ts {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// variables that will be passed to the loop as parameters
|
||||
const loopParameters: ParameterDeclaration[] = [];
|
||||
// variables declared in the loop initializer that will be changed inside the loop
|
||||
const loopOutParameters: LoopOutParameter[] = [];
|
||||
if (loopInitializer && (getCombinedNodeFlags(loopInitializer) & NodeFlags.BlockScoped)) {
|
||||
const hasCapturedBindingsInForInitializer = shouldConvertInitializerOfForStatement(node);
|
||||
for (const decl of loopInitializer.declarations) {
|
||||
processLoopVariableDeclaration(decl, loopParameters, loopOutParameters);
|
||||
processLoopVariableDeclaration(node, decl, loopParameters, loopOutParameters, hasCapturedBindingsInForInitializer);
|
||||
}
|
||||
}
|
||||
|
||||
const outerConvertedLoopState = convertedLoopState;
|
||||
convertedLoopState = { loopOutParameters };
|
||||
if (outerConvertedLoopState) {
|
||||
const currentState: ConvertedLoopState = { loopParameters, loopOutParameters };
|
||||
if (convertedLoopState) {
|
||||
// convertedOuterLoopState !== undefined means that this converted loop is nested in another converted loop.
|
||||
// if outer converted loop has already accumulated some state - pass it through
|
||||
if (outerConvertedLoopState.argumentsName) {
|
||||
if (convertedLoopState.argumentsName) {
|
||||
// outer loop has already used 'arguments' so we've already have some name to alias it
|
||||
// use the same name in all nested loops
|
||||
convertedLoopState.argumentsName = outerConvertedLoopState.argumentsName;
|
||||
currentState.argumentsName = convertedLoopState.argumentsName;
|
||||
}
|
||||
if (outerConvertedLoopState.thisName) {
|
||||
if (convertedLoopState.thisName) {
|
||||
// outer loop has already used 'this' so we've already have some name to alias it
|
||||
// use the same name in all nested loops
|
||||
convertedLoopState.thisName = outerConvertedLoopState.thisName;
|
||||
currentState.thisName = convertedLoopState.thisName;
|
||||
}
|
||||
if (outerConvertedLoopState.hoistedLocalVariables) {
|
||||
if (convertedLoopState.hoistedLocalVariables) {
|
||||
// we've already collected some non-block scoped variable declarations in enclosing loop
|
||||
// use the same storage in nested loop
|
||||
convertedLoopState.hoistedLocalVariables = outerConvertedLoopState.hoistedLocalVariables;
|
||||
currentState.hoistedLocalVariables = convertedLoopState.hoistedLocalVariables;
|
||||
}
|
||||
}
|
||||
return currentState;
|
||||
}
|
||||
|
||||
function addExtraDeclarationsForConvertedLoop(statements: Statement[], state: ConvertedLoopState, outerState: ConvertedLoopState | undefined) {
|
||||
let extraVariableDeclarations: VariableDeclaration[] | undefined;
|
||||
// propagate state from the inner loop to the outer loop if necessary
|
||||
if (state.argumentsName) {
|
||||
// if alias for arguments is set
|
||||
if (outerState) {
|
||||
// pass it to outer converted loop
|
||||
outerState.argumentsName = state.argumentsName;
|
||||
}
|
||||
else {
|
||||
// this is top level converted loop and we need to create an alias for 'arguments' object
|
||||
(extraVariableDeclarations || (extraVariableDeclarations = [])).push(
|
||||
createVariableDeclaration(
|
||||
state.argumentsName,
|
||||
/*type*/ undefined,
|
||||
createIdentifier("arguments")
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (state.thisName) {
|
||||
// if alias for this is set
|
||||
if (outerState) {
|
||||
// pass it to outer converted loop
|
||||
outerState.thisName = state.thisName;
|
||||
}
|
||||
else {
|
||||
// this is top level converted loop so we need to create an alias for 'this' here
|
||||
// NOTE:
|
||||
// if converted loops were all nested in arrow function then we'll always emit '_this' so convertedLoopState.thisName will not be set.
|
||||
// If it is set this means that all nested loops are not nested in arrow function and it is safe to capture 'this'.
|
||||
(extraVariableDeclarations || (extraVariableDeclarations = [])).push(
|
||||
createVariableDeclaration(
|
||||
state.thisName,
|
||||
/*type*/ undefined,
|
||||
createIdentifier("this")
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (state.hoistedLocalVariables) {
|
||||
// if hoistedLocalVariables !== undefined this means that we've possibly collected some variable declarations to be hoisted later
|
||||
if (outerState) {
|
||||
// pass them to outer converted loop
|
||||
outerState.hoistedLocalVariables = state.hoistedLocalVariables;
|
||||
}
|
||||
else {
|
||||
if (!extraVariableDeclarations) {
|
||||
extraVariableDeclarations = [];
|
||||
}
|
||||
// hoist collected variable declarations
|
||||
for (const identifier of state.hoistedLocalVariables) {
|
||||
extraVariableDeclarations.push(createVariableDeclaration(identifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add extra variables to hold out parameters if necessary
|
||||
if (state.loopOutParameters.length) {
|
||||
if (!extraVariableDeclarations) {
|
||||
extraVariableDeclarations = [];
|
||||
}
|
||||
for (const outParam of state.loopOutParameters) {
|
||||
extraVariableDeclarations.push(createVariableDeclaration(outParam.outParamName));
|
||||
}
|
||||
}
|
||||
|
||||
if (state.conditionVariable) {
|
||||
if (!extraVariableDeclarations) {
|
||||
extraVariableDeclarations = [];
|
||||
}
|
||||
extraVariableDeclarations.push(createVariableDeclaration(state.conditionVariable, /*type*/ undefined, createFalse()));
|
||||
}
|
||||
|
||||
// create variable statement to hold all introduced variable declarations
|
||||
if (extraVariableDeclarations) {
|
||||
statements.push(createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList(extraVariableDeclarations)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
interface IterationStatementPartFunction<T> {
|
||||
functionName: Identifier;
|
||||
functionDeclaration: Statement;
|
||||
containsYield: boolean;
|
||||
part: T;
|
||||
}
|
||||
|
||||
function createOutVariable(p: LoopOutParameter) {
|
||||
return createVariableDeclaration(p.originalName, /*type*/ undefined, p.outParamName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a `_loop_init` function for a `ForStatement` with a block-scoped initializer
|
||||
* that is captured in a closure inside of the initializer. The `_loop_init` function is
|
||||
* used to preserve the per-iteration environment semantics of
|
||||
* [13.7.4.8 RS: ForBodyEvaluation](https://tc39.github.io/ecma262/#sec-forbodyevaluation).
|
||||
*/
|
||||
function createFunctionForInitializerOfForStatement(node: ForStatementWithConvertibleInitializer, currentState: ConvertedLoopState): IterationStatementPartFunction<VariableDeclarationList> {
|
||||
const functionName = createUniqueName("_loop_init");
|
||||
|
||||
const containsYield = (node.initializer.transformFlags & TransformFlags.ContainsYield) !== 0;
|
||||
let emitFlags = EmitFlags.None;
|
||||
if (currentState.containsLexicalThis) emitFlags |= EmitFlags.CapturesThis;
|
||||
if (containsYield && hierarchyFacts & HierarchyFacts.AsyncFunctionBody) emitFlags |= EmitFlags.AsyncFunctionBody;
|
||||
|
||||
const statements: Statement[] = [];
|
||||
statements.push(createVariableStatement(/*modifiers*/ undefined, node.initializer));
|
||||
copyOutParameters(currentState.loopOutParameters, LoopOutParameterFlags.Initializer, CopyDirection.ToOutParameter, statements);
|
||||
|
||||
// This transforms the following ES2015 syntax:
|
||||
//
|
||||
// for (let i = (setImmediate(() => console.log(i)), 0); i < 2; i++) {
|
||||
// // loop body
|
||||
// }
|
||||
//
|
||||
// Into the following ES5 syntax:
|
||||
//
|
||||
// var _loop_init_1 = function () {
|
||||
// var i = (setImmediate(() => console.log(i)), 0);
|
||||
// out_i_1 = i;
|
||||
// };
|
||||
// var out_i_1;
|
||||
// _loop_init_1();
|
||||
// for (var i = out_i_1; i < 2; i++) {
|
||||
// // loop body
|
||||
// }
|
||||
//
|
||||
// Which prevents mutations to `i` in the per-iteration environment of the body
|
||||
// from affecting the initial value for `i` outside of the per-iteration environment.
|
||||
|
||||
const functionDeclaration = createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
setEmitFlags(
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(
|
||||
functionName,
|
||||
/*type*/ undefined,
|
||||
setEmitFlags(
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
containsYield ? createToken(SyntaxKind.AsteriskToken) : undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
/*parameters*/ undefined,
|
||||
/*type*/ undefined,
|
||||
visitNode(
|
||||
createBlock(statements, /*multiLine*/ true),
|
||||
visitor,
|
||||
isBlock
|
||||
)
|
||||
),
|
||||
emitFlags
|
||||
)
|
||||
)
|
||||
]),
|
||||
EmitFlags.NoHoisting
|
||||
)
|
||||
);
|
||||
|
||||
const part = createVariableDeclarationList(map(currentState.loopOutParameters, createOutVariable));
|
||||
return { functionName, containsYield, functionDeclaration, part };
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a `_loop` function for an `IterationStatement` with a block-scoped initializer
|
||||
* that is captured in a closure inside of the loop body. The `_loop` function is used to
|
||||
* preserve the per-iteration environment semantics of
|
||||
* [13.7.4.8 RS: ForBodyEvaluation](https://tc39.github.io/ecma262/#sec-forbodyevaluation).
|
||||
*/
|
||||
function createFunctionForBodyOfIterationStatement(node: IterationStatement, currentState: ConvertedLoopState, outerState: ConvertedLoopState | undefined): IterationStatementPartFunction<Statement[]> {
|
||||
const functionName = createUniqueName("_loop");
|
||||
startLexicalEnvironment();
|
||||
let loopBody = visitNode(node.statement, visitor, isStatement, liftToBlock);
|
||||
const statement = visitNode(node.statement, visitor, isStatement, liftToBlock);
|
||||
const lexicalEnvironment = endLexicalEnvironment();
|
||||
|
||||
const currentState = convertedLoopState;
|
||||
convertedLoopState = outerConvertedLoopState;
|
||||
const statements: Statement[] = [];
|
||||
if (shouldConvertConditionOfForStatement(node) || shouldConvertIncrementorOfForStatement(node)) {
|
||||
// If a block-scoped variable declared in the initializer of `node` is captured in
|
||||
// the condition or incrementor, we must move the condition and incrementor into
|
||||
// the body of the for loop.
|
||||
//
|
||||
// This transforms the following ES2015 syntax:
|
||||
//
|
||||
// for (let i = 0; setImmediate(() => console.log(i)), i < 2; setImmediate(() => console.log(i)), i++) {
|
||||
// // loop body
|
||||
// }
|
||||
//
|
||||
// Into the following ES5 syntax:
|
||||
//
|
||||
// var _loop_1 = function (i) {
|
||||
// if (inc_1)
|
||||
// setImmediate(() => console.log(i)), i++;
|
||||
// else
|
||||
// inc_1 = true;
|
||||
// if (!(setImmediate(() => console.log(i)), i < 2))
|
||||
// return out_i_1 = i, "break";
|
||||
// // loop body
|
||||
// out_i_1 = i;
|
||||
// }
|
||||
// var out_i_1, inc_1 = false;
|
||||
// for (var i = 0;;) {
|
||||
// var state_1 = _loop_1(i);
|
||||
// i = out_i_1;
|
||||
// if (state_1 === "break")
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// Which prevents mutations to `i` in the per-iteration environment of the body
|
||||
// from affecting the value of `i` in the previous per-iteration environment.
|
||||
//
|
||||
// Note that the incrementor of a `for` loop is evaluated in a *new* per-iteration
|
||||
// environment that is carried over to the next iteration of the loop. As a result,
|
||||
// we must indicate whether this is the first evaluation of the loop body so that
|
||||
// we only evaluate the incrementor on subsequent evaluations.
|
||||
|
||||
if (loopOutParameters.length || lexicalEnvironment) {
|
||||
const statements = isBlock(loopBody) ? loopBody.statements.slice() : [loopBody];
|
||||
if (loopOutParameters.length) {
|
||||
copyOutParameters(loopOutParameters, CopyDirection.ToOutParameter, statements);
|
||||
currentState.conditionVariable = createUniqueName("inc");
|
||||
statements.push(createIf(
|
||||
currentState.conditionVariable,
|
||||
createStatement(visitNode(node.incrementor, visitor, isExpression)),
|
||||
createStatement(createAssignment(currentState.conditionVariable, createTrue()))
|
||||
));
|
||||
|
||||
if (shouldConvertConditionOfForStatement(node)) {
|
||||
statements.push(createIf(
|
||||
createPrefix(SyntaxKind.ExclamationToken, visitNode(node.condition, visitor, isExpression)),
|
||||
visitNode(createBreak(), visitor, isStatement)
|
||||
));
|
||||
}
|
||||
addStatementsAfterPrologue(statements, lexicalEnvironment);
|
||||
loopBody = createBlock(statements, /*multiline*/ true);
|
||||
}
|
||||
|
||||
if (isBlock(loopBody)) {
|
||||
loopBody.multiLine = true;
|
||||
if (isBlock(statement)) {
|
||||
addRange(statements, statement.statements);
|
||||
}
|
||||
else {
|
||||
loopBody = createBlock([loopBody], /*multiline*/ true);
|
||||
statements.push(statement);
|
||||
}
|
||||
|
||||
copyOutParameters(currentState.loopOutParameters, LoopOutParameterFlags.Body, CopyDirection.ToOutParameter, statements);
|
||||
addStatementsAfterPrologue(statements, lexicalEnvironment);
|
||||
|
||||
const loopBody = createBlock(statements, /*multiLine*/ true);
|
||||
if (isBlock(statement)) setOriginalNode(loopBody, statement);
|
||||
|
||||
const containsYield = (node.statement.transformFlags & TransformFlags.ContainsYield) !== 0;
|
||||
const isAsyncBlockContainingAwait = containsYield && (hierarchyFacts & HierarchyFacts.AsyncFunctionBody) !== 0;
|
||||
|
||||
let loopBodyFlags: EmitFlags = 0;
|
||||
if (currentState.containsLexicalThis) {
|
||||
loopBodyFlags |= EmitFlags.CapturesThis;
|
||||
}
|
||||
let emitFlags: EmitFlags = 0;
|
||||
if (currentState.containsLexicalThis) emitFlags |= EmitFlags.CapturesThis;
|
||||
if (containsYield && (hierarchyFacts & HierarchyFacts.AsyncFunctionBody) !== 0) emitFlags |= EmitFlags.AsyncFunctionBody;
|
||||
|
||||
if (isAsyncBlockContainingAwait) {
|
||||
loopBodyFlags |= EmitFlags.AsyncFunctionBody;
|
||||
}
|
||||
// This transforms the following ES2015 syntax (in addition to other variations):
|
||||
//
|
||||
// for (let i = 0; i < 2; i++) {
|
||||
// setImmediate(() => console.log(i));
|
||||
// }
|
||||
//
|
||||
// Into the following ES5 syntax:
|
||||
//
|
||||
// var _loop_1 = function (i) {
|
||||
// setImmediate(() => console.log(i));
|
||||
// };
|
||||
// for (var i = 0; i < 2; i++) {
|
||||
// _loop_1(i);
|
||||
// }
|
||||
|
||||
const convertedLoopVariable =
|
||||
const functionDeclaration =
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
setEmitFlags(
|
||||
@@ -2762,11 +3145,11 @@ namespace ts {
|
||||
containsYield ? createToken(SyntaxKind.AsteriskToken) : undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
loopParameters,
|
||||
currentState.loopParameters,
|
||||
/*type*/ undefined,
|
||||
<Block>loopBody
|
||||
loopBody
|
||||
),
|
||||
loopBodyFlags
|
||||
emitFlags
|
||||
)
|
||||
)
|
||||
]
|
||||
@@ -2775,106 +3158,8 @@ namespace ts {
|
||||
)
|
||||
);
|
||||
|
||||
const statements: Statement[] = [convertedLoopVariable];
|
||||
|
||||
let extraVariableDeclarations: VariableDeclaration[] | undefined;
|
||||
// propagate state from the inner loop to the outer loop if necessary
|
||||
if (currentState.argumentsName) {
|
||||
// if alias for arguments is set
|
||||
if (outerConvertedLoopState) {
|
||||
// pass it to outer converted loop
|
||||
outerConvertedLoopState.argumentsName = currentState.argumentsName;
|
||||
}
|
||||
else {
|
||||
// this is top level converted loop and we need to create an alias for 'arguments' object
|
||||
(extraVariableDeclarations || (extraVariableDeclarations = [])).push(
|
||||
createVariableDeclaration(
|
||||
currentState.argumentsName,
|
||||
/*type*/ undefined,
|
||||
createIdentifier("arguments")
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentState.thisName) {
|
||||
// if alias for this is set
|
||||
if (outerConvertedLoopState) {
|
||||
// pass it to outer converted loop
|
||||
outerConvertedLoopState.thisName = currentState.thisName;
|
||||
}
|
||||
else {
|
||||
// this is top level converted loop so we need to create an alias for 'this' here
|
||||
// NOTE:
|
||||
// if converted loops were all nested in arrow function then we'll always emit '_this' so convertedLoopState.thisName will not be set.
|
||||
// If it is set this means that all nested loops are not nested in arrow function and it is safe to capture 'this'.
|
||||
(extraVariableDeclarations || (extraVariableDeclarations = [])).push(
|
||||
createVariableDeclaration(
|
||||
currentState.thisName,
|
||||
/*type*/ undefined,
|
||||
createIdentifier("this")
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentState.hoistedLocalVariables) {
|
||||
// if hoistedLocalVariables !== undefined this means that we've possibly collected some variable declarations to be hoisted later
|
||||
if (outerConvertedLoopState) {
|
||||
// pass them to outer converted loop
|
||||
outerConvertedLoopState.hoistedLocalVariables = currentState.hoistedLocalVariables;
|
||||
}
|
||||
else {
|
||||
if (!extraVariableDeclarations) {
|
||||
extraVariableDeclarations = [];
|
||||
}
|
||||
// hoist collected variable declarations
|
||||
for (const identifier of currentState.hoistedLocalVariables) {
|
||||
extraVariableDeclarations.push(createVariableDeclaration(identifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add extra variables to hold out parameters if necessary
|
||||
if (loopOutParameters.length) {
|
||||
if (!extraVariableDeclarations) {
|
||||
extraVariableDeclarations = [];
|
||||
}
|
||||
for (const outParam of loopOutParameters) {
|
||||
extraVariableDeclarations.push(createVariableDeclaration(outParam.outParamName));
|
||||
}
|
||||
}
|
||||
|
||||
// create variable statement to hold all introduced variable declarations
|
||||
if (extraVariableDeclarations) {
|
||||
statements.push(createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList(extraVariableDeclarations)
|
||||
));
|
||||
}
|
||||
|
||||
const convertedLoopBodyStatements = generateCallToConvertedLoop(functionName, loopParameters, currentState, containsYield);
|
||||
|
||||
let loop: Statement;
|
||||
if (convert) {
|
||||
loop = convert(node, outermostLabeledStatement, convertedLoopBodyStatements);
|
||||
}
|
||||
else {
|
||||
let clone = getMutableClone(node);
|
||||
// clean statement part
|
||||
clone.statement = undefined!;
|
||||
// visit childnodes to transform initializer/condition/incrementor parts
|
||||
clone = visitEachChild(clone, visitor, context);
|
||||
// set loop statement
|
||||
clone.statement = createBlock(convertedLoopBodyStatements, /*multiline*/ true);
|
||||
// reset and re-aggregate the transform flags
|
||||
clone.transformFlags = 0;
|
||||
aggregateTransformFlags(clone);
|
||||
loop = restoreEnclosingLabel(clone, outermostLabeledStatement, convertedLoopState && resetLabel);
|
||||
}
|
||||
|
||||
statements.push(loop);
|
||||
return statements;
|
||||
const part = generateCallToConvertedLoop(functionName, currentState, outerState, containsYield);
|
||||
return { functionName, containsYield, functionDeclaration, part };
|
||||
}
|
||||
|
||||
function copyOutParameter(outParam: LoopOutParameter, copyDirection: CopyDirection): BinaryExpression {
|
||||
@@ -2883,14 +3168,26 @@ namespace ts {
|
||||
return createBinary(target, SyntaxKind.EqualsToken, source);
|
||||
}
|
||||
|
||||
function copyOutParameters(outParams: LoopOutParameter[], copyDirection: CopyDirection, statements: Statement[]): void {
|
||||
function copyOutParameters(outParams: LoopOutParameter[], partFlags: LoopOutParameterFlags, copyDirection: CopyDirection, statements: Statement[]): void {
|
||||
for (const outParam of outParams) {
|
||||
statements.push(createExpressionStatement(copyOutParameter(outParam, copyDirection)));
|
||||
if (outParam.flags & partFlags) {
|
||||
statements.push(createExpressionStatement(copyOutParameter(outParam, copyDirection)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function generateCallToConvertedLoop(loopFunctionExpressionName: Identifier, parameters: ParameterDeclaration[], state: ConvertedLoopState, isAsyncBlockContainingAwait: boolean): Statement[] {
|
||||
const outerConvertedLoopState = convertedLoopState;
|
||||
function generateCallToConvertedLoopInitializer(initFunctionExpressionName: Identifier, containsYield: boolean): Statement {
|
||||
const call = createCall(initFunctionExpressionName, /*typeArguments*/ undefined, []);
|
||||
const callResult = containsYield
|
||||
? createYield(
|
||||
createToken(SyntaxKind.AsteriskToken),
|
||||
setEmitFlags(call, EmitFlags.Iterator)
|
||||
)
|
||||
: call;
|
||||
return createStatement(callResult);
|
||||
}
|
||||
|
||||
function generateCallToConvertedLoop(loopFunctionExpressionName: Identifier, state: ConvertedLoopState, outerState: ConvertedLoopState | undefined, containsYield: boolean): Statement[] {
|
||||
|
||||
const statements: Statement[] = [];
|
||||
// loop is considered simple if it does not have any return statements or break\continue that transfer control outside of the loop
|
||||
@@ -2901,8 +3198,8 @@ namespace ts {
|
||||
!state.labeledNonLocalBreaks &&
|
||||
!state.labeledNonLocalContinues;
|
||||
|
||||
const call = createCall(loopFunctionExpressionName, /*typeArguments*/ undefined, map(parameters, p => <Identifier>p.name));
|
||||
const callResult = isAsyncBlockContainingAwait
|
||||
const call = createCall(loopFunctionExpressionName, /*typeArguments*/ undefined, map(state.loopParameters, p => <Identifier>p.name));
|
||||
const callResult = containsYield
|
||||
? createYield(
|
||||
createToken(SyntaxKind.AsteriskToken),
|
||||
setEmitFlags(call, EmitFlags.Iterator)
|
||||
@@ -2910,7 +3207,7 @@ namespace ts {
|
||||
: call;
|
||||
if (isSimpleLoop) {
|
||||
statements.push(createExpressionStatement(callResult));
|
||||
copyOutParameters(state.loopOutParameters!, CopyDirection.ToOriginal, statements);
|
||||
copyOutParameters(state.loopOutParameters, LoopOutParameterFlags.Body, CopyDirection.ToOriginal, statements);
|
||||
}
|
||||
else {
|
||||
const loopResultName = createUniqueName("state");
|
||||
@@ -2921,12 +3218,12 @@ namespace ts {
|
||||
)
|
||||
);
|
||||
statements.push(stateVariable);
|
||||
copyOutParameters(state.loopOutParameters!, CopyDirection.ToOriginal, statements);
|
||||
copyOutParameters(state.loopOutParameters, LoopOutParameterFlags.Body, CopyDirection.ToOriginal, statements);
|
||||
|
||||
if (state.nonLocalJumps! & Jump.Return) {
|
||||
let returnStatement: ReturnStatement;
|
||||
if (outerConvertedLoopState) {
|
||||
outerConvertedLoopState.nonLocalJumps! |= Jump.Return;
|
||||
if (outerState) {
|
||||
outerState.nonLocalJumps! |= Jump.Return;
|
||||
returnStatement = createReturn(loopResultName);
|
||||
}
|
||||
else {
|
||||
@@ -2959,8 +3256,8 @@ namespace ts {
|
||||
|
||||
if (state.labeledNonLocalBreaks || state.labeledNonLocalContinues) {
|
||||
const caseClauses: CaseClause[] = [];
|
||||
processLabeledJumps(state.labeledNonLocalBreaks!, /*isBreak*/ true, loopResultName, outerConvertedLoopState, caseClauses);
|
||||
processLabeledJumps(state.labeledNonLocalContinues!, /*isBreak*/ false, loopResultName, outerConvertedLoopState, caseClauses);
|
||||
processLabeledJumps(state.labeledNonLocalBreaks!, /*isBreak*/ true, loopResultName, outerState, caseClauses);
|
||||
processLabeledJumps(state.labeledNonLocalContinues!, /*isBreak*/ false, loopResultName, outerState, caseClauses);
|
||||
statements.push(
|
||||
createSwitch(
|
||||
loopResultName,
|
||||
@@ -3008,20 +3305,28 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
function processLoopVariableDeclaration(decl: VariableDeclaration | BindingElement, loopParameters: ParameterDeclaration[], loopOutParameters: LoopOutParameter[]) {
|
||||
function processLoopVariableDeclaration(container: IterationStatement, decl: VariableDeclaration | BindingElement, loopParameters: ParameterDeclaration[], loopOutParameters: LoopOutParameter[], hasCapturedBindingsInForInitializer: boolean) {
|
||||
const name = decl.name;
|
||||
if (isBindingPattern(name)) {
|
||||
for (const element of name.elements) {
|
||||
if (!isOmittedExpression(element)) {
|
||||
processLoopVariableDeclaration(element, loopParameters, loopOutParameters);
|
||||
processLoopVariableDeclaration(container, element, loopParameters, loopOutParameters, hasCapturedBindingsInForInitializer);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
loopParameters.push(createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name));
|
||||
if (resolver.getNodeCheckFlags(decl) & NodeCheckFlags.NeedsLoopOutParameter) {
|
||||
const checkFlags = resolver.getNodeCheckFlags(decl);
|
||||
if (checkFlags & NodeCheckFlags.NeedsLoopOutParameter || hasCapturedBindingsInForInitializer) {
|
||||
const outParamName = createUniqueName("out_" + idText(name));
|
||||
loopOutParameters.push({ originalName: name, outParamName });
|
||||
let flags: LoopOutParameterFlags = 0;
|
||||
if (checkFlags & NodeCheckFlags.NeedsLoopOutParameter) {
|
||||
flags |= LoopOutParameterFlags.Body;
|
||||
}
|
||||
if (isForStatement(container) && container.initializer && resolver.isBindingCapturedByNode(container.initializer, decl)) {
|
||||
flags |= LoopOutParameterFlags.Initializer;
|
||||
}
|
||||
loopOutParameters.push({ flags, originalName: name, outParamName });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3442,7 +3747,7 @@ namespace ts {
|
||||
function visitCallExpressionWithPotentialCapturedThisAssignment(node: CallExpression, assignToCapturedThis: boolean): CallExpression | BinaryExpression {
|
||||
// We are here either because SuperKeyword was used somewhere in the expression, or
|
||||
// because we contain a SpreadElementExpression.
|
||||
if (node.transformFlags & TransformFlags.ContainsSpread ||
|
||||
if (node.transformFlags & TransformFlags.ContainsRestOrSpread ||
|
||||
node.expression.kind === SyntaxKind.SuperKeyword ||
|
||||
isSuperProperty(skipOuterExpressions(node.expression))) {
|
||||
|
||||
@@ -3452,7 +3757,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
let resultingCall: CallExpression | BinaryExpression;
|
||||
if (node.transformFlags & TransformFlags.ContainsSpread) {
|
||||
if (node.transformFlags & TransformFlags.ContainsRestOrSpread) {
|
||||
// [source]
|
||||
// f(...a, b)
|
||||
// x.m(...a, b)
|
||||
@@ -3515,7 +3820,7 @@ namespace ts {
|
||||
* @param node A NewExpression node.
|
||||
*/
|
||||
function visitNewExpression(node: NewExpression): LeftHandSideExpression {
|
||||
if (node.transformFlags & TransformFlags.ContainsSpread) {
|
||||
if (node.transformFlags & TransformFlags.ContainsRestOrSpread) {
|
||||
// We are here because we contain a SpreadElementExpression.
|
||||
// [source]
|
||||
// new C(...a)
|
||||
@@ -4089,7 +4394,7 @@ namespace ts {
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
}
|
||||
};
|
||||
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
|
||||
@@ -32,6 +32,15 @@ namespace ts {
|
||||
|
||||
let enclosingFunctionParameterNames: UnderscoreEscapedMap<true>;
|
||||
|
||||
/**
|
||||
* Keeps track of property names accessed on super (`super.x`) within async functions.
|
||||
*/
|
||||
let capturedSuperProperties: UnderscoreEscapedMap<true>;
|
||||
/** Whether the async function contains an element access on super (`super[x]`). */
|
||||
let hasSuperElementAccess: boolean;
|
||||
/** A set of node IDs for generated super accessors (variable statements). */
|
||||
const substitutedSuperAccessors: boolean[] = [];
|
||||
|
||||
// Save the previous transformation hooks.
|
||||
const previousOnEmitNode = context.onEmitNode;
|
||||
const previousOnSubstituteNode = context.onSubstituteNode;
|
||||
@@ -56,7 +65,6 @@ namespace ts {
|
||||
if ((node.transformFlags & TransformFlags.ContainsES2017) === 0) {
|
||||
return node;
|
||||
}
|
||||
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.AsyncKeyword:
|
||||
// ES2017 async modifier should be elided for targets < ES2017
|
||||
@@ -77,6 +85,18 @@ namespace ts {
|
||||
case SyntaxKind.ArrowFunction:
|
||||
return visitArrowFunction(<ArrowFunction>node);
|
||||
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
if (capturedSuperProperties && isPropertyAccessExpression(node) && node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
capturedSuperProperties.set(node.name.escapedText, true);
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
if (capturedSuperProperties && (<ElementAccessExpression>node).expression.kind === SyntaxKind.SuperKeyword) {
|
||||
hasSuperElementAccess = true;
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
|
||||
default:
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
@@ -398,6 +418,11 @@ namespace ts {
|
||||
recordDeclarationName(parameter, enclosingFunctionParameterNames);
|
||||
}
|
||||
|
||||
const savedCapturedSuperProperties = capturedSuperProperties;
|
||||
const savedHasSuperElementAccess = hasSuperElementAccess;
|
||||
capturedSuperProperties = createUnderscoreEscapedMap<true>();
|
||||
hasSuperElementAccess = false;
|
||||
|
||||
let result: ConciseBody;
|
||||
if (!isArrowFunction) {
|
||||
const statements: Statement[] = [];
|
||||
@@ -415,18 +440,26 @@ namespace ts {
|
||||
|
||||
addStatementsAfterPrologue(statements, endLexicalEnvironment());
|
||||
|
||||
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
|
||||
// This step isn't needed if we eventually transform this to ES5.
|
||||
const emitSuperHelpers = languageVersion >= ScriptTarget.ES2015 && resolver.getNodeCheckFlags(node) & (NodeCheckFlags.AsyncMethodWithSuperBinding | NodeCheckFlags.AsyncMethodWithSuper);
|
||||
|
||||
if (emitSuperHelpers) {
|
||||
enableSubstitutionForAsyncMethodsWithSuper();
|
||||
const variableStatement = createSuperAccessVariableStatement(resolver, node, capturedSuperProperties);
|
||||
substitutedSuperAccessors[getNodeId(variableStatement)] = true;
|
||||
addStatementsAfterPrologue(statements, [variableStatement]);
|
||||
}
|
||||
|
||||
const block = createBlock(statements, /*multiLine*/ true);
|
||||
setTextRange(block, node.body);
|
||||
|
||||
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
|
||||
// This step isn't needed if we eventually transform this to ES5.
|
||||
if (languageVersion >= ScriptTarget.ES2015) {
|
||||
if (emitSuperHelpers && hasSuperElementAccess) {
|
||||
// Emit helpers for super element access expressions (`super[x]`).
|
||||
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuperBinding) {
|
||||
enableSubstitutionForAsyncMethodsWithSuper();
|
||||
addEmitHelper(block, advancedAsyncSuperHelper);
|
||||
}
|
||||
else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuper) {
|
||||
enableSubstitutionForAsyncMethodsWithSuper();
|
||||
addEmitHelper(block, asyncSuperHelper);
|
||||
}
|
||||
}
|
||||
@@ -452,6 +485,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
enclosingFunctionParameterNames = savedEnclosingFunctionParameterNames;
|
||||
capturedSuperProperties = savedCapturedSuperProperties;
|
||||
hasSuperElementAccess = savedHasSuperElementAccess;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -493,6 +528,8 @@ namespace ts {
|
||||
context.enableEmitNotification(SyntaxKind.GetAccessor);
|
||||
context.enableEmitNotification(SyntaxKind.SetAccessor);
|
||||
context.enableEmitNotification(SyntaxKind.Constructor);
|
||||
// We need to be notified when entering the generated accessor arrow functions.
|
||||
context.enableEmitNotification(SyntaxKind.VariableStatement);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -516,6 +553,14 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Disable substitution in the generated super accessor itself.
|
||||
else if (enabledSubstitutions && substitutedSuperAccessors[getNodeId(node)]) {
|
||||
const savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
|
||||
enclosingSuperContainerFlags = 0;
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
|
||||
return;
|
||||
}
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
|
||||
@@ -548,8 +593,10 @@ namespace ts {
|
||||
|
||||
function substitutePropertyAccessExpression(node: PropertyAccessExpression) {
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
createLiteral(idText(node.name)),
|
||||
return setTextRange(
|
||||
createPropertyAccess(
|
||||
createFileLevelUniqueName("_super"),
|
||||
node.name),
|
||||
node
|
||||
);
|
||||
}
|
||||
@@ -558,7 +605,7 @@ namespace ts {
|
||||
|
||||
function substituteElementAccessExpression(node: ElementAccessExpression) {
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
return createSuperElementAccessInAsyncMethod(
|
||||
node.argumentExpression,
|
||||
node
|
||||
);
|
||||
@@ -593,12 +640,12 @@ namespace ts {
|
||||
|| kind === SyntaxKind.SetAccessor;
|
||||
}
|
||||
|
||||
function createSuperAccessInAsyncMethod(argumentExpression: Expression, location: TextRange): LeftHandSideExpression {
|
||||
function createSuperElementAccessInAsyncMethod(argumentExpression: Expression, location: TextRange): LeftHandSideExpression {
|
||||
if (enclosingSuperContainerFlags & NodeCheckFlags.AsyncMethodWithSuperBinding) {
|
||||
return setTextRange(
|
||||
createPropertyAccess(
|
||||
createCall(
|
||||
createFileLevelUniqueName("_super"),
|
||||
createFileLevelUniqueName("_superIndex"),
|
||||
/*typeArguments*/ undefined,
|
||||
[argumentExpression]
|
||||
),
|
||||
@@ -610,7 +657,7 @@ namespace ts {
|
||||
else {
|
||||
return setTextRange(
|
||||
createCall(
|
||||
createFileLevelUniqueName("_super"),
|
||||
createFileLevelUniqueName("_superIndex"),
|
||||
/*typeArguments*/ undefined,
|
||||
[argumentExpression]
|
||||
),
|
||||
@@ -620,6 +667,89 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/** Creates a variable named `_super` with accessor properties for the given property names. */
|
||||
export function createSuperAccessVariableStatement(resolver: EmitResolver, node: FunctionLikeDeclaration, names: UnderscoreEscapedMap<true>) {
|
||||
// Create a variable declaration with a getter/setter (if binding) definition for each name:
|
||||
// const _super = Object.create(null, { x: { get: () => super.x, set: (v) => super.x = v }, ... });
|
||||
const hasBinding = (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuperBinding) !== 0;
|
||||
const accessors: PropertyAssignment[] = [];
|
||||
names.forEach((_, key) => {
|
||||
const name = unescapeLeadingUnderscores(key);
|
||||
const getterAndSetter: PropertyAssignment[] = [];
|
||||
getterAndSetter.push(createPropertyAssignment(
|
||||
"get",
|
||||
createArrowFunction(
|
||||
/* modifiers */ undefined,
|
||||
/* typeParameters */ undefined,
|
||||
/* parameters */ [],
|
||||
/* type */ undefined,
|
||||
/* equalsGreaterThanToken */ undefined,
|
||||
createPropertyAccess(
|
||||
createSuper(),
|
||||
name
|
||||
)
|
||||
)
|
||||
));
|
||||
if (hasBinding) {
|
||||
getterAndSetter.push(
|
||||
createPropertyAssignment(
|
||||
"set",
|
||||
createArrowFunction(
|
||||
/* modifiers */ undefined,
|
||||
/* typeParameters */ undefined,
|
||||
/* parameters */ [
|
||||
createParameter(
|
||||
/* decorators */ undefined,
|
||||
/* modifiers */ undefined,
|
||||
/* dotDotDotToken */ undefined,
|
||||
"v",
|
||||
/* questionToken */ undefined,
|
||||
/* type */ undefined,
|
||||
/* initializer */ undefined
|
||||
)
|
||||
],
|
||||
/* type */ undefined,
|
||||
/* equalsGreaterThanToken */ undefined,
|
||||
createAssignment(
|
||||
createPropertyAccess(
|
||||
createSuper(),
|
||||
name),
|
||||
createIdentifier("v")
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
accessors.push(
|
||||
createPropertyAssignment(
|
||||
name,
|
||||
createObjectLiteral(getterAndSetter),
|
||||
)
|
||||
);
|
||||
});
|
||||
return createVariableStatement(
|
||||
/* modifiers */ undefined,
|
||||
createVariableDeclarationList(
|
||||
[
|
||||
createVariableDeclaration(
|
||||
createFileLevelUniqueName("_super"),
|
||||
/* type */ undefined,
|
||||
createCall(
|
||||
createPropertyAccess(
|
||||
createIdentifier("Object"),
|
||||
"create"
|
||||
),
|
||||
/* typeArguments */ undefined,
|
||||
[
|
||||
createNull(),
|
||||
createObjectLiteral(accessors, /* multiline */ true)
|
||||
]
|
||||
)
|
||||
)
|
||||
],
|
||||
NodeFlags.Const));
|
||||
}
|
||||
|
||||
const awaiterHelper: EmitHelper = {
|
||||
name: "typescript:awaiter",
|
||||
scoped: false,
|
||||
@@ -667,14 +797,14 @@ namespace ts {
|
||||
name: "typescript:async-super",
|
||||
scoped: true,
|
||||
text: helperString`
|
||||
const ${"_super"} = name => super[name];`
|
||||
const ${"_superIndex"} = name => super[name];`
|
||||
};
|
||||
|
||||
export const advancedAsyncSuperHelper: EmitHelper = {
|
||||
name: "typescript:advanced-async-super",
|
||||
scoped: true,
|
||||
text: helperString`
|
||||
const ${"_super"} = (function (geti, seti) {
|
||||
const ${"_superIndex"} = (function (geti, seti) {
|
||||
const cache = Object.create(null);
|
||||
return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });
|
||||
})(name => super[name], (name, value) => super[name] = value);`
|
||||
|
||||
@@ -26,6 +26,13 @@ namespace ts {
|
||||
let enclosingFunctionFlags: FunctionFlags;
|
||||
let enclosingSuperContainerFlags: NodeCheckFlags = 0;
|
||||
|
||||
/** Keeps track of property names accessed on super (`super.x`) within async functions. */
|
||||
let capturedSuperProperties: UnderscoreEscapedMap<true>;
|
||||
/** Whether the async function contains an element access on super (`super[x]`). */
|
||||
let hasSuperElementAccess: boolean;
|
||||
/** A set of node IDs for generated super accessors. */
|
||||
const substitutedSuperAccessors: boolean[] = [];
|
||||
|
||||
return chainBundle(transformSourceFile);
|
||||
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
@@ -57,7 +64,6 @@ namespace ts {
|
||||
if ((node.transformFlags & TransformFlags.ContainsESNext) === 0) {
|
||||
return node;
|
||||
}
|
||||
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.AwaitExpression:
|
||||
return visitAwaitExpression(node as AwaitExpression);
|
||||
@@ -101,6 +107,16 @@ namespace ts {
|
||||
return visitParenthesizedExpression(node as ParenthesizedExpression, noDestructuringValue);
|
||||
case SyntaxKind.CatchClause:
|
||||
return visitCatchClause(node as CatchClause);
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
if (capturedSuperProperties && isPropertyAccessExpression(node) && node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
capturedSuperProperties.set(node.name.escapedText, true);
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
if (capturedSuperProperties && (<ElementAccessExpression>node).expression.kind === SyntaxKind.SuperKeyword) {
|
||||
hasSuperElementAccess = true;
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
default:
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
@@ -210,7 +226,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function visitObjectLiteralExpression(node: ObjectLiteralExpression): Expression {
|
||||
if (node.transformFlags & TransformFlags.ContainsObjectSpread) {
|
||||
if (node.transformFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
// spread elements emit like so:
|
||||
// non-spread elements are chunked together into object literals, and then all are passed to __assign:
|
||||
// { a, ...o, b } => __assign({a}, o, {b});
|
||||
@@ -250,7 +266,7 @@ namespace ts {
|
||||
* @param node A BinaryExpression node.
|
||||
*/
|
||||
function visitBinaryExpression(node: BinaryExpression, noDestructuringValue: boolean): Expression {
|
||||
if (isDestructuringAssignment(node) && node.left.transformFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (isDestructuringAssignment(node) && node.left.transformFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
return flattenDestructuringAssignment(
|
||||
node,
|
||||
visitor,
|
||||
@@ -276,7 +292,7 @@ namespace ts {
|
||||
*/
|
||||
function visitVariableDeclaration(node: VariableDeclaration): VisitResult<VariableDeclaration> {
|
||||
// If we are here it is because the name contains a binding pattern with a rest somewhere in it.
|
||||
if (isBindingPattern(node.name) && node.name.transformFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (isBindingPattern(node.name) && node.name.transformFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
return flattenDestructuringBinding(
|
||||
node,
|
||||
visitor,
|
||||
@@ -307,7 +323,7 @@ namespace ts {
|
||||
* @param node A ForOfStatement.
|
||||
*/
|
||||
function visitForOfStatement(node: ForOfStatement, outermostLabeledStatement: LabeledStatement | undefined): VisitResult<Statement> {
|
||||
if (node.initializer.transformFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (node.initializer.transformFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
node = transformForOfStatementWithObjectRest(node);
|
||||
}
|
||||
if (node.awaitModifier) {
|
||||
@@ -499,7 +515,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function visitParameter(node: ParameterDeclaration): ParameterDeclaration {
|
||||
if (node.transformFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (node.transformFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
// Binding patterns are converted into a generated name and are
|
||||
// evaluated inside the function body.
|
||||
return updateParameter(
|
||||
@@ -655,41 +671,57 @@ namespace ts {
|
||||
const statementOffset = addPrologue(statements, node.body!.statements, /*ensureUseStrict*/ false, visitor);
|
||||
appendObjectRestAssignmentsIfNeeded(statements, node);
|
||||
|
||||
statements.push(
|
||||
createReturn(
|
||||
createAsyncGeneratorHelper(
|
||||
context,
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
createToken(SyntaxKind.AsteriskToken),
|
||||
node.name && getGeneratedNameForNode(node.name),
|
||||
/*typeParameters*/ undefined,
|
||||
/*parameters*/ [],
|
||||
/*type*/ undefined,
|
||||
updateBlock(
|
||||
node.body!,
|
||||
visitLexicalEnvironment(node.body!.statements, visitor, context, statementOffset)
|
||||
)
|
||||
const savedCapturedSuperProperties = capturedSuperProperties;
|
||||
const savedHasSuperElementAccess = hasSuperElementAccess;
|
||||
capturedSuperProperties = createUnderscoreEscapedMap<true>();
|
||||
hasSuperElementAccess = false;
|
||||
|
||||
const returnStatement = createReturn(
|
||||
createAsyncGeneratorHelper(
|
||||
context,
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
createToken(SyntaxKind.AsteriskToken),
|
||||
node.name && getGeneratedNameForNode(node.name),
|
||||
/*typeParameters*/ undefined,
|
||||
/*parameters*/ [],
|
||||
/*type*/ undefined,
|
||||
updateBlock(
|
||||
node.body!,
|
||||
visitLexicalEnvironment(node.body!.statements, visitor, context, statementOffset)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
|
||||
// This step isn't needed if we eventually transform this to ES5.
|
||||
const emitSuperHelpers = languageVersion >= ScriptTarget.ES2015 && resolver.getNodeCheckFlags(node) & (NodeCheckFlags.AsyncMethodWithSuperBinding | NodeCheckFlags.AsyncMethodWithSuper);
|
||||
|
||||
if (emitSuperHelpers) {
|
||||
enableSubstitutionForAsyncMethodsWithSuper();
|
||||
const variableStatement = createSuperAccessVariableStatement(resolver, node, capturedSuperProperties);
|
||||
substitutedSuperAccessors[getNodeId(variableStatement)] = true;
|
||||
addStatementsAfterPrologue(statements, [variableStatement]);
|
||||
}
|
||||
|
||||
statements.push(returnStatement);
|
||||
|
||||
addStatementsAfterPrologue(statements, endLexicalEnvironment());
|
||||
const block = updateBlock(node.body!, statements);
|
||||
|
||||
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
|
||||
// This step isn't needed if we eventually transform this to ES5.
|
||||
if (languageVersion >= ScriptTarget.ES2015) {
|
||||
if (emitSuperHelpers && hasSuperElementAccess) {
|
||||
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuperBinding) {
|
||||
enableSubstitutionForAsyncMethodsWithSuper();
|
||||
addEmitHelper(block, advancedAsyncSuperHelper);
|
||||
}
|
||||
else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuper) {
|
||||
enableSubstitutionForAsyncMethodsWithSuper();
|
||||
addEmitHelper(block, asyncSuperHelper);
|
||||
}
|
||||
}
|
||||
|
||||
capturedSuperProperties = savedCapturedSuperProperties;
|
||||
hasSuperElementAccess = savedHasSuperElementAccess;
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
@@ -716,7 +748,7 @@ namespace ts {
|
||||
|
||||
function appendObjectRestAssignmentsIfNeeded(statements: Statement[] | undefined, node: FunctionLikeDeclaration): Statement[] | undefined {
|
||||
for (const parameter of node.parameters) {
|
||||
if (parameter.transformFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (parameter.transformFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
const temp = getGeneratedNameForNode(parameter);
|
||||
const declarations = flattenDestructuringBinding(
|
||||
parameter,
|
||||
@@ -758,6 +790,8 @@ namespace ts {
|
||||
context.enableEmitNotification(SyntaxKind.GetAccessor);
|
||||
context.enableEmitNotification(SyntaxKind.SetAccessor);
|
||||
context.enableEmitNotification(SyntaxKind.Constructor);
|
||||
// We need to be notified when entering the generated accessor arrow functions.
|
||||
context.enableEmitNotification(SyntaxKind.VariableStatement);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -781,6 +815,14 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Disable substitution in the generated super accessor itself.
|
||||
else if (enabledSubstitutions && substitutedSuperAccessors[getNodeId(node)]) {
|
||||
const savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
|
||||
enclosingSuperContainerFlags = 0 as NodeCheckFlags;
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
|
||||
return;
|
||||
}
|
||||
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
@@ -813,8 +855,10 @@ namespace ts {
|
||||
|
||||
function substitutePropertyAccessExpression(node: PropertyAccessExpression) {
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
createLiteral(idText(node.name)),
|
||||
return setTextRange(
|
||||
createPropertyAccess(
|
||||
createFileLevelUniqueName("_super"),
|
||||
node.name),
|
||||
node
|
||||
);
|
||||
}
|
||||
@@ -823,7 +867,7 @@ namespace ts {
|
||||
|
||||
function substituteElementAccessExpression(node: ElementAccessExpression) {
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
return createSuperElementAccessInAsyncMethod(
|
||||
node.argumentExpression,
|
||||
node
|
||||
);
|
||||
@@ -858,12 +902,12 @@ namespace ts {
|
||||
|| kind === SyntaxKind.SetAccessor;
|
||||
}
|
||||
|
||||
function createSuperAccessInAsyncMethod(argumentExpression: Expression, location: TextRange): LeftHandSideExpression {
|
||||
function createSuperElementAccessInAsyncMethod(argumentExpression: Expression, location: TextRange): LeftHandSideExpression {
|
||||
if (enclosingSuperContainerFlags & NodeCheckFlags.AsyncMethodWithSuperBinding) {
|
||||
return setTextRange(
|
||||
createPropertyAccess(
|
||||
createCall(
|
||||
createIdentifier("_super"),
|
||||
createIdentifier("_superIndex"),
|
||||
/*typeArguments*/ undefined,
|
||||
[argumentExpression]
|
||||
),
|
||||
@@ -875,7 +919,7 @@ namespace ts {
|
||||
else {
|
||||
return setTextRange(
|
||||
createCall(
|
||||
createIdentifier("_super"),
|
||||
createIdentifier("_superIndex"),
|
||||
/*typeArguments*/ undefined,
|
||||
[argumentExpression]
|
||||
),
|
||||
|
||||
@@ -53,7 +53,10 @@ namespace ts {
|
||||
* @param node The SourceFile node.
|
||||
*/
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
if (node.isDeclarationFile || !(isEffectiveExternalModule(node, compilerOptions) || node.transformFlags & TransformFlags.ContainsDynamicImport)) {
|
||||
if (node.isDeclarationFile ||
|
||||
!(isEffectiveExternalModule(node, compilerOptions) ||
|
||||
node.transformFlags & TransformFlags.ContainsDynamicImport ||
|
||||
(isJsonSourceFile(node) && hasJsonModuleEmitEnabled(compilerOptions) && (compilerOptions.out || compilerOptions.outFile)))) {
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -117,6 +120,7 @@ namespace ts {
|
||||
function transformAMDModule(node: SourceFile) {
|
||||
const define = createIdentifier("define");
|
||||
const moduleName = tryGetModuleNameFromFile(node, host, compilerOptions);
|
||||
const jsonSourceFile = isJsonSourceFile(node) && node;
|
||||
|
||||
// An AMD define function has the following shape:
|
||||
//
|
||||
@@ -158,7 +162,7 @@ namespace ts {
|
||||
// Add the dependency array argument:
|
||||
//
|
||||
// ["require", "exports", module1", "module2", ...]
|
||||
createArrayLiteral([
|
||||
createArrayLiteral(jsonSourceFile ? emptyArray : [
|
||||
createLiteral("require"),
|
||||
createLiteral("exports"),
|
||||
...aliasedModuleNames,
|
||||
@@ -168,7 +172,9 @@ namespace ts {
|
||||
// Add the module body function argument:
|
||||
//
|
||||
// function (require, exports, module1, module2) ...
|
||||
createFunctionExpression(
|
||||
jsonSourceFile ?
|
||||
jsonSourceFile.statements.length ? jsonSourceFile.statements[0].expression : createObjectLiteral() :
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
|
||||
@@ -973,9 +973,11 @@ namespace ts {
|
||||
// Check if we have property assignment inside class declaration.
|
||||
// If there is a property assignment, we need to emit constructor whether users define it or not
|
||||
// If there is no property assignment, we can omit constructor if users do not define it
|
||||
const hasInstancePropertyWithInitializer = forEach(node.members, isInstanceInitializedProperty);
|
||||
const hasParameterPropertyAssignments = node.transformFlags & TransformFlags.ContainsParameterPropertyAssignments;
|
||||
const constructor = getFirstConstructorWithBody(node);
|
||||
const hasInstancePropertyWithInitializer = forEach(node.members, isInstanceInitializedProperty);
|
||||
const hasParameterPropertyAssignments = constructor &&
|
||||
constructor.transformFlags & TransformFlags.ContainsTypeScriptClassSyntax &&
|
||||
forEach(constructor.parameters, isParameterWithPropertyAssignment);
|
||||
|
||||
// If the class does not contain nodes that require a synthesized constructor,
|
||||
// accept the current constructor if it exists.
|
||||
@@ -1899,6 +1901,9 @@ namespace ts {
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return createIdentifier("Number");
|
||||
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
return getGlobalBigIntNameWithFallback();
|
||||
|
||||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
return createIdentifier("Boolean");
|
||||
@@ -1910,6 +1915,9 @@ namespace ts {
|
||||
case SyntaxKind.NumberKeyword:
|
||||
return createIdentifier("Number");
|
||||
|
||||
case SyntaxKind.BigIntKeyword:
|
||||
return getGlobalBigIntNameWithFallback();
|
||||
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
return languageVersion < ScriptTarget.ES2015
|
||||
? getGlobalSymbolNameWithFallback()
|
||||
@@ -1920,7 +1928,10 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.IntersectionType:
|
||||
case SyntaxKind.UnionType:
|
||||
return serializeUnionOrIntersectionType(<UnionOrIntersectionTypeNode>node);
|
||||
return serializeTypeList((<UnionOrIntersectionTypeNode>node).types);
|
||||
|
||||
case SyntaxKind.ConditionalType:
|
||||
return serializeTypeList([(<ConditionalTypeNode>node).trueType, (<ConditionalTypeNode>node).falseType]);
|
||||
|
||||
case SyntaxKind.TypeQuery:
|
||||
case SyntaxKind.TypeOperator:
|
||||
@@ -1933,6 +1944,7 @@ namespace ts {
|
||||
case SyntaxKind.ImportType:
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
return Debug.failBadSyntaxKind(node);
|
||||
}
|
||||
@@ -1940,11 +1952,11 @@ namespace ts {
|
||||
return createIdentifier("Object");
|
||||
}
|
||||
|
||||
function serializeUnionOrIntersectionType(node: UnionOrIntersectionTypeNode): SerializedTypeNode {
|
||||
function serializeTypeList(types: ReadonlyArray<TypeNode>): SerializedTypeNode {
|
||||
// Note when updating logic here also update getEntityNameForDecoratorMetadata
|
||||
// so that aliases can be marked as referenced
|
||||
let serializedUnion: SerializedTypeNode | undefined;
|
||||
for (let typeNode of node.types) {
|
||||
for (let typeNode of types) {
|
||||
while (typeNode.kind === SyntaxKind.ParenthesizedType) {
|
||||
typeNode = (typeNode as ParenthesizedTypeNode).type; // Skip parens if need be
|
||||
}
|
||||
@@ -1990,6 +2002,11 @@ namespace ts {
|
||||
const kind = resolver.getTypeReferenceSerializationKind(node.typeName, currentNameScope || currentLexicalScope);
|
||||
switch (kind) {
|
||||
case TypeReferenceSerializationKind.Unknown:
|
||||
// From conditional type type reference that cannot be resolved is Similar to any or unknown
|
||||
if (findAncestor(node, n => n.parent && isConditionalTypeNode(n.parent) && (n.parent.trueType === n || n.parent.falseType === n))) {
|
||||
return createIdentifier("Object");
|
||||
}
|
||||
|
||||
const serialized = serializeEntityNameAsExpressionFallback(node.typeName);
|
||||
const temp = createTempVariable(hoistVariableDeclaration);
|
||||
return createConditional(
|
||||
@@ -2004,6 +2021,9 @@ namespace ts {
|
||||
case TypeReferenceSerializationKind.VoidNullableOrNeverType:
|
||||
return createVoidZero();
|
||||
|
||||
case TypeReferenceSerializationKind.BigIntLikeType:
|
||||
return getGlobalBigIntNameWithFallback();
|
||||
|
||||
case TypeReferenceSerializationKind.BooleanType:
|
||||
return createIdentifier("Boolean");
|
||||
|
||||
@@ -2113,6 +2133,20 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an expression that points to the global "BigInt" constructor at runtime if it is
|
||||
* available.
|
||||
*/
|
||||
function getGlobalBigIntNameWithFallback(): SerializedTypeNode {
|
||||
return languageVersion < ScriptTarget.ESNext
|
||||
? createConditional(
|
||||
createTypeCheck(createIdentifier("BigInt"), "function"),
|
||||
createIdentifier("BigInt"),
|
||||
createIdentifier("Object")
|
||||
)
|
||||
: createIdentifier("BigInt");
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple inlinable expression is an expression which can be copied into multiple locations
|
||||
* without risk of repeating any sideeffects and whose value could not possibly change between
|
||||
|
||||
+815
-726
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,7 @@
|
||||
"files": [
|
||||
"core.ts",
|
||||
"performance.ts",
|
||||
"semver.ts",
|
||||
|
||||
"types.ts",
|
||||
"sys.ts",
|
||||
@@ -24,7 +25,7 @@
|
||||
"checker.ts",
|
||||
"factory.ts",
|
||||
"visitor.ts",
|
||||
"sourcemapDecoder.ts",
|
||||
"sourcemap.ts",
|
||||
"transformers/utilities.ts",
|
||||
"transformers/destructuring.ts",
|
||||
"transformers/ts.ts",
|
||||
@@ -41,8 +42,6 @@
|
||||
"transformers/declarations/diagnostics.ts",
|
||||
"transformers/declarations.ts",
|
||||
"transformer.ts",
|
||||
"sourcemap.ts",
|
||||
"comments.ts",
|
||||
"emitter.ts",
|
||||
"watchUtilities.ts",
|
||||
"program.ts",
|
||||
@@ -51,6 +50,7 @@
|
||||
"resolutionCache.ts",
|
||||
"moduleSpecifiers.ts",
|
||||
"watch.ts",
|
||||
"tsbuild.ts"
|
||||
"tsbuild.ts",
|
||||
"inspectValue.ts",
|
||||
]
|
||||
}
|
||||
|
||||
+455
-173
File diff suppressed because it is too large
Load Diff
+666
-270
File diff suppressed because it is too large
Load Diff
@@ -1111,6 +1111,7 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
result = reduceNode((<TaggedTemplateExpression>node).tag, cbNode, result);
|
||||
result = reduceNodes((<TaggedTemplateExpression>node).typeArguments, cbNodes, result);
|
||||
result = reduceNode((<TaggedTemplateExpression>node).template, cbNode, result);
|
||||
break;
|
||||
|
||||
@@ -1377,6 +1378,7 @@ namespace ts {
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
result = reduceNode((<JsxSelfClosingElement | JsxOpeningElement>node).tagName, cbNode, result);
|
||||
result = reduceNodes((<JsxSelfClosingElement | JsxOpeningElement>node).typeArguments, cbNode, result);
|
||||
result = reduceNode((<JsxSelfClosingElement | JsxOpeningElement>node).attributes, cbNode, result);
|
||||
break;
|
||||
|
||||
|
||||
+101
-68
@@ -27,12 +27,6 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export const nonClearingMessageCodes: number[] = [
|
||||
Diagnostics.Found_1_error_Watching_for_file_changes.code,
|
||||
Diagnostics.Found_0_errors_Watching_for_file_changes.code
|
||||
];
|
||||
|
||||
/**
|
||||
* @returns Whether the screen was cleared.
|
||||
*/
|
||||
@@ -41,7 +35,7 @@ namespace ts {
|
||||
!options.preserveWatchOutput &&
|
||||
!options.extendedDiagnostics &&
|
||||
!options.diagnostics &&
|
||||
!contains(nonClearingMessageCodes, diagnostic.code)) {
|
||||
contains(screenStartingMessageCodes, diagnostic.code)) {
|
||||
system.clearScreen();
|
||||
return true;
|
||||
}
|
||||
@@ -49,7 +43,6 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export const screenStartingMessageCodes: number[] = [
|
||||
Diagnostics.Starting_compilation_in_watch_mode.code,
|
||||
Diagnostics.File_change_detected_Starting_incremental_compilation.code,
|
||||
@@ -107,15 +100,31 @@ namespace ts {
|
||||
getGlobalDiagnostics(): ReadonlyArray<Diagnostic>;
|
||||
getSemanticDiagnostics(): ReadonlyArray<Diagnostic>;
|
||||
getConfigFileParsingDiagnostics(): ReadonlyArray<Diagnostic>;
|
||||
emit(): EmitResult;
|
||||
emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback): EmitResult;
|
||||
}
|
||||
|
||||
export type ReportEmitErrorSummary = (errorCount: number) => void;
|
||||
|
||||
export function getErrorCountForSummary(diagnostics: ReadonlyArray<Diagnostic>) {
|
||||
return countWhere(diagnostics, diagnostic => diagnostic.category === DiagnosticCategory.Error);
|
||||
}
|
||||
|
||||
export function getWatchErrorSummaryDiagnosticMessage(errorCount: number) {
|
||||
return errorCount === 1 ?
|
||||
Diagnostics.Found_1_error_Watching_for_file_changes :
|
||||
Diagnostics.Found_0_errors_Watching_for_file_changes;
|
||||
}
|
||||
|
||||
export function getErrorSummaryText(errorCount: number, newLine: string) {
|
||||
if (errorCount === 0) return "";
|
||||
const d = createCompilerDiagnostic(errorCount === 1 ? Diagnostics.Found_1_error : Diagnostics.Found_0_errors, errorCount);
|
||||
return `${newLine}${flattenDiagnosticMessageText(d.messageText, newLine)}${newLine}${newLine}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper that emit files, report diagnostics and lists emitted and/or source files depending on compiler options
|
||||
*/
|
||||
export function emitFilesAndReportErrors(program: ProgramToEmitFilesAndReportErrors, reportDiagnostic: DiagnosticReporter, writeFileName?: (s: string) => void, reportSummary?: ReportEmitErrorSummary) {
|
||||
export function emitFilesAndReportErrors(program: ProgramToEmitFilesAndReportErrors, reportDiagnostic: DiagnosticReporter, writeFileName?: (s: string) => void, reportSummary?: ReportEmitErrorSummary, writeFile?: WriteFileCallback) {
|
||||
// First get and report any syntactic errors.
|
||||
const diagnostics = program.getConfigFileParsingDiagnostics().slice();
|
||||
const configFileParsingDiagnosticsLength = diagnostics.length;
|
||||
@@ -134,7 +143,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Emit and report any errors we ran into.
|
||||
const { emittedFiles, emitSkipped, diagnostics: emitDiagnostics } = program.emit();
|
||||
const { emittedFiles, emitSkipped, diagnostics: emitDiagnostics } = program.emit(/*targetSourceFile*/ undefined, writeFile);
|
||||
addRange(diagnostics, emitDiagnostics);
|
||||
|
||||
if (reportSemanticDiagnostics) {
|
||||
@@ -157,7 +166,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (reportSummary) {
|
||||
reportSummary(diagnostics.filter(diagnostic => diagnostic.category === DiagnosticCategory.Error).length);
|
||||
reportSummary(getErrorCountForSummary(diagnostics));
|
||||
}
|
||||
|
||||
if (emitSkipped && diagnostics.length > 0) {
|
||||
@@ -174,6 +183,17 @@ namespace ts {
|
||||
|
||||
const noopFileWatcher: FileWatcher = { close: noop };
|
||||
|
||||
export function createWatchHost(system = sys, reportWatchStatus?: WatchStatusReporter): WatchHost {
|
||||
const onWatchStatusChange = reportWatchStatus || createWatchStatusReporter(system);
|
||||
return {
|
||||
onWatchStatusChange,
|
||||
watchFile: system.watchFile ? ((path, callback, pollingInterval) => system.watchFile!(path, callback, pollingInterval)) : () => noopFileWatcher,
|
||||
watchDirectory: system.watchDirectory ? ((path, callback, recursive) => system.watchDirectory!(path, callback, recursive)) : () => noopFileWatcher,
|
||||
setTimeout: system.setTimeout ? ((callback, ms, ...args: any[]) => system.setTimeout!.call(system, callback, ms, ...args)) : noop,
|
||||
clearTimeout: system.clearTimeout ? (timeoutId => system.clearTimeout!(timeoutId)) : noop
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the watch compiler host that can be extended with config file or root file names and options host
|
||||
*/
|
||||
@@ -183,9 +203,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
let host: DirectoryStructureHost = system;
|
||||
host; // tslint:disable-line no-unused-expression (TODO: `host` is unused!)
|
||||
const useCaseSensitiveFileNames = () => system.useCaseSensitiveFileNames;
|
||||
const writeFileName = (s: string) => system.write(s + system.newLine);
|
||||
const onWatchStatusChange = reportWatchStatus || createWatchStatusReporter(system);
|
||||
const { onWatchStatusChange, watchFile, watchDirectory, setTimeout, clearTimeout } = createWatchHost(system, reportWatchStatus);
|
||||
return {
|
||||
useCaseSensitiveFileNames,
|
||||
getNewLine: () => system.newLine,
|
||||
@@ -199,10 +220,10 @@ namespace ts {
|
||||
readDirectory: (path, extensions, exclude, include, depth) => system.readDirectory(path, extensions, exclude, include, depth),
|
||||
realpath: system.realpath && (path => system.realpath!(path)),
|
||||
getEnvironmentVariable: system.getEnvironmentVariable && (name => system.getEnvironmentVariable(name)),
|
||||
watchFile: system.watchFile ? ((path, callback, pollingInterval) => system.watchFile!(path, callback, pollingInterval)) : () => noopFileWatcher,
|
||||
watchDirectory: system.watchDirectory ? ((path, callback, recursive) => system.watchDirectory!(path, callback, recursive)) : () => noopFileWatcher,
|
||||
setTimeout: system.setTimeout ? ((callback, ms, ...args: any[]) => system.setTimeout!.call(system, callback, ms, ...args)) : noop,
|
||||
clearTimeout: system.clearTimeout ? (timeoutId => system.clearTimeout!(timeoutId)) : noop,
|
||||
watchFile,
|
||||
watchDirectory,
|
||||
setTimeout,
|
||||
clearTimeout,
|
||||
trace: s => system.write(s),
|
||||
onWatchStatusChange,
|
||||
createDirectory: path => system.createDirectory(path),
|
||||
@@ -221,16 +242,16 @@ namespace ts {
|
||||
const compilerOptions = builderProgram.getCompilerOptions();
|
||||
const newLine = getNewLineCharacter(compilerOptions, () => system.newLine);
|
||||
|
||||
const reportSummary = (errorCount: number) => {
|
||||
if (errorCount === 1) {
|
||||
onWatchStatusChange(createCompilerDiagnostic(Diagnostics.Found_1_error_Watching_for_file_changes, errorCount), newLine, compilerOptions);
|
||||
}
|
||||
else {
|
||||
onWatchStatusChange(createCompilerDiagnostic(Diagnostics.Found_0_errors_Watching_for_file_changes, errorCount, errorCount), newLine, compilerOptions);
|
||||
}
|
||||
};
|
||||
|
||||
emitFilesAndReportErrors(builderProgram, reportDiagnostic, writeFileName, reportSummary);
|
||||
emitFilesAndReportErrors(
|
||||
builderProgram,
|
||||
reportDiagnostic,
|
||||
writeFileName,
|
||||
errorCount => onWatchStatusChange!(
|
||||
createCompilerDiagnostic(getWatchErrorSummaryDiagnosticMessage(errorCount), errorCount),
|
||||
newLine,
|
||||
compilerOptions
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,10 +278,11 @@ namespace ts {
|
||||
/**
|
||||
* Creates the watch compiler host from system for compiling root files and options in watch mode
|
||||
*/
|
||||
export function createWatchCompilerHostOfFilesAndCompilerOptions<T extends BuilderProgram = EmitAndSemanticDiagnosticsBuilderProgram>(rootFiles: string[], options: CompilerOptions, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfFilesAndCompilerOptions<T> {
|
||||
export function createWatchCompilerHostOfFilesAndCompilerOptions<T extends BuilderProgram = EmitAndSemanticDiagnosticsBuilderProgram>(rootFiles: string[], options: CompilerOptions, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter, projectReferences?: ReadonlyArray<ProjectReference>): WatchCompilerHostOfFilesAndCompilerOptions<T> {
|
||||
const host = createWatchCompilerHost(system, createProgram, reportDiagnostic || createDiagnosticReporter(system), reportWatchStatus) as WatchCompilerHostOfFilesAndCompilerOptions<T>;
|
||||
host.rootFiles = rootFiles;
|
||||
host.options = options;
|
||||
host.projectReferences = projectReferences;
|
||||
return host;
|
||||
}
|
||||
}
|
||||
@@ -268,8 +290,22 @@ namespace ts {
|
||||
namespace ts {
|
||||
export type WatchStatusReporter = (diagnostic: Diagnostic, newLine: string, options: CompilerOptions) => void;
|
||||
/** Create the program with rootNames and options, if they are undefined, oldProgram and new configFile diagnostics create new program */
|
||||
export type CreateProgram<T extends BuilderProgram> = (rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: T, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>) => T;
|
||||
export interface WatchCompilerHost<T extends BuilderProgram> {
|
||||
export type CreateProgram<T extends BuilderProgram> = (rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: T, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>, projectReferences?: ReadonlyArray<ProjectReference> | undefined) => T;
|
||||
/** Host that has watch functionality used in --watch mode */
|
||||
export interface WatchHost {
|
||||
/** If provided, called with Diagnostic message that informs about change in watch status */
|
||||
onWatchStatusChange?(diagnostic: Diagnostic, newLine: string, options: CompilerOptions): void;
|
||||
|
||||
/** Used to watch changes in source files, missing files needed to update the program or config file */
|
||||
watchFile(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher;
|
||||
/** Used to watch resolved module's failed lookup locations, config file specs, type roots where auto type reference directives are added */
|
||||
watchDirectory(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
|
||||
/** If provided, will be used to set delayed compilation, so that multiple changes in short span are compiled together */
|
||||
setTimeout?(callback: (...args: any[]) => void, ms: number, ...args: any[]): any;
|
||||
/** If provided, will be used to reset existing delayed compilation */
|
||||
clearTimeout?(timeoutId: any): void;
|
||||
}
|
||||
export interface WatchCompilerHost<T extends BuilderProgram> extends WatchHost {
|
||||
// TODO: GH#18217 Optional methods are frequently asserted
|
||||
|
||||
/**
|
||||
@@ -278,8 +314,6 @@ namespace ts {
|
||||
createProgram: CreateProgram<T>;
|
||||
/** If provided, callback to invoke after every new program creation */
|
||||
afterProgramCreate?(program: T): void;
|
||||
/** If provided, called with Diagnostic message that informs about change in watch status */
|
||||
onWatchStatusChange?(diagnostic: Diagnostic, newLine: string, options: CompilerOptions): void;
|
||||
|
||||
// Only for testing
|
||||
/*@internal*/
|
||||
@@ -319,18 +353,9 @@ namespace ts {
|
||||
getEnvironmentVariable?(name: string): string | undefined;
|
||||
|
||||
/** If provided, used to resolve the module names, otherwise typescript's default module resolution */
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[];
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[], redirectedReference?: ResolvedProjectReference): (ResolvedModule | undefined)[];
|
||||
/** If provided, used to resolve type reference directives, otherwise typescript's default resolution */
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
|
||||
/** Used to watch changes in source files, missing files needed to update the program or config file */
|
||||
watchFile(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher;
|
||||
/** Used to watch resolved module's failed lookup locations, config file specs, type roots where auto type reference directives are added */
|
||||
watchDirectory(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
|
||||
/** If provided, will be used to set delayed compilation, so that multiple changes in short span are compiled together */
|
||||
setTimeout?(callback: (...args: any[]) => void, ms: number, ...args: any[]): any;
|
||||
/** If provided, will be used to reset existing delayed compilation */
|
||||
clearTimeout?(timeoutId: any): void;
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): (ResolvedTypeReferenceDirective | undefined)[];
|
||||
}
|
||||
|
||||
/** Internal interface used to wire emit through same host */
|
||||
@@ -351,6 +376,9 @@ namespace ts {
|
||||
|
||||
/** Compiler options */
|
||||
options: CompilerOptions;
|
||||
|
||||
/** Project References */
|
||||
projectReferences?: ReadonlyArray<ProjectReference>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -404,11 +432,11 @@ namespace ts {
|
||||
/**
|
||||
* Create the watch compiler host for either configFile or fileNames and its options
|
||||
*/
|
||||
export function createWatchCompilerHost<T extends BuilderProgram>(rootFiles: string[], options: CompilerOptions, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfFilesAndCompilerOptions<T>;
|
||||
export function createWatchCompilerHost<T extends BuilderProgram>(configFileName: string, optionsToExtend: CompilerOptions | undefined, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfConfigFile<T>;
|
||||
export function createWatchCompilerHost<T extends BuilderProgram>(rootFilesOrConfigFileName: string | string[], options: CompilerOptions | undefined, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfFilesAndCompilerOptions<T> | WatchCompilerHostOfConfigFile<T> {
|
||||
export function createWatchCompilerHost<T extends BuilderProgram>(rootFiles: string[], options: CompilerOptions, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter, projectReferences?: ReadonlyArray<ProjectReference>): WatchCompilerHostOfFilesAndCompilerOptions<T>;
|
||||
export function createWatchCompilerHost<T extends BuilderProgram>(rootFilesOrConfigFileName: string | string[], options: CompilerOptions | undefined, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter, projectReferences?: ReadonlyArray<ProjectReference>): WatchCompilerHostOfFilesAndCompilerOptions<T> | WatchCompilerHostOfConfigFile<T> {
|
||||
if (isArray(rootFilesOrConfigFileName)) {
|
||||
return createWatchCompilerHostOfFilesAndCompilerOptions(rootFilesOrConfigFileName, options!, system, createProgram, reportDiagnostic, reportWatchStatus); // TODO: GH#18217
|
||||
return createWatchCompilerHostOfFilesAndCompilerOptions(rootFilesOrConfigFileName, options!, system, createProgram, reportDiagnostic, reportWatchStatus, projectReferences); // TODO: GH#18217
|
||||
}
|
||||
else {
|
||||
return createWatchCompilerHostOfConfigFile(rootFilesOrConfigFileName, options, system, createProgram, reportDiagnostic, reportWatchStatus);
|
||||
@@ -454,9 +482,10 @@ namespace ts {
|
||||
const getCurrentDirectory = () => currentDirectory;
|
||||
const readFile: (path: string, encoding?: string) => string | undefined = (path, encoding) => host.readFile(path, encoding);
|
||||
const { configFileName, optionsToExtend: optionsToExtendForConfigFile = {}, createProgram } = host;
|
||||
let { rootFiles: rootFileNames, options: compilerOptions } = host;
|
||||
let { rootFiles: rootFileNames, options: compilerOptions, projectReferences } = host;
|
||||
let configFileSpecs: ConfigFileSpecs;
|
||||
let configFileParsingDiagnostics: ReadonlyArray<Diagnostic> | undefined;
|
||||
let configFileParsingDiagnostics: Diagnostic[] | undefined;
|
||||
let canConfigFileJsonReportNoInputFiles = false;
|
||||
let hasChangedConfigFileParsingErrors = false;
|
||||
|
||||
const cachedDirectoryStructureHost = configFileName === undefined ? undefined : createCachedDirectoryStructureHost(host, currentDirectory, useCaseSensitiveFileNames);
|
||||
@@ -470,7 +499,8 @@ namespace ts {
|
||||
fileExists: path => host.fileExists(path),
|
||||
readFile,
|
||||
getCurrentDirectory,
|
||||
onUnRecoverableConfigFileDiagnostic: host.onUnRecoverableConfigFileDiagnostic
|
||||
onUnRecoverableConfigFileDiagnostic: host.onUnRecoverableConfigFileDiagnostic,
|
||||
trace: host.trace ? s => host.trace!(s) : undefined
|
||||
};
|
||||
|
||||
// From tsc we want to get already parsed result and hence check for rootFileNames
|
||||
@@ -533,7 +563,8 @@ namespace ts {
|
||||
},
|
||||
maxNumberOfFilesToIterateForInvalidation: host.maxNumberOfFilesToIterateForInvalidation,
|
||||
getCurrentProgram,
|
||||
writeLog
|
||||
writeLog,
|
||||
readDirectory: (path, extensions, exclude, include, depth?) => directoryStructureHost.readDirectory!(path, extensions, exclude, include, depth),
|
||||
};
|
||||
// Cache for the module resolution
|
||||
const resolutionCache = createResolutionCache(compilerHost, configFileName ?
|
||||
@@ -543,11 +574,11 @@ namespace ts {
|
||||
);
|
||||
// Resolve module using host module resolution strategy if provided otherwise use resolution cache to resolve module names
|
||||
compilerHost.resolveModuleNames = host.resolveModuleNames ?
|
||||
((moduleNames, containingFile, reusedNames) => host.resolveModuleNames!(moduleNames, containingFile, reusedNames)) :
|
||||
((moduleNames, containingFile, reusedNames) => resolutionCache.resolveModuleNames(moduleNames, containingFile, reusedNames));
|
||||
((moduleNames, containingFile, reusedNames, redirectedReference) => host.resolveModuleNames!(moduleNames, containingFile, reusedNames, redirectedReference)) :
|
||||
((moduleNames, containingFile, reusedNames, redirectedReference) => resolutionCache.resolveModuleNames(moduleNames, containingFile, reusedNames, redirectedReference));
|
||||
compilerHost.resolveTypeReferenceDirectives = host.resolveTypeReferenceDirectives ?
|
||||
((typeDirectiveNames, containingFile) => host.resolveTypeReferenceDirectives!(typeDirectiveNames, containingFile)) :
|
||||
((typeDirectiveNames, containingFile) => resolutionCache.resolveTypeReferenceDirectives(typeDirectiveNames, containingFile));
|
||||
((typeDirectiveNames, containingFile, redirectedReference) => host.resolveTypeReferenceDirectives!(typeDirectiveNames, containingFile, redirectedReference)) :
|
||||
((typeDirectiveNames, containingFile, redirectedReference) => resolutionCache.resolveTypeReferenceDirectives(typeDirectiveNames, containingFile, redirectedReference));
|
||||
const userProvidedResolution = !!host.resolveModuleNames || !!host.resolveTypeReferenceDirectives;
|
||||
|
||||
synchronizeProgram();
|
||||
@@ -580,9 +611,9 @@ namespace ts {
|
||||
|
||||
// All resolutions are invalid if user provided resolutions
|
||||
const hasInvalidatedResolution = resolutionCache.createHasInvalidatedResolution(userProvidedResolution);
|
||||
if (isProgramUptoDate(getCurrentProgram(), rootFileNames, compilerOptions, getSourceVersion, fileExists, hasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames)) {
|
||||
if (isProgramUptoDate(getCurrentProgram(), rootFileNames, compilerOptions, getSourceVersion, fileExists, hasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames, projectReferences)) {
|
||||
if (hasChangedConfigFileParsingErrors) {
|
||||
builderProgram = createProgram(/*rootNames*/ undefined, /*options*/ undefined, compilerHost, builderProgram, configFileParsingDiagnostics);
|
||||
builderProgram = createProgram(/*rootNames*/ undefined, /*options*/ undefined, compilerHost, builderProgram, configFileParsingDiagnostics, projectReferences);
|
||||
hasChangedConfigFileParsingErrors = false;
|
||||
}
|
||||
}
|
||||
@@ -611,7 +642,7 @@ namespace ts {
|
||||
resolutionCache.startCachingPerDirectoryResolution();
|
||||
compilerHost.hasInvalidatedResolution = hasInvalidatedResolution;
|
||||
compilerHost.hasChangedAutomaticTypeDirectiveNames = hasChangedAutomaticTypeDirectiveNames;
|
||||
builderProgram = createProgram(rootFileNames, compilerOptions, compilerHost, builderProgram, configFileParsingDiagnostics);
|
||||
builderProgram = createProgram(rootFileNames, compilerOptions, compilerHost, builderProgram, configFileParsingDiagnostics, projectReferences);
|
||||
resolutionCache.finishCachingPerDirectoryResolution();
|
||||
|
||||
// Update watches
|
||||
@@ -749,8 +780,8 @@ namespace ts {
|
||||
return !hostSourceFile || isFileMissingOnHost(hostSourceFile) ? undefined : hostSourceFile.version.toString();
|
||||
}
|
||||
|
||||
function onReleaseOldSourceFile(oldSourceFile: SourceFile, _oldOptions: CompilerOptions) {
|
||||
const hostSourceFileInfo = sourceFilesCache.get(oldSourceFile.path);
|
||||
function onReleaseOldSourceFile(oldSourceFile: SourceFile, _oldOptions: CompilerOptions, hasSourceFileByPath: boolean) {
|
||||
const hostSourceFileInfo = sourceFilesCache.get(oldSourceFile.resolvedPath);
|
||||
// If this is the source file thats in the cache and new program doesnt need it,
|
||||
// remove the cached entry.
|
||||
// Note we arent deleting entry if file became missing in new program or
|
||||
@@ -764,8 +795,10 @@ namespace ts {
|
||||
if ((hostSourceFileInfo as FilePresentOnHost).fileWatcher) {
|
||||
(hostSourceFileInfo as FilePresentOnHost).fileWatcher.close();
|
||||
}
|
||||
sourceFilesCache.delete(oldSourceFile.path);
|
||||
resolutionCache.removeResolutionsOfFile(oldSourceFile.path);
|
||||
sourceFilesCache.delete(oldSourceFile.resolvedPath);
|
||||
if (!hasSourceFileByPath) {
|
||||
resolutionCache.removeResolutionsOfFile(oldSourceFile.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -815,12 +848,7 @@ namespace ts {
|
||||
function reloadFileNamesFromConfigFile() {
|
||||
writeLog("Reloading new file names and options");
|
||||
const result = getFileNamesFromConfigSpecs(configFileSpecs, getDirectoryPath(configFileName), compilerOptions, parseConfigFileHost);
|
||||
if (result.fileNames.length) {
|
||||
configFileParsingDiagnostics = filter(configFileParsingDiagnostics, error => !isErrorNoInputFiles(error));
|
||||
hasChangedConfigFileParsingErrors = true;
|
||||
}
|
||||
else if (!configFileSpecs.filesSpecs && !some(configFileParsingDiagnostics, isErrorNoInputFiles)) {
|
||||
configFileParsingDiagnostics = configFileParsingDiagnostics!.concat(getErrorForNoInputFiles(configFileSpecs, configFileName));
|
||||
if (updateErrorForNoInputFiles(result, configFileName, configFileSpecs, configFileParsingDiagnostics!, canConfigFileJsonReportNoInputFiles)) {
|
||||
hasChangedConfigFileParsingErrors = true;
|
||||
}
|
||||
rootFileNames = result.fileNames;
|
||||
@@ -852,7 +880,9 @@ namespace ts {
|
||||
rootFileNames = configFileParseResult.fileNames;
|
||||
compilerOptions = configFileParseResult.options;
|
||||
configFileSpecs = configFileParseResult.configFileSpecs!; // TODO: GH#18217
|
||||
configFileParsingDiagnostics = getConfigFileParsingDiagnostics(configFileParseResult);
|
||||
projectReferences = configFileParseResult.projectReferences;
|
||||
configFileParsingDiagnostics = getConfigFileParsingDiagnostics(configFileParseResult).slice();
|
||||
canConfigFileJsonReportNoInputFiles = canJsonReportNoInutFiles(configFileParseResult.raw);
|
||||
hasChangedConfigFileParsingErrors = true;
|
||||
}
|
||||
|
||||
@@ -863,6 +893,7 @@ namespace ts {
|
||||
if (eventKind === FileWatcherEventKind.Deleted && sourceFilesCache.get(path)) {
|
||||
resolutionCache.invalidateResolutionOfFile(path);
|
||||
}
|
||||
resolutionCache.removeResolutionsFromProjectReferenceRedirects(path);
|
||||
nextSourceFileVersion(path);
|
||||
|
||||
// Update the program
|
||||
@@ -922,6 +953,8 @@ namespace ts {
|
||||
}
|
||||
nextSourceFileVersion(fileOrDirectoryPath);
|
||||
|
||||
if (isPathInNodeModulesStartingWithDot(fileOrDirectoryPath)) return;
|
||||
|
||||
// If the the added or created file or directory is not supported file name, ignore the file
|
||||
// But when watched directory is added/removed, we need to reload the file list
|
||||
if (fileOrDirectoryPath !== directory && hasExtension(fileOrDirectoryPath) && !isSupportedSourceFileName(fileOrDirectory, compilerOptions)) {
|
||||
|
||||
+41
-26
@@ -3,12 +3,15 @@ namespace ts.server {
|
||||
writeMessage(message: string): void;
|
||||
}
|
||||
|
||||
interface RenameEntry extends RenameInfo {
|
||||
fileName: string;
|
||||
position: number;
|
||||
locations: RenameLocation[];
|
||||
findInStrings: boolean;
|
||||
findInComments: boolean;
|
||||
interface RenameEntry {
|
||||
readonly renameInfo: RenameInfo;
|
||||
readonly inputs: {
|
||||
readonly fileName: string;
|
||||
readonly position: number;
|
||||
readonly findInStrings: boolean;
|
||||
readonly findInComments: boolean;
|
||||
};
|
||||
readonly locations: RenameLocation[];
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -34,7 +37,7 @@ namespace ts.server {
|
||||
private sequence = 0;
|
||||
private lineMaps: Map<number[]> = createMap<number[]>();
|
||||
private messages: string[] = [];
|
||||
private lastRenameEntry: RenameEntry;
|
||||
private lastRenameEntry: RenameEntry | undefined;
|
||||
|
||||
constructor(private host: SessionClientHost) {
|
||||
}
|
||||
@@ -390,37 +393,45 @@ namespace ts.server {
|
||||
const locations: RenameLocation[] = [];
|
||||
for (const entry of body.locs) {
|
||||
const fileName = entry.file;
|
||||
for (const loc of entry.locs) {
|
||||
locations.push({ textSpan: this.decodeSpan(loc, fileName), fileName });
|
||||
for (const { start, end, ...prefixSuffixText } of entry.locs) {
|
||||
locations.push({ textSpan: this.decodeSpan({ start, end }, fileName), fileName, ...prefixSuffixText });
|
||||
}
|
||||
}
|
||||
|
||||
return this.lastRenameEntry = {
|
||||
canRename: body.info.canRename,
|
||||
displayName: body.info.displayName,
|
||||
fullDisplayName: body.info.fullDisplayName,
|
||||
kind: body.info.kind,
|
||||
kindModifiers: body.info.kindModifiers,
|
||||
localizedErrorMessage: body.info.localizedErrorMessage,
|
||||
triggerSpan: createTextSpanFromBounds(position, position),
|
||||
fileName,
|
||||
position,
|
||||
findInStrings: !!findInStrings,
|
||||
findInComments: !!findInComments,
|
||||
const renameInfo = body.info.canRename
|
||||
? identity<RenameInfoSuccess>({
|
||||
canRename: body.info.canRename,
|
||||
fileToRename: body.info.fileToRename,
|
||||
displayName: body.info.displayName,
|
||||
fullDisplayName: body.info.fullDisplayName,
|
||||
kind: body.info.kind,
|
||||
kindModifiers: body.info.kindModifiers,
|
||||
triggerSpan: createTextSpanFromBounds(position, position),
|
||||
})
|
||||
: identity<RenameInfoFailure>({ canRename: false, localizedErrorMessage: body.info.localizedErrorMessage });
|
||||
this.lastRenameEntry = {
|
||||
renameInfo,
|
||||
inputs: {
|
||||
fileName,
|
||||
position,
|
||||
findInStrings: !!findInStrings,
|
||||
findInComments: !!findInComments,
|
||||
},
|
||||
locations,
|
||||
};
|
||||
return renameInfo;
|
||||
}
|
||||
|
||||
findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[] {
|
||||
if (!this.lastRenameEntry ||
|
||||
this.lastRenameEntry.fileName !== fileName ||
|
||||
this.lastRenameEntry.position !== position ||
|
||||
this.lastRenameEntry.findInStrings !== findInStrings ||
|
||||
this.lastRenameEntry.findInComments !== findInComments) {
|
||||
this.lastRenameEntry.inputs.fileName !== fileName ||
|
||||
this.lastRenameEntry.inputs.position !== position ||
|
||||
this.lastRenameEntry.inputs.findInStrings !== findInStrings ||
|
||||
this.lastRenameEntry.inputs.findInComments !== findInComments) {
|
||||
this.getRenameInfo(fileName, position, findInStrings, findInComments);
|
||||
}
|
||||
|
||||
return this.lastRenameEntry.locations;
|
||||
return this.lastRenameEntry!.locations;
|
||||
}
|
||||
|
||||
private decodeNavigationBarItems(items: protocol.NavigationBarItem[] | undefined, fileName: string, lineMap: number[]): NavigationBarItem[] {
|
||||
@@ -683,6 +694,10 @@ namespace ts.server {
|
||||
return response.body!.map(entry => this.decodeSpan(entry, fileName)); // TODO: GH#18217
|
||||
}
|
||||
|
||||
configurePlugin(pluginName: string, configuration: any): void {
|
||||
this.processRequest<protocol.ConfigurePluginRequest>("configurePlugin", { pluginName, configuration });
|
||||
}
|
||||
|
||||
getIndentationAtPosition(_fileName: string, _position: number, _options: EditorOptions): number {
|
||||
return notImplemented();
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace compiler {
|
||||
private _inputs: documents.TextDocument[] = [];
|
||||
private _inputsAndOutputs: collections.SortedMap<string, CompilationOutput>;
|
||||
|
||||
constructor(host: fakes.CompilerHost, options: ts.CompilerOptions, program: ts.Program | undefined, result: ts.EmitResult | undefined, diagnostics: ts.Diagnostic[]) {
|
||||
constructor(host: fakes.CompilerHost, options: ts.CompilerOptions, program: ts.Program | undefined, result: ts.EmitResult | undefined, diagnostics: ReadonlyArray<ts.Diagnostic>) {
|
||||
this.host = host;
|
||||
this.program = program;
|
||||
this.result = result;
|
||||
|
||||
+37
-1
@@ -215,7 +215,7 @@ namespace fakes {
|
||||
|
||||
private _setParentNodes: boolean;
|
||||
private _sourceFiles: collections.SortedMap<string, ts.SourceFile>;
|
||||
private _parseConfigHost: ParseConfigHost;
|
||||
private _parseConfigHost: ParseConfigHost | undefined;
|
||||
private _newLine: string;
|
||||
|
||||
constructor(sys: System | vfs.FileSystem, options = ts.getDefaultCompilerOptions(), setParentNodes = false) {
|
||||
@@ -374,5 +374,41 @@ namespace fakes {
|
||||
return parsed;
|
||||
}
|
||||
}
|
||||
|
||||
export class SolutionBuilderHost extends CompilerHost implements ts.SolutionBuilderHost {
|
||||
diagnostics: ts.Diagnostic[] = [];
|
||||
|
||||
reportDiagnostic(diagnostic: ts.Diagnostic) {
|
||||
this.diagnostics.push(diagnostic);
|
||||
}
|
||||
|
||||
reportSolutionBuilderStatus(diagnostic: ts.Diagnostic) {
|
||||
this.diagnostics.push(diagnostic);
|
||||
}
|
||||
|
||||
clearDiagnostics() {
|
||||
this.diagnostics.length = 0;
|
||||
}
|
||||
|
||||
assertDiagnosticMessages(...expected: ts.DiagnosticMessage[]) {
|
||||
const actual = this.diagnostics.slice();
|
||||
if (actual.length !== expected.length) {
|
||||
assert.fail<any>(actual, expected, `Diagnostic arrays did not match - got\r\n${actual.map(a => " " + a.messageText).join("\r\n")}\r\nexpected\r\n${expected.map(e => " " + e.message).join("\r\n")}`);
|
||||
}
|
||||
for (let i = 0; i < actual.length; i++) {
|
||||
if (actual[i].code !== expected[i].code) {
|
||||
assert.fail(actual[i].messageText, expected[i].message, `Mismatched error code - expected diagnostic ${i} "${actual[i].messageText}" to match ${expected[i].message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printDiagnostics(header = "== Diagnostics ==") {
|
||||
const out = ts.createDiagnosticReporter(ts.sys);
|
||||
ts.sys.write(header + "\r\n");
|
||||
for (const d of this.diagnostics) {
|
||||
out(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+845
-654
File diff suppressed because it is too large
Load Diff
+64
-82
@@ -28,12 +28,10 @@ var assert: typeof _chai.assert = _chai.assert;
|
||||
};
|
||||
}
|
||||
|
||||
var global: NodeJS.Global = Function("return this").call(undefined);
|
||||
var global: NodeJS.Global = Function("return this").call(undefined); // tslint:disable-line:function-constructor
|
||||
|
||||
declare var window: {};
|
||||
declare var XMLHttpRequest: {
|
||||
new(): XMLHttpRequest;
|
||||
};
|
||||
declare var XMLHttpRequest: new() => XMLHttpRequest;
|
||||
interface XMLHttpRequest {
|
||||
readonly readyState: number;
|
||||
readonly responseText: string;
|
||||
@@ -490,7 +488,7 @@ namespace Harness {
|
||||
getExecutingFilePath(): string;
|
||||
getWorkspaceRoot(): string;
|
||||
exit(exitCode?: number): void;
|
||||
readDirectory(path: string, extension?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];
|
||||
readDirectory(path: string, extension?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): ReadonlyArray<string>;
|
||||
getAccessibleFileSystemEntries(dirname: string): ts.FileSystemEntries;
|
||||
tryEnableSourceMapsForHost?(): void;
|
||||
getEnvironmentVariable?(name: string): string;
|
||||
@@ -1159,7 +1157,7 @@ namespace Harness {
|
||||
}
|
||||
// If not a primitive, the possible types are specified in what is effectively a map of options.
|
||||
case "list":
|
||||
return ts.parseListTypeOption(<ts.CommandLineOptionOfListType>option, value, errors);
|
||||
return ts.parseListTypeOption(option, value, errors);
|
||||
default:
|
||||
return ts.parseCustomTypeOption(<ts.CommandLineOptionOfCustomType>option, value, errors);
|
||||
}
|
||||
@@ -1325,6 +1323,9 @@ namespace Harness {
|
||||
const [, content] = value;
|
||||
outputLines += content;
|
||||
}
|
||||
if (pretty) {
|
||||
outputLines += ts.getErrorSummaryText(ts.getErrorCountForSummary(diagnostics), IO.newLine());
|
||||
}
|
||||
return outputLines;
|
||||
}
|
||||
|
||||
@@ -1483,17 +1484,12 @@ namespace Harness {
|
||||
}
|
||||
|
||||
export function doErrorBaseline(baselinePath: string, inputFiles: ReadonlyArray<TestFile>, errors: ReadonlyArray<ts.Diagnostic>, pretty?: boolean) {
|
||||
Baseline.runBaseline(baselinePath.replace(/\.tsx?$/, ".errors.txt"), (): string | null => {
|
||||
if (!errors || (errors.length === 0)) {
|
||||
/* tslint:disable:no-null-keyword */
|
||||
return null;
|
||||
/* tslint:enable:no-null-keyword */
|
||||
}
|
||||
return getErrorBaseline(inputFiles, errors, pretty);
|
||||
});
|
||||
Baseline.runBaseline(baselinePath.replace(/\.tsx?$/, ".errors.txt"),
|
||||
// tslint:disable-next-line no-null-keyword
|
||||
!errors || (errors.length === 0) ? null : getErrorBaseline(inputFiles, errors, pretty));
|
||||
}
|
||||
|
||||
export function doTypeAndSymbolBaseline(baselinePath: string, program: ts.Program, allFiles: {unitName: string, content: string}[], opts?: Baseline.BaselineOptions, multifile?: boolean, skipTypeBaselines?: boolean, skipSymbolBaselines?: boolean) {
|
||||
export function doTypeAndSymbolBaseline(baselinePath: string, program: ts.Program, allFiles: {unitName: string, content: string}[], opts?: Baseline.BaselineOptions, multifile?: boolean, skipTypeBaselines?: boolean, skipSymbolBaselines?: boolean, hasErrorBaseline?: boolean) {
|
||||
// The full walker simulates the types that you would get from doing a full
|
||||
// compile. The pull walker simulates the types you get when you just do
|
||||
// a type query for a random node (like how the LS would do it). Most of the
|
||||
@@ -1509,7 +1505,7 @@ namespace Harness {
|
||||
// These types are equivalent, but depend on what order the compiler observed
|
||||
// certain parts of the program.
|
||||
|
||||
const fullWalker = new TypeWriterWalker(program, /*fullTypeCheck*/ true);
|
||||
const fullWalker = new TypeWriterWalker(program, /*fullTypeCheck*/ true, !!hasErrorBaseline);
|
||||
|
||||
// Produce baselines. The first gives the types for all expressions.
|
||||
// The second gives symbols for all identifiers.
|
||||
@@ -1552,7 +1548,7 @@ namespace Harness {
|
||||
|
||||
if (!multifile) {
|
||||
const fullBaseLine = generateBaseLine(isSymbolBaseLine, isSymbolBaseLine ? skipSymbolBaselines : skipTypeBaselines);
|
||||
Baseline.runBaseline(outputFileName + fullExtension, () => fullBaseLine, opts);
|
||||
Baseline.runBaseline(outputFileName + fullExtension, fullBaseLine, opts);
|
||||
}
|
||||
else {
|
||||
Baseline.runMultifileBaseline(outputFileName, fullExtension, () => {
|
||||
@@ -1637,22 +1633,22 @@ namespace Harness {
|
||||
throw new Error("Number of sourcemap files should be same as js files.");
|
||||
}
|
||||
|
||||
Baseline.runBaseline(baselinePath.replace(/\.tsx?/, ".js.map"), () => {
|
||||
if ((options.noEmitOnError && result.diagnostics.length !== 0) || result.maps.size === 0) {
|
||||
// We need to return null here or the runBaseLine will actually create a empty file.
|
||||
// Baselining isn't required here because there is no output.
|
||||
/* tslint:disable:no-null-keyword */
|
||||
return null;
|
||||
/* tslint:enable:no-null-keyword */
|
||||
}
|
||||
|
||||
let sourceMapCode = "";
|
||||
let sourceMapCode: string | null;
|
||||
if ((options.noEmitOnError && result.diagnostics.length !== 0) || result.maps.size === 0) {
|
||||
// We need to return null here or the runBaseLine will actually create a empty file.
|
||||
// Baselining isn't required here because there is no output.
|
||||
/* tslint:disable:no-null-keyword */
|
||||
sourceMapCode = null;
|
||||
/* tslint:enable:no-null-keyword */
|
||||
}
|
||||
else {
|
||||
sourceMapCode = "";
|
||||
result.maps.forEach(sourceMap => {
|
||||
if (sourceMapCode) sourceMapCode += "\r\n";
|
||||
sourceMapCode += fileOutput(sourceMap, harnessSettings);
|
||||
});
|
||||
|
||||
return sourceMapCode;
|
||||
});
|
||||
}
|
||||
Baseline.runBaseline(baselinePath.replace(/\.tsx?/, ".js.map"), sourceMapCode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1662,49 +1658,43 @@ namespace Harness {
|
||||
}
|
||||
|
||||
// check js output
|
||||
Baseline.runBaseline(baselinePath.replace(/\.tsx?/, ts.Extension.Js), () => {
|
||||
let tsCode = "";
|
||||
const tsSources = otherFiles.concat(toBeCompiled);
|
||||
if (tsSources.length > 1) {
|
||||
tsCode += "//// [" + header + "] ////\r\n\r\n";
|
||||
}
|
||||
for (let i = 0; i < tsSources.length; i++) {
|
||||
tsCode += "//// [" + ts.getBaseFileName(tsSources[i].unitName) + "]\r\n";
|
||||
tsCode += tsSources[i].content + (i < (tsSources.length - 1) ? "\r\n" : "");
|
||||
}
|
||||
let tsCode = "";
|
||||
const tsSources = otherFiles.concat(toBeCompiled);
|
||||
if (tsSources.length > 1) {
|
||||
tsCode += "//// [" + header + "] ////\r\n\r\n";
|
||||
}
|
||||
for (let i = 0; i < tsSources.length; i++) {
|
||||
tsCode += "//// [" + ts.getBaseFileName(tsSources[i].unitName) + "]\r\n";
|
||||
tsCode += tsSources[i].content + (i < (tsSources.length - 1) ? "\r\n" : "");
|
||||
}
|
||||
|
||||
let jsCode = "";
|
||||
result.js.forEach(file => {
|
||||
jsCode += fileOutput(file, harnessSettings);
|
||||
});
|
||||
|
||||
if (result.dts.size > 0) {
|
||||
jsCode += "\r\n\r\n";
|
||||
result.dts.forEach(declFile => {
|
||||
jsCode += fileOutput(declFile, harnessSettings);
|
||||
});
|
||||
}
|
||||
|
||||
const declFileContext = prepareDeclarationCompilationContext(
|
||||
toBeCompiled, otherFiles, result, harnessSettings, options, /*currentDirectory*/ undefined
|
||||
);
|
||||
const declFileCompilationResult = compileDeclarationFiles(declFileContext, result.symlinks);
|
||||
|
||||
if (declFileCompilationResult && declFileCompilationResult.declResult.diagnostics.length) {
|
||||
jsCode += "\r\n\r\n//// [DtsFileErrors]\r\n";
|
||||
jsCode += "\r\n\r\n";
|
||||
jsCode += getErrorBaseline(tsConfigFiles.concat(declFileCompilationResult.declInputFiles, declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.diagnostics);
|
||||
}
|
||||
|
||||
if (jsCode.length > 0) {
|
||||
return tsCode + "\r\n\r\n" + jsCode;
|
||||
}
|
||||
else {
|
||||
/* tslint:disable:no-null-keyword */
|
||||
return null;
|
||||
/* tslint:enable:no-null-keyword */
|
||||
let jsCode = "";
|
||||
result.js.forEach(file => {
|
||||
if (jsCode.length && jsCode.charCodeAt(jsCode.length - 1) !== ts.CharacterCodes.lineFeed) {
|
||||
jsCode += "\r\n";
|
||||
}
|
||||
jsCode += fileOutput(file, harnessSettings);
|
||||
});
|
||||
|
||||
if (result.dts.size > 0) {
|
||||
jsCode += "\r\n\r\n";
|
||||
result.dts.forEach(declFile => {
|
||||
jsCode += fileOutput(declFile, harnessSettings);
|
||||
});
|
||||
}
|
||||
|
||||
const declFileContext = prepareDeclarationCompilationContext(
|
||||
toBeCompiled, otherFiles, result, harnessSettings, options, /*currentDirectory*/ undefined
|
||||
);
|
||||
const declFileCompilationResult = compileDeclarationFiles(declFileContext, result.symlinks);
|
||||
|
||||
if (declFileCompilationResult && declFileCompilationResult.declResult.diagnostics.length) {
|
||||
jsCode += "\r\n\r\n//// [DtsFileErrors]\r\n";
|
||||
jsCode += "\r\n\r\n";
|
||||
jsCode += getErrorBaseline(tsConfigFiles.concat(declFileCompilationResult.declInputFiles, declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.diagnostics);
|
||||
}
|
||||
|
||||
Baseline.runBaseline(baselinePath.replace(/\.tsx?/, ts.Extension.Js), jsCode.length > 0 ? tsCode + "\r\n\r\n" + jsCode : null); // tslint:disable-line no-null-keyword
|
||||
}
|
||||
|
||||
function fileOutput(file: documents.TextDocument, harnessSettings: TestCaseParser.CompilerSettings): string {
|
||||
@@ -2027,16 +2017,6 @@ namespace Harness {
|
||||
}
|
||||
|
||||
const fileCache: { [idx: string]: boolean } = {};
|
||||
function generateActual(generateContent: () => string | null): string | null {
|
||||
|
||||
const actual = generateContent();
|
||||
|
||||
if (actual === undefined) {
|
||||
throw new Error("The generated content was \"undefined\". Return \"null\" if no baselining is required.\"");
|
||||
}
|
||||
|
||||
return actual;
|
||||
}
|
||||
|
||||
function compareToBaseline(actual: string | null, relativeFileName: string, opts: BaselineOptions | undefined) {
|
||||
// actual is now either undefined (the generator had an error), null (no file requested),
|
||||
@@ -2100,9 +2080,11 @@ namespace Harness {
|
||||
}
|
||||
}
|
||||
|
||||
export function runBaseline(relativeFileName: string, generateContent: () => string | null, opts?: BaselineOptions): void {
|
||||
export function runBaseline(relativeFileName: string, actual: string | null, opts?: BaselineOptions): void {
|
||||
const actualFileName = localPath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder);
|
||||
const actual = generateActual(generateContent);
|
||||
if (actual === undefined) {
|
||||
throw new Error("The generated content was \"undefined\". Return \"null\" if no baselining is required.\"");
|
||||
}
|
||||
const comparison = compareToBaseline(actual, relativeFileName, opts);
|
||||
writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
namespace Harness.LanguageService {
|
||||
|
||||
export function makeDefaultProxy(info: ts.server.PluginCreateInfo): ts.LanguageService {
|
||||
// tslint:disable-next-line:no-null-keyword
|
||||
const proxy = Object.create(/*prototype*/ null);
|
||||
const langSvc: any = info.languageService;
|
||||
for (const k of Object.keys(langSvc)) {
|
||||
// tslint:disable-next-line only-arrow-functions
|
||||
proxy[k] = function () {
|
||||
return langSvc[k].apply(langSvc, arguments);
|
||||
};
|
||||
}
|
||||
return proxy;
|
||||
}
|
||||
|
||||
export class ScriptInfo {
|
||||
public version = 1;
|
||||
public editRanges: { length: number; textChangeRange: ts.TextChangeRange; }[] = [];
|
||||
@@ -268,15 +282,15 @@ namespace Harness.LanguageService {
|
||||
getHost(): LanguageServiceAdapterHost { return this.host; }
|
||||
getLanguageService(): ts.LanguageService { return ts.createLanguageService(this.host); }
|
||||
getClassifier(): ts.Classifier { return ts.createClassifier(); }
|
||||
getPreProcessedFileInfo(fileName: string, fileContents: string): ts.PreProcessedFileInfo { return ts.preProcessFile(fileContents, /* readImportFiles */ true, ts.hasJavaScriptFileExtension(fileName)); }
|
||||
getPreProcessedFileInfo(fileName: string, fileContents: string): ts.PreProcessedFileInfo { return ts.preProcessFile(fileContents, /* readImportFiles */ true, ts.hasJSFileExtension(fileName)); }
|
||||
}
|
||||
|
||||
/// Shim adapter
|
||||
class ShimLanguageServiceHost extends LanguageServiceAdapterHost implements ts.LanguageServiceShimHost, ts.CoreServicesShimHost {
|
||||
private nativeHost: NativeLanguageServiceHost;
|
||||
|
||||
public getModuleResolutionsForFile: (fileName: string) => string;
|
||||
public getTypeReferenceDirectiveResolutionsForFile: (fileName: string) => string;
|
||||
public getModuleResolutionsForFile: ((fileName: string) => string) | undefined;
|
||||
public getTypeReferenceDirectiveResolutionsForFile: ((fileName: string) => string) | undefined;
|
||||
|
||||
constructor(preprocessToResolve: boolean, cancellationToken?: ts.HostCancellationToken, options?: ts.CompilerOptions) {
|
||||
super(cancellationToken, options);
|
||||
@@ -625,7 +639,7 @@ namespace Harness.LanguageService {
|
||||
|
||||
// Server adapter
|
||||
class SessionClientHost extends NativeLanguageServiceHost implements ts.server.SessionClientHost {
|
||||
private client: ts.server.SessionClient;
|
||||
private client!: ts.server.SessionClient;
|
||||
|
||||
constructor(cancellationToken: ts.HostCancellationToken | undefined, settings: ts.CompilerOptions | undefined) {
|
||||
super(cancellationToken, settings);
|
||||
@@ -833,25 +847,42 @@ namespace Harness.LanguageService {
|
||||
error: undefined
|
||||
};
|
||||
|
||||
// Accepts configurations
|
||||
case "configurable-diagnostic-adder":
|
||||
let customMessage = "default message";
|
||||
return {
|
||||
module: () => ({
|
||||
create(info: ts.server.PluginCreateInfo) {
|
||||
customMessage = info.config.message;
|
||||
const proxy = makeDefaultProxy(info);
|
||||
proxy.getSemanticDiagnostics = filename => {
|
||||
const prev = info.languageService.getSemanticDiagnostics(filename);
|
||||
const sourceFile: ts.SourceFile = info.project.getSourceFile(ts.toPath(filename, /*basePath*/ undefined, ts.createGetCanonicalFileName(info.serverHost.useCaseSensitiveFileNames)))!;
|
||||
prev.push({
|
||||
category: ts.DiagnosticCategory.Error,
|
||||
file: sourceFile,
|
||||
code: 9999,
|
||||
length: 3,
|
||||
messageText: customMessage,
|
||||
start: 0
|
||||
});
|
||||
return prev;
|
||||
};
|
||||
return proxy;
|
||||
},
|
||||
onConfigurationChanged(config: any) {
|
||||
customMessage = config.message;
|
||||
}
|
||||
}),
|
||||
error: undefined
|
||||
};
|
||||
|
||||
default:
|
||||
return {
|
||||
module: undefined,
|
||||
error: new Error("Could not resolve module")
|
||||
};
|
||||
}
|
||||
|
||||
function makeDefaultProxy(info: ts.server.PluginCreateInfo): ts.LanguageService {
|
||||
// tslint:disable-next-line:no-null-keyword
|
||||
const proxy = Object.create(/*prototype*/ null);
|
||||
const langSvc: any = info.languageService;
|
||||
for (const k of Object.keys(langSvc)) {
|
||||
// tslint:disable-next-line only-arrow-functions
|
||||
proxy[k] = function () {
|
||||
return langSvc[k].apply(langSvc, arguments);
|
||||
};
|
||||
}
|
||||
return proxy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,44 +1,36 @@
|
||||
namespace Harness.SourceMapRecorder {
|
||||
|
||||
interface SourceMapSpanWithDecodeErrors {
|
||||
sourceMapSpan: ts.SourceMapSpan;
|
||||
sourceMapSpan: ts.Mapping;
|
||||
decodeErrors: string[] | undefined;
|
||||
}
|
||||
|
||||
namespace SourceMapDecoder {
|
||||
let sourceMapMappings: string;
|
||||
let decodingIndex: number;
|
||||
let mappings: ts.sourcemaps.MappingsDecoder | undefined;
|
||||
let mappings: ts.MappingsDecoder | undefined;
|
||||
|
||||
export interface DecodedMapping {
|
||||
sourceMapSpan: ts.SourceMapSpan;
|
||||
sourceMapSpan: ts.Mapping;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export function initializeSourceMapDecoding(sourceMapData: ts.SourceMapData) {
|
||||
export function initializeSourceMapDecoding(sourceMapData: ts.SourceMapEmitResult) {
|
||||
decodingIndex = 0;
|
||||
sourceMapMappings = sourceMapData.sourceMapMappings;
|
||||
mappings = ts.sourcemaps.decodeMappings({
|
||||
version: 3,
|
||||
file: sourceMapData.sourceMapFile,
|
||||
sources: sourceMapData.sourceMapSources,
|
||||
sourceRoot: sourceMapData.sourceMapSourceRoot,
|
||||
sourcesContent: sourceMapData.sourceMapSourcesContent,
|
||||
mappings: sourceMapData.sourceMapMappings,
|
||||
names: sourceMapData.sourceMapNames
|
||||
});
|
||||
sourceMapMappings = sourceMapData.sourceMap.mappings;
|
||||
mappings = ts.decodeMappings(sourceMapData.sourceMap.mappings);
|
||||
}
|
||||
|
||||
export function decodeNextEncodedSourceMapSpan(): DecodedMapping {
|
||||
if (!mappings) return ts.Debug.fail("not initialized");
|
||||
const result = mappings.next();
|
||||
if (result.done) return { error: mappings.error || "No encoded entry found", sourceMapSpan: mappings.lastSpan };
|
||||
if (result.done) return { error: mappings.error || "No encoded entry found", sourceMapSpan: mappings.state };
|
||||
return { sourceMapSpan: result.value };
|
||||
}
|
||||
|
||||
export function hasCompletedDecoding() {
|
||||
if (!mappings) return ts.Debug.fail("not initialized");
|
||||
return mappings.decodingIndex === sourceMapMappings.length;
|
||||
return mappings.pos === sourceMapMappings.length;
|
||||
}
|
||||
|
||||
export function getRemainingDecodeString() {
|
||||
@@ -49,7 +41,7 @@ namespace Harness.SourceMapRecorder {
|
||||
namespace SourceMapSpanWriter {
|
||||
let sourceMapRecorder: Compiler.WriterAggregator;
|
||||
let sourceMapSources: string[];
|
||||
let sourceMapNames: string[] | undefined;
|
||||
let sourceMapNames: string[] | null | undefined;
|
||||
|
||||
let jsFile: documents.TextDocument;
|
||||
let jsLineMap: ReadonlyArray<number>;
|
||||
@@ -61,10 +53,10 @@ namespace Harness.SourceMapRecorder {
|
||||
let nextJsLineToWrite: number;
|
||||
let spanMarkerContinues: boolean;
|
||||
|
||||
export function initializeSourceMapSpanWriter(sourceMapRecordWriter: Compiler.WriterAggregator, sourceMapData: ts.SourceMapData, currentJsFile: documents.TextDocument) {
|
||||
export function initializeSourceMapSpanWriter(sourceMapRecordWriter: Compiler.WriterAggregator, sourceMapData: ts.SourceMapEmitResult, currentJsFile: documents.TextDocument) {
|
||||
sourceMapRecorder = sourceMapRecordWriter;
|
||||
sourceMapSources = sourceMapData.sourceMapSources;
|
||||
sourceMapNames = sourceMapData.sourceMapNames;
|
||||
sourceMapSources = sourceMapData.sourceMap.sources;
|
||||
sourceMapNames = sourceMapData.sourceMap.names;
|
||||
|
||||
jsFile = currentJsFile;
|
||||
jsLineMap = jsFile.lineStarts;
|
||||
@@ -75,43 +67,39 @@ namespace Harness.SourceMapRecorder {
|
||||
spanMarkerContinues = false;
|
||||
|
||||
SourceMapDecoder.initializeSourceMapDecoding(sourceMapData);
|
||||
|
||||
sourceMapRecorder.WriteLine("===================================================================");
|
||||
sourceMapRecorder.WriteLine("JsFile: " + sourceMapData.sourceMapFile);
|
||||
sourceMapRecorder.WriteLine("mapUrl: " + sourceMapData.jsSourceMappingURL);
|
||||
sourceMapRecorder.WriteLine("sourceRoot: " + sourceMapData.sourceMapSourceRoot);
|
||||
sourceMapRecorder.WriteLine("sources: " + sourceMapData.sourceMapSources);
|
||||
if (sourceMapData.sourceMapSourcesContent) {
|
||||
sourceMapRecorder.WriteLine("sourcesContent: " + JSON.stringify(sourceMapData.sourceMapSourcesContent));
|
||||
sourceMapRecorder.WriteLine("JsFile: " + sourceMapData.sourceMap.file);
|
||||
sourceMapRecorder.WriteLine("mapUrl: " + ts.tryGetSourceMappingURL(ts.getLineInfo(jsFile.text, jsLineMap)));
|
||||
sourceMapRecorder.WriteLine("sourceRoot: " + sourceMapData.sourceMap.sourceRoot);
|
||||
sourceMapRecorder.WriteLine("sources: " + sourceMapData.sourceMap.sources);
|
||||
if (sourceMapData.sourceMap.sourcesContent) {
|
||||
sourceMapRecorder.WriteLine("sourcesContent: " + JSON.stringify(sourceMapData.sourceMap.sourcesContent));
|
||||
}
|
||||
sourceMapRecorder.WriteLine("===================================================================");
|
||||
}
|
||||
|
||||
function getSourceMapSpanString(mapEntry: ts.SourceMapSpan, getAbsentNameIndex?: boolean) {
|
||||
let mapString = "Emitted(" + (mapEntry.emittedLine + 1) + ", " + (mapEntry.emittedColumn + 1) + ") Source(" + (mapEntry.sourceLine + 1) + ", " + (mapEntry.sourceColumn + 1) + ") + SourceIndex(" + mapEntry.sourceIndex + ")";
|
||||
if (mapEntry.nameIndex! >= 0 && mapEntry.nameIndex! < sourceMapNames!.length) {
|
||||
mapString += " name (" + sourceMapNames![mapEntry.nameIndex!] + ")";
|
||||
}
|
||||
else {
|
||||
if ((mapEntry.nameIndex && mapEntry.nameIndex !== -1) || getAbsentNameIndex) {
|
||||
mapString += " nameIndex (" + mapEntry.nameIndex + ")";
|
||||
function getSourceMapSpanString(mapEntry: ts.Mapping, getAbsentNameIndex?: boolean) {
|
||||
let mapString = "Emitted(" + (mapEntry.generatedLine + 1) + ", " + (mapEntry.generatedCharacter + 1) + ")";
|
||||
if (ts.isSourceMapping(mapEntry)) {
|
||||
mapString += " Source(" + (mapEntry.sourceLine + 1) + ", " + (mapEntry.sourceCharacter + 1) + ") + SourceIndex(" + mapEntry.sourceIndex + ")";
|
||||
if (mapEntry.nameIndex! >= 0 && mapEntry.nameIndex! < sourceMapNames!.length) {
|
||||
mapString += " name (" + sourceMapNames![mapEntry.nameIndex!] + ")";
|
||||
}
|
||||
else {
|
||||
if ((mapEntry.nameIndex && mapEntry.nameIndex !== -1) || getAbsentNameIndex) {
|
||||
mapString += " nameIndex (" + mapEntry.nameIndex + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mapString;
|
||||
}
|
||||
|
||||
export function recordSourceMapSpan(sourceMapSpan: ts.SourceMapSpan) {
|
||||
export function recordSourceMapSpan(sourceMapSpan: ts.Mapping) {
|
||||
// verify the decoded span is same as the new span
|
||||
const decodeResult = SourceMapDecoder.decodeNextEncodedSourceMapSpan();
|
||||
let decodeErrors: string[] | undefined;
|
||||
if (typeof decodeResult.error === "string"
|
||||
|| decodeResult.sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine
|
||||
|| decodeResult.sourceMapSpan.emittedColumn !== sourceMapSpan.emittedColumn
|
||||
|| decodeResult.sourceMapSpan.sourceLine !== sourceMapSpan.sourceLine
|
||||
|| decodeResult.sourceMapSpan.sourceColumn !== sourceMapSpan.sourceColumn
|
||||
|| decodeResult.sourceMapSpan.sourceIndex !== sourceMapSpan.sourceIndex
|
||||
|| decodeResult.sourceMapSpan.nameIndex !== sourceMapSpan.nameIndex) {
|
||||
if (typeof decodeResult.error === "string" || !ts.sameMapping(decodeResult.sourceMapSpan, sourceMapSpan)) {
|
||||
if (decodeResult.error) {
|
||||
decodeErrors = ["!!^^ !!^^ There was decoding error in the sourcemap at this location: " + decodeResult.error];
|
||||
}
|
||||
@@ -121,7 +109,7 @@ namespace Harness.SourceMapRecorder {
|
||||
decodeErrors.push("!!^^ !!^^ Decoded span from sourcemap's mappings entry: " + getSourceMapSpanString(decodeResult.sourceMapSpan, /*getAbsentNameIndex*/ true) + " Span encoded by the emitter:" + getSourceMapSpanString(sourceMapSpan, /*getAbsentNameIndex*/ true));
|
||||
}
|
||||
|
||||
if (spansOnSingleLine.length && spansOnSingleLine[0].sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine) {
|
||||
if (spansOnSingleLine.length && spansOnSingleLine[0].sourceMapSpan.generatedLine !== sourceMapSpan.generatedLine) {
|
||||
// On different line from the one that we have been recording till now,
|
||||
writeRecordedSpans();
|
||||
spansOnSingleLine = [];
|
||||
@@ -129,14 +117,21 @@ namespace Harness.SourceMapRecorder {
|
||||
spansOnSingleLine.push({ sourceMapSpan, decodeErrors });
|
||||
}
|
||||
|
||||
export function recordNewSourceFileSpan(sourceMapSpan: ts.SourceMapSpan, newSourceFileCode: string) {
|
||||
assert.isTrue(spansOnSingleLine.length === 0 || spansOnSingleLine[0].sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine, "new file source map span should be on new line. We currently handle only that scenario");
|
||||
export function recordNewSourceFileSpan(sourceMapSpan: ts.Mapping, newSourceFileCode: string) {
|
||||
let continuesLine = false;
|
||||
if (spansOnSingleLine.length > 0 && spansOnSingleLine[0].sourceMapSpan.generatedCharacter === sourceMapSpan.generatedLine) {
|
||||
writeRecordedSpans();
|
||||
spansOnSingleLine = [];
|
||||
nextJsLineToWrite--; // walk back one line to reprint the line
|
||||
continuesLine = true;
|
||||
}
|
||||
|
||||
recordSourceMapSpan(sourceMapSpan);
|
||||
|
||||
assert.isTrue(spansOnSingleLine.length === 1);
|
||||
sourceMapRecorder.WriteLine("-------------------------------------------------------------------");
|
||||
sourceMapRecorder.WriteLine("emittedFile:" + jsFile.file);
|
||||
sourceMapRecorder.WriteLine("sourceFile:" + sourceMapSources[spansOnSingleLine[0].sourceMapSpan.sourceIndex]);
|
||||
sourceMapRecorder.WriteLine("emittedFile:" + jsFile.file + (continuesLine ? ` (${sourceMapSpan.generatedLine + 1}, ${sourceMapSpan.generatedCharacter + 1})` : ""));
|
||||
sourceMapRecorder.WriteLine("sourceFile:" + sourceMapSources[spansOnSingleLine[0].sourceMapSpan.sourceIndex!]);
|
||||
sourceMapRecorder.WriteLine("-------------------------------------------------------------------");
|
||||
|
||||
tsLineMap = ts.computeLineStarts(newSourceFileCode);
|
||||
@@ -195,7 +190,7 @@ namespace Harness.SourceMapRecorder {
|
||||
prevEmittedCol = 0;
|
||||
for (let i = 0; i < spansOnSingleLine.length; i++) {
|
||||
fn(spansOnSingleLine[i], i);
|
||||
prevEmittedCol = spansOnSingleLine[i].sourceMapSpan.emittedColumn;
|
||||
prevEmittedCol = spansOnSingleLine[i].sourceMapSpan.generatedCharacter;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,7 +201,7 @@ namespace Harness.SourceMapRecorder {
|
||||
}
|
||||
}
|
||||
|
||||
function writeSourceMapMarker(currentSpan: SourceMapSpanWithDecodeErrors, index: number, endColumn = currentSpan.sourceMapSpan.emittedColumn, endContinues = false) {
|
||||
function writeSourceMapMarker(currentSpan: SourceMapSpanWithDecodeErrors, index: number, endColumn = currentSpan.sourceMapSpan.generatedCharacter, endContinues = false) {
|
||||
const markerId = getMarkerId(index);
|
||||
markerIds.push(markerId);
|
||||
|
||||
@@ -223,7 +218,7 @@ namespace Harness.SourceMapRecorder {
|
||||
}
|
||||
|
||||
function writeSourceMapSourceText(currentSpan: SourceMapSpanWithDecodeErrors, index: number) {
|
||||
const sourcePos = tsLineMap[currentSpan.sourceMapSpan.sourceLine] + (currentSpan.sourceMapSpan.sourceColumn);
|
||||
const sourcePos = tsLineMap[currentSpan.sourceMapSpan.sourceLine!] + (currentSpan.sourceMapSpan.sourceCharacter!);
|
||||
let sourceText = "";
|
||||
if (prevWrittenSourcePos < sourcePos) {
|
||||
// Position that goes forward, get text
|
||||
@@ -255,7 +250,7 @@ namespace Harness.SourceMapRecorder {
|
||||
}
|
||||
|
||||
if (spansOnSingleLine.length) {
|
||||
const currentJsLine = spansOnSingleLine[0].sourceMapSpan.emittedLine;
|
||||
const currentJsLine = spansOnSingleLine[0].sourceMapSpan.generatedLine;
|
||||
|
||||
// Write js line
|
||||
writeJsFileLines(currentJsLine + 1);
|
||||
@@ -280,14 +275,14 @@ namespace Harness.SourceMapRecorder {
|
||||
}
|
||||
}
|
||||
|
||||
export function getSourceMapRecord(sourceMapDataList: ReadonlyArray<ts.SourceMapData>, program: ts.Program, jsFiles: ReadonlyArray<documents.TextDocument>, declarationFiles: ReadonlyArray<documents.TextDocument>) {
|
||||
export function getSourceMapRecord(sourceMapDataList: ReadonlyArray<ts.SourceMapEmitResult>, program: ts.Program, jsFiles: ReadonlyArray<documents.TextDocument>, declarationFiles: ReadonlyArray<documents.TextDocument>) {
|
||||
const sourceMapRecorder = new Compiler.WriterAggregator();
|
||||
|
||||
for (let i = 0; i < sourceMapDataList.length; i++) {
|
||||
const sourceMapData = sourceMapDataList[i];
|
||||
let prevSourceFile: ts.SourceFile | undefined;
|
||||
let currentFile: documents.TextDocument;
|
||||
if (ts.endsWith(sourceMapData.sourceMapFile, ts.Extension.Dts)) {
|
||||
if (ts.endsWith(sourceMapData.sourceMap.file, ts.Extension.Dts)) {
|
||||
if (sourceMapDataList.length > jsFiles.length) {
|
||||
currentFile = declarationFiles[Math.floor(i / 2)]; // When both kinds of source map are present, they alternate js/dts
|
||||
}
|
||||
@@ -305,11 +300,15 @@ namespace Harness.SourceMapRecorder {
|
||||
}
|
||||
|
||||
SourceMapSpanWriter.initializeSourceMapSpanWriter(sourceMapRecorder, sourceMapData, currentFile);
|
||||
const mapper = ts.sourcemaps.decodeMappings({ mappings: sourceMapData.sourceMapMappings, sources: sourceMapData.sourceMapSources });
|
||||
const mapper = ts.decodeMappings(sourceMapData.sourceMap.mappings);
|
||||
for (let { value: decodedSourceMapping, done } = mapper.next(); !done; { value: decodedSourceMapping, done } = mapper.next()) {
|
||||
const currentSourceFile = program.getSourceFile(sourceMapData.inputSourceFileNames[decodedSourceMapping.sourceIndex])!;
|
||||
const currentSourceFile = ts.isSourceMapping(decodedSourceMapping)
|
||||
? program.getSourceFile(sourceMapData.inputSourceFileNames[decodedSourceMapping.sourceIndex])
|
||||
: undefined;
|
||||
if (currentSourceFile !== prevSourceFile) {
|
||||
SourceMapSpanWriter.recordNewSourceFileSpan(decodedSourceMapping, currentSourceFile.text);
|
||||
if (currentSourceFile) {
|
||||
SourceMapSpanWriter.recordNewSourceFileSpan(decodedSourceMapping, currentSourceFile.text);
|
||||
}
|
||||
prevSourceFile = currentSourceFile;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -21,11 +21,11 @@ interface TypeWriterResult {
|
||||
}
|
||||
|
||||
class TypeWriterWalker {
|
||||
currentSourceFile: ts.SourceFile;
|
||||
currentSourceFile!: ts.SourceFile;
|
||||
|
||||
private checker: ts.TypeChecker;
|
||||
|
||||
constructor(private program: ts.Program, fullTypeCheck: boolean) {
|
||||
constructor(private program: ts.Program, fullTypeCheck: boolean, private hadErrorBaseline: boolean) {
|
||||
// Consider getting both the diagnostics checker and the non-diagnostics checker to verify
|
||||
// they are consistent.
|
||||
this.checker = fullTypeCheck
|
||||
@@ -69,6 +69,26 @@ class TypeWriterWalker {
|
||||
}
|
||||
}
|
||||
|
||||
private isImportStatementName(node: ts.Node) {
|
||||
if (ts.isImportSpecifier(node.parent) && (node.parent.name === node || node.parent.propertyName === node)) return true;
|
||||
if (ts.isImportClause(node.parent) && node.parent.name === node) return true;
|
||||
if (ts.isImportEqualsDeclaration(node.parent) && node.parent.name === node) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private isExportStatementName(node: ts.Node) {
|
||||
if (ts.isExportAssignment(node.parent) && node.parent.expression === node) return true;
|
||||
if (ts.isExportSpecifier(node.parent) && (node.parent.name === node || node.parent.propertyName === node)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private isIntrinsicJsxTag(node: ts.Node) {
|
||||
const p = node.parent;
|
||||
if (!(ts.isJsxOpeningElement(p) || ts.isJsxClosingElement(p) || ts.isJsxSelfClosingElement(p))) return false;
|
||||
if (p.tagName !== node) return false;
|
||||
return ts.isIntrinsicJsxName(node.getText());
|
||||
}
|
||||
|
||||
private writeTypeOrSymbol(node: ts.Node, isSymbolWalk: boolean): TypeWriterResult | undefined {
|
||||
const actualPos = ts.skipTrivia(this.currentSourceFile.text, node.pos);
|
||||
const lineAndCharacter = this.currentSourceFile.getLineAndCharacterOfPosition(actualPos);
|
||||
@@ -85,7 +105,31 @@ class TypeWriterWalker {
|
||||
// let type = this.checker.getTypeAtLocation(node);
|
||||
let type = ts.isExpressionWithTypeArgumentsInClassExtendsClause(node.parent) ? this.checker.getTypeAtLocation(node.parent) : undefined;
|
||||
if (!type || type.flags & ts.TypeFlags.Any) type = this.checker.getTypeAtLocation(node);
|
||||
const typeString = this.checker.typeToString(type, node.parent, ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.AllowUniqueESSymbolType);
|
||||
const typeString =
|
||||
// Distinguish `errorType`s from `any`s; but only if the file has no errors.
|
||||
// Additionally,
|
||||
// * the LHS of a qualified name
|
||||
// * a binding pattern name
|
||||
// * labels
|
||||
// * the "global" in "declare global"
|
||||
// * the "target" in "new.target"
|
||||
// * names in import statements
|
||||
// * type-only names in export statements
|
||||
// * and intrinsic jsx tag names
|
||||
// return `error`s via `getTypeAtLocation`
|
||||
// But this is generally expected, so we don't call those out, either
|
||||
(!this.hadErrorBaseline &&
|
||||
type.flags & ts.TypeFlags.Any &&
|
||||
!ts.isBindingElement(node.parent) &&
|
||||
!ts.isPropertyAccessOrQualifiedName(node.parent) &&
|
||||
!ts.isLabelName(node) &&
|
||||
!(ts.isModuleDeclaration(node.parent) && ts.isGlobalScopeAugmentation(node.parent)) &&
|
||||
!ts.isMetaProperty(node.parent) &&
|
||||
!this.isImportStatementName(node) &&
|
||||
!this.isExportStatementName(node) &&
|
||||
!this.isIntrinsicJsxTag(node)) ?
|
||||
(type as ts.IntrinsicType).intrinsicName :
|
||||
this.checker.typeToString(type, node.parent, ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.AllowUniqueESSymbolType);
|
||||
return {
|
||||
line: lineAndCharacter.line,
|
||||
syntaxKind: node.kind,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user