mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge remote-tracking branch 'origin/master' into overlappyTypes
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.2.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
-2
@@ -1,8 +1,8 @@
|
||||
language: node_js
|
||||
|
||||
node_js:
|
||||
- 'stable'
|
||||
- '8'
|
||||
- 'node'
|
||||
- '10'
|
||||
- '6'
|
||||
|
||||
sudo: false
|
||||
@@ -20,6 +20,7 @@ branches:
|
||||
- release-2.8
|
||||
- release-2.9
|
||||
- release-3.0
|
||||
- release-3.1
|
||||
|
||||
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.
|
||||
+6
-6
@@ -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
|
||||
@@ -104,7 +104,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 +137,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 +153,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 +194,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).
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ const exec = require("./scripts/build/exec");
|
||||
const browserify = require("./scripts/build/browserify");
|
||||
const prepend = require("./scripts/build/prepend");
|
||||
const { removeSourceMaps } = require("./scripts/build/sourcemaps");
|
||||
const { CancellationTokenSource, CancelError, delay, Semaphore } = require("prex");
|
||||
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");
|
||||
|
||||
|
||||
+2
-3
@@ -147,14 +147,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 +520,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;
|
||||
|
||||
@@ -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
|
||||
|
||||
+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
|
||||
|
||||
|
||||
@@ -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}\".",
|
||||
|
||||
@@ -135,9 +135,9 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_1254" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_or_literal_enum_refere_1254" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A 'const' initializer in an ambient context must be a string or numeric literal.]]></Val>
|
||||
<Val><![CDATA[A 'const' initializer in an ambient context must be a string or numeric literal or literal enum reference.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -741,6 +741,18 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Add_unknown_conversion_for_non_overlapping_types_95069" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add 'unknown' conversion for non-overlapping types]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Add_unknown_to_all_conversions_of_non_overlapping_types_95070" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add 'unknown' to all conversions of non-overlapping types]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript__5068" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.]]></Val>
|
||||
@@ -861,9 +873,21 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type_2356" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";An_argument_for_0_was_not_provided_6210" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[An arithmetic operand must be of type 'any', 'number' or an enum type.]]></Val>
|
||||
<Val><![CDATA[An argument for '{0}' was not provided.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";An_argument_matching_this_binding_pattern_was_not_provided_6211" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[An argument matching this binding pattern was not provided.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type_2356" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -1095,6 +1119,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";An_outer_value_of_this_is_shadowed_by_this_container_2738" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[An outer value of 'this' is shadowed by this container.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";An_overload_signature_cannot_be_declared_as_a_generator_1222" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[An overload signature cannot be declared as a generator.]]></Val>
|
||||
@@ -1203,6 +1233,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";BigInt_literals_are_not_available_when_targeting_lower_than_ESNext_2737" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[BigInt literals are not available when targeting lower than ESNext.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Binary_digit_expected_1177" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Binary digit expected.]]></Val>
|
||||
@@ -1233,6 +1269,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Build_option_0_requires_a_value_of_type_1_5073" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Build option '{0}' requires a value of type {1}.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Building_project_0_6358" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Building project '{0}'...]]></Val>
|
||||
@@ -1401,6 +1443,36 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_2583" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Cannot find name '{0}'. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_2584" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Cannot find name '{0}'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_types_Slashje_2582" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[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.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_types_Slashjquery_an_2581" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[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.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_types_Slashnode_and_th_2580" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[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.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Cannot_find_namespace_0_2503" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Cannot find namespace '{0}'.]]></Val>
|
||||
@@ -2001,6 +2073,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Did_you_mean_for_0_to_be_constrained_to_type_new_args_Colon_any_1_2735" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Did you mean for '{0}' to be constrained to type 'new (...args: any[]5D;) => {1}'?]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Did_you_mean_to_call_this_expression_6212" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Did you mean to call this expression?]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Did_you_mean_to_use_new_with_this_expression_6213" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Did you mean to use 'new' with this expression?]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Digit_expected_1124" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Digit expected.]]></Val>
|
||||
@@ -2259,6 +2349,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Enable_strict_bind_call_and_apply_methods_on_functions_6214" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Enable strict 'bind', 'call', and 'apply' methods on functions.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Enable_strict_checking_of_function_types_6186" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Enable strict checking of function types.]]></Val>
|
||||
@@ -2349,6 +2445,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Enum_type_0_circularly_references_itself_2586" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Enum type '{0}' circularly references itself.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Enum_type_0_has_members_with_initializers_that_are_not_literals_2535" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Enum type '{0}' has members with initializers that are not literals.]]></Val>
|
||||
@@ -2421,9 +2523,9 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_type_of_0_field_in_package_json_to_be_string_got_1_6105" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Expected_type_of_0_field_in_package_json_to_be_1_got_2_6105" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected type of '{0}' field in 'package.json' to be 'string', got '{1}'.]]></Val>
|
||||
<Val><![CDATA[Expected type of '{0}' field in 'package.json' to be '{1}', got '{2}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -2691,12 +2793,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Found_0_errors_6217" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Found {0} errors.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Found_0_errors_Watching_for_file_changes_6194" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Found {0} errors. Watching for file changes.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Found_1_error_6216" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Found 1 error.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Found_1_error_Watching_for_file_changes_6193" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Found 1 error. Watching for file changes.]]></Val>
|
||||
@@ -2775,12 +2889,30 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Function_type_which_lacks_return_type_annotation_implicitly_has_an_0_return_type_7014" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Function type, which lacks return-type annotation, implicitly has an '{0}' return type.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Generate_get_and_set_accessors_95046" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Generate 'get' and 'set' accessors]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Generate_types_for_0_95067" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Generate types for '{0}']]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Generate_types_for_all_packages_without_types_95068" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Generate types for all packages without types]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Generates_a_sourcemap_for_each_corresponding_d_ts_file_6000" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Generates a sourcemap for each corresponding '.d.ts' file.]]></Val>
|
||||
@@ -2829,12 +2961,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Generic_type_instantiation_is_excessively_deep_and_possibly_infinite_2550" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Generic type instantiation is excessively deep and possibly infinite.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Getter_and_setter_accessors_do_not_agree_in_visibility_2379" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Getter and setter accessors do not agree in visibility.]]></Val>
|
||||
@@ -3225,6 +3351,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";It_is_highly_likely_that_you_are_missing_a_semicolon_2734" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[It is highly likely that you are missing a semicolon.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_0_1_does_not_match_the_extends_2_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@{0} {1}' does not match the 'extends {2}' clause.]]></Val>
|
||||
@@ -3255,6 +3387,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_type_0_circularly_references_itself_2587" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc type '{0}' circularly references itself.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags_8021" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@typedef' tag should either have a type annotation or be followed by '@property' or '@member' tags.]]></Val>
|
||||
@@ -3483,6 +3621,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Member_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage_7045" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Member '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Merge_conflict_marker_encountered_1185" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Merge conflict marker encountered.]]></Val>
|
||||
@@ -3705,6 +3849,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Non_simple_parameter_declared_here_1348" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Non-simple parameter declared here.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Not_all_code_paths_return_a_value_7030" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Not all code paths return a value.]]></Val>
|
||||
@@ -3843,6 +3993,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Operator_0_cannot_be_applied_to_type_1_2736" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Operator '{0}' cannot be applied to type '{1}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Operator_0_cannot_be_applied_to_types_1_and_2_2365" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Operator '{0}' cannot be applied to types '{1}' and '{2}'.]]></Val>
|
||||
@@ -3909,9 +4065,9 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs_5071" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs_amd_es2015_or_5071" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.]]></Val>
|
||||
<Val><![CDATA[Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -3999,6 +4155,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage_7044" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Parameter_0_is_not_in_the_same_position_as_parameter_1_1227" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter '{0}' is not in the same position as parameter '{1}'.]]></Val>
|
||||
@@ -4203,6 +4365,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Print_the_final_configuration_instead_of_building_1350" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Print the final configuration instead of building.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Print_this_message_6017" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Print this message.]]></Val>
|
||||
@@ -4317,6 +4485,18 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Property_0_implicitly_has_type_any_but_a_better_type_for_its_get_accessor_may_be_inferred_from_usage_7048" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Property '{0}' implicitly has type 'any', but a better type for its get accessor may be inferred from usage.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Property_0_implicitly_has_type_any_but_a_better_type_for_its_set_accessor_may_be_inferred_from_usage_7049" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Property '{0}' implicitly has type 'any', but a better type for its set accessor may be inferred from usage.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2_2416" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Property '{0}' in type '{1}' is not assignable to the same property in base type '{2}'.]]></Val>
|
||||
@@ -4359,6 +4539,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Property_0_is_missing_in_type_1_but_required_in_type_2_2741" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Property '{0}' is missing in type '{1}' but required in type '{2}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Property_0_is_optional_in_type_1_but_required_in_type_2_2327" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Property '{0}' is optional in type '{1}' but required in type '{2}'.]]></Val>
|
||||
@@ -4773,6 +4959,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage_7047" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Rest parameter '{0}' implicitly has an 'any[]5D;' type, but a better type may be inferred from usage.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Rest_signatures_are_incompatible_2572" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Rest signatures are incompatible.]]></Val>
|
||||
@@ -5025,12 +5217,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Skipping_clean_because_not_all_projects_could_be_located_6371" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Skipping clean because not all projects could be located]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Source_Map_Options_6175" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Source Map Options]]></Val>
|
||||
@@ -5313,6 +5499,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";The_expected_type_comes_from_the_return_type_of_this_signature_6502" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[The expected type comes from the return type of this signature.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";The_expected_type_comes_from_this_index_signature_6501" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[The expected type comes from this index signature.]]></Val>
|
||||
@@ -5391,9 +5583,9 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type_2362" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type_2362" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.]]></Val>
|
||||
<Val><![CDATA[The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -5481,9 +5673,9 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type_2363" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type_2363" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.]]></Val>
|
||||
<Val><![CDATA[The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -5589,6 +5781,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_parameter_is_not_allowed_with_use_strict_directive_1346" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This parameter is not allowed with 'use strict' directive.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found_2354" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This syntax requires an imported helper but module '{0}' cannot be found.]]></Val>
|
||||
@@ -5679,6 +5877,18 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_missing_the_following_properties_from_type_1_Colon_2_2739" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is missing the following properties from type '{1}': {2}]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more_2740" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is missing the following properties from type '{1}': {2}, and {3} more.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_a_constructor_function_type_2507" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not a constructor function type.]]></Val>
|
||||
@@ -6051,6 +6261,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Unknown_build_option_0_5072" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Unknown build option '{0}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Unknown_compiler_option_0_5023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Unknown compiler option '{0}'.]]></Val>
|
||||
@@ -6141,6 +6357,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Using_compiler_options_of_project_reference_redirect_0_6215" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Using compiler options of project reference redirect '{0}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";VERSION_6036" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[VERSION]]></Val>
|
||||
@@ -6165,6 +6387,18 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Variable_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage_7043" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Variable '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Variable_0_implicitly_has_type_1_in_some_locations_but_a_better_type_may_be_inferred_from_usage_7046" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Variable '{0}' implicitly has type '{1}' in some locations, but a better type may be inferred from usage.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined_7034" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Variable '{0}' implicitly has type '{1}' in some locations where its type cannot be determined.]]></Val>
|
||||
@@ -6207,6 +6441,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";You_cannot_rename_a_module_via_a_global_import_8031" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[You cannot rename a module via a global import.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library_8001" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[You cannot rename elements that are defined in the standard TypeScript library.]]></Val>
|
||||
@@ -6243,6 +6483,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_implicitly_has_an_1_return_type_but_a_better_type_may_be_inferred_from_usage_7050" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' implicitly has an '{1}' return type, but a better type may be inferred from usage.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_reference_7023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.]]></Val>
|
||||
@@ -6393,6 +6639,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Do_you_need_to_change_your_target_library_2585" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{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.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead_2686" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' refers to a UMD global, but the current file is a module. Consider adding an import instead.]]></Val>
|
||||
@@ -6657,12 +6909,36 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";package_json_does_not_have_a_typesVersions_entry_that_matches_version_0_6207" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['package.json' does not have a 'typesVersions' entry that matches version '{0}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";package_json_has_0_field_1_that_references_2_6101" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['package.json' has '{0}' field '{1}' that references '{2}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";package_json_has_a_typesVersions_entry_0_that_is_not_a_valid_semver_range_6209" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['package.json' has a 'typesVersions' entry '{0}' that is not a valid semver range.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_ma_6208" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['package.json' has a 'typesVersions' entry '{0}' that matches compiler version '{1}', looking for a pattern to match module name '{2}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";package_json_has_a_typesVersions_field_with_version_specific_path_mappings_6206" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['package.json' has a 'typesVersions' field with version-specific path mappings.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";parameter_modifiers_can_only_be_used_in_a_ts_file_8012" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['parameter modifiers' can only be used in a .ts file.]]></Val>
|
||||
@@ -6831,6 +7107,18 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";use_strict_directive_cannot_be_used_with_non_simple_parameter_list_1347" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['use strict' directive cannot be used with non-simple parameter list.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";use_strict_directive_used_here_1349" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['use strict' directive used here.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";with_statements_are_not_allowed_in_an_async_function_block_1300" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['with' statements are not allowed in an async function block.]]></Val>
|
||||
|
||||
@@ -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
+517
-299
File diff suppressed because it is too large
Load Diff
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
+71
-1
@@ -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;
|
||||
@@ -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
+1296
-13
File diff suppressed because it is too large
Load Diff
Vendored
+67
-8
@@ -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.
|
||||
@@ -781,7 +786,7 @@ declare namespace ts.server.protocol {
|
||||
/**
|
||||
* The file locations referencing the symbol.
|
||||
*/
|
||||
refs: ReferencesResponseItem[];
|
||||
refs: ReadonlyArray<ReferencesResponseItem>;
|
||||
/**
|
||||
* The name of the symbol.
|
||||
*/
|
||||
@@ -827,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.
|
||||
*/
|
||||
@@ -852,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'.
|
||||
@@ -860,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 {
|
||||
/**
|
||||
@@ -995,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.
|
||||
*/
|
||||
@@ -1373,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;
|
||||
}
|
||||
/**
|
||||
@@ -1832,6 +1860,7 @@ declare namespace ts.server.protocol {
|
||||
*/
|
||||
interface DiagnosticEvent extends Event {
|
||||
body?: DiagnosticEventBody;
|
||||
event: DiagnosticEventKind;
|
||||
}
|
||||
interface ConfigFileDiagnosticEventBody {
|
||||
/**
|
||||
@@ -1885,6 +1914,35 @@ 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;
|
||||
@@ -2220,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;
|
||||
|
||||
@@ -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",
|
||||
|
||||
+15110
-12145
File diff suppressed because it is too large
Load Diff
+22227
-17693
File diff suppressed because it is too large
Load Diff
Vendored
+740
-774
File diff suppressed because it is too large
Load Diff
+22357
-17802
File diff suppressed because it is too large
Load Diff
Vendored
+612
-725
File diff suppressed because it is too large
Load Diff
+21694
-17419
File diff suppressed because it is too large
Load Diff
Vendored
+612
-725
File diff suppressed because it is too large
Load Diff
+21694
-17419
File diff suppressed because it is too large
Load Diff
+16680
-13557
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": "新行",
|
||||
|
||||
+3
-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.2.0",
|
||||
"license": "Apache-2.0",
|
||||
"description": "TypeScript is a language for application scale JavaScript development",
|
||||
"keywords": [
|
||||
@@ -75,6 +75,7 @@
|
||||
"gulp-typescript": "latest",
|
||||
"istanbul": "latest",
|
||||
"jake": "latest",
|
||||
"lodash": "4.17.10",
|
||||
"merge2": "latest",
|
||||
"minimist": "latest",
|
||||
"mkdirp": "latest",
|
||||
|
||||
@@ -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) {
|
||||
|
||||
+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;
|
||||
+134
-69
@@ -234,13 +234,17 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (symbolFlags & SymbolFlags.Value) {
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -636,6 +640,7 @@ namespace ts {
|
||||
function bindChildrenWorker(node: Node): void {
|
||||
if (checkUnreachable(node)) {
|
||||
bindEachChild(node);
|
||||
bindJSDoc(node);
|
||||
return;
|
||||
}
|
||||
switch (node.kind) {
|
||||
@@ -1176,7 +1181,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];
|
||||
@@ -1375,6 +1379,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindJSDocTypeAlias(node: JSDocTypedefTag | JSDocCallbackTag) {
|
||||
node.tagName.parent = node;
|
||||
if (node.fullName) {
|
||||
setParentPointers(node, node.fullName);
|
||||
}
|
||||
@@ -2108,7 +2113,7 @@ namespace ts {
|
||||
// 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:
|
||||
@@ -2184,6 +2189,19 @@ namespace ts {
|
||||
return bindFunctionExpression(<FunctionExpression>node);
|
||||
|
||||
case SyntaxKind.CallExpression:
|
||||
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);
|
||||
}
|
||||
@@ -2286,14 +2304,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2301,27 +2324,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) {
|
||||
@@ -2352,6 +2365,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
|
||||
@@ -2390,7 +2419,7 @@ 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) {
|
||||
@@ -2456,7 +2485,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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2477,6 +2511,12 @@ 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;
|
||||
@@ -2508,25 +2548,27 @@ namespace ts {
|
||||
bindPropertyAssignment(node.expression, node, /*isPrototypeProperty*/ false);
|
||||
}
|
||||
|
||||
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;
|
||||
if (!isPrototypeProperty && (!namespaceSymbol || !(namespaceSymbol.flags & SymbolFlags.Namespace)) && isToplevel) {
|
||||
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.Assignment;
|
||||
const excludeFlags = SymbolFlags.ValueModuleExcludes & ~SymbolFlags.Assignment;
|
||||
namespaceSymbol = forEachIdentifierInEntityName(propertyAccess.expression, namespaceSymbol, (id, symbol, parent) => {
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
return namespaceSymbol;
|
||||
}
|
||||
|
||||
function bindPotentiallyNewExpandoMemberToNamespace(declaration: PropertyAccessEntityNameExpression | CallExpression, namespaceSymbol: Symbol | undefined, isPrototypeProperty: boolean) {
|
||||
if (!namespaceSymbol || !isExpandoSymbol(namespaceSymbol)) {
|
||||
return;
|
||||
}
|
||||
@@ -2536,10 +2578,19 @@ namespace ts {
|
||||
(namespaceSymbol.members || (namespaceSymbol.members = createSymbolTable())) :
|
||||
(namespaceSymbol.exports || (namespaceSymbol.exports = createSymbolTable()));
|
||||
|
||||
const isMethod = isFunctionLikeDeclaration(getAssignedExpandoInitializer(propertyAccess)!);
|
||||
const isMethod = isFunctionLikeDeclaration(getAssignedExpandoInitializer(declaration)!);
|
||||
const includes = isMethod ? SymbolFlags.Method : SymbolFlags.Property;
|
||||
const excludes = isMethod ? SymbolFlags.MethodExcludes : SymbolFlags.PropertyExcludes;
|
||||
declareSymbol(symbolTable, namespaceSymbol, propertyAccess, includes | SymbolFlags.Assignment, excludes & ~SymbolFlags.Assignment);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2557,6 +2608,9 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
const node = symbol.valueDeclaration;
|
||||
if (isCallExpression(node)) {
|
||||
return !!getAssignedExpandoInitializer(node);
|
||||
}
|
||||
let init = !node ? undefined :
|
||||
isVariableDeclaration(node) ? node.initializer :
|
||||
isBinaryExpression(node) ? node.right :
|
||||
@@ -2657,7 +2711,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (!isBindingPattern(node.name)) {
|
||||
const isEnum = !!getJSDocEnumTag(node);
|
||||
const isEnum = isInJSFile(node) && !!getJSDocEnumTag(node);
|
||||
const enumFlags = (isEnum ? SymbolFlags.RegularEnum : SymbolFlags.None);
|
||||
const enumExcludes = (isEnum ? SymbolFlags.RegularEnumExcludes : SymbolFlags.None);
|
||||
if (isBlockOrCatchScoped(node)) {
|
||||
@@ -2868,7 +2922,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isExportsOrModuleExportsOrAlias(sourceFile: SourceFile, node: Expression): boolean {
|
||||
return isExportsIdentifier(node) ||
|
||||
isModuleExportsPropertyAccessExpression(node) ||
|
||||
@@ -2892,6 +2945,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);
|
||||
}
|
||||
|
||||
@@ -2996,7 +3052,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.
|
||||
@@ -3027,7 +3083,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;
|
||||
@@ -3070,18 +3126,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;
|
||||
}
|
||||
|
||||
@@ -3134,7 +3190,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;
|
||||
}
|
||||
@@ -3156,7 +3212,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;
|
||||
}
|
||||
@@ -3233,7 +3289,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// function declarations with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@@ -3257,7 +3313,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// function declarations with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@@ -3288,7 +3344,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// function declarations with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@@ -3303,7 +3359,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;
|
||||
@@ -3337,7 +3393,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// function declarations with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@@ -3379,7 +3435,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// function expressions with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@@ -3420,7 +3476,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// arrow functions with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@@ -3440,7 +3496,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;
|
||||
@@ -3456,7 +3514,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;
|
||||
@@ -3468,7 +3528,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;
|
||||
}
|
||||
|
||||
@@ -3642,6 +3702,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) {
|
||||
@@ -3658,6 +3722,7 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.AnyKeyword:
|
||||
case SyntaxKind.NumberKeyword:
|
||||
case SyntaxKind.BigIntKeyword:
|
||||
case SyntaxKind.NeverKeyword:
|
||||
case SyntaxKind.ObjectKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
@@ -3717,11 +3782,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:
|
||||
@@ -3737,8 +3802,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;
|
||||
@@ -3751,13 +3816,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:
|
||||
@@ -3774,7 +3839,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;
|
||||
@@ -3785,7 +3850,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;
|
||||
@@ -3833,7 +3898,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;
|
||||
@@ -3866,6 +3930,7 @@ namespace ts {
|
||||
return TransformFlags.MethodOrAccessorExcludes;
|
||||
case SyntaxKind.AnyKeyword:
|
||||
case SyntaxKind.NumberKeyword:
|
||||
case SyntaxKind.BigIntKeyword:
|
||||
case SyntaxKind.NeverKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
case SyntaxKind.ObjectKeyword:
|
||||
|
||||
+84
-18
@@ -38,6 +38,10 @@ namespace ts {
|
||||
* 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
|
||||
*/
|
||||
@@ -64,9 +68,11 @@ namespace ts {
|
||||
state.semanticDiagnosticsPerFile = createMap<ReadonlyArray<Diagnostic>>();
|
||||
}
|
||||
state.changedFilesSet = createMap<true>();
|
||||
|
||||
const useOldState = BuilderState.canReuseOldState(state.referencedMap, oldState);
|
||||
const oldCompilerOptions = useOldState ? oldState!.program.getCompilerOptions() : undefined;
|
||||
const canCopySemanticDiagnostics = useOldState && oldState!.semanticDiagnosticsPerFile && !!state.semanticDiagnosticsPerFile &&
|
||||
!compilerOptionsAffectSemanticDiagnostics(compilerOptions, oldState!.program.getCompilerOptions());
|
||||
!compilerOptionsAffectSemanticDiagnostics(compilerOptions, oldCompilerOptions!);
|
||||
if (useOldState) {
|
||||
// Verify the sanity of old state
|
||||
if (!oldState!.currentChangedFilePath) {
|
||||
@@ -83,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;
|
||||
@@ -101,6 +109,11 @@ 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) {
|
||||
@@ -193,6 +206,19 @@ namespace ts {
|
||||
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
|
||||
|
||||
@@ -201,12 +227,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
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)
|
||||
removeSemanticDiagnosticsOfFilesReferencingPath(state, exportedFromPath as Path, seenFileAndExportsOfFile)
|
||||
)) {
|
||||
return;
|
||||
}
|
||||
@@ -215,7 +242,7 @@ namespace ts {
|
||||
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)
|
||||
removeSemanticDiagnosticsOfFilesReferencingPath(state, exportedFromPath as Path, seenFileAndExportsOfFile)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -223,9 +250,41 @@ namespace ts {
|
||||
* 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) {
|
||||
function removeSemanticDiagnosticsOfFilesReferencingPath(state: BuilderProgramState, referencedPath: Path, seenFileAndExportsOfFile: Map<true>) {
|
||||
return forEachEntry(state.referencedMap!, (referencesInFile, filePath) =>
|
||||
referencesInFile.has(referencedPath) && removeSemanticDiagnosticsOf(state, filePath as Path)
|
||||
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)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -235,7 +294,7 @@ namespace ts {
|
||||
*/
|
||||
function removeSemanticDiagnosticsOf(state: BuilderProgramState, path: Path) {
|
||||
if (!state.semanticDiagnosticsFromOldState) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
state.semanticDiagnosticsFromOldState.delete(path);
|
||||
state.semanticDiagnosticsPerFile!.delete(path);
|
||||
@@ -294,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;
|
||||
@@ -307,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 {
|
||||
@@ -410,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[] = [];
|
||||
@@ -623,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));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -633,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,
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace ts.BuilderState {
|
||||
function getReferencedFileFromImportedModuleSymbol(symbol: Symbol) {
|
||||
if (symbol.declarations && symbol.declarations[0]) {
|
||||
const declarationSourceFile = getSourceFileOfNode(symbol.declarations[0]);
|
||||
return declarationSourceFile && declarationSourceFile.path;
|
||||
return declarationSourceFile && declarationSourceFile.resolvedPath;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,6 +100,13 @@ namespace ts.BuilderState {
|
||||
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
|
||||
*/
|
||||
@@ -123,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);
|
||||
}
|
||||
}
|
||||
@@ -136,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>();
|
||||
@@ -254,6 +292,11 @@ 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);
|
||||
@@ -325,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);
|
||||
}
|
||||
|
||||
@@ -387,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
|
||||
*/
|
||||
@@ -430,7 +489,7 @@ 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, exportedModulesMapCache: ComputingExportedModulesMap | undefined) {
|
||||
if (!isExternalModule(sourceFileWithUpdatedShape) && !containsOnlyAmbientModules(sourceFileWithUpdatedShape)) {
|
||||
if (isFileAffectingGlobalScope(sourceFileWithUpdatedShape)) {
|
||||
return getAllFilesExcludingDefaultLibraryFile(state, programOfThisState, sourceFileWithUpdatedShape);
|
||||
}
|
||||
|
||||
|
||||
+2200
-1512
File diff suppressed because it is too large
Load Diff
+337
-160
@@ -44,7 +44,8 @@ namespace ts {
|
||||
["esnext.array", "lib.esnext.array.d.ts"],
|
||||
["esnext.symbol", "lib.esnext.symbol.d.ts"],
|
||||
["esnext.asynciterable", "lib.esnext.asynciterable.d.ts"],
|
||||
["esnext.intl", "lib.esnext.intl.d.ts"]
|
||||
["esnext.intl", "lib.esnext.intl.d.ts"],
|
||||
["esnext.bigint", "lib.esnext.bigint.d.ts"]
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -62,7 +63,8 @@ namespace ts {
|
||||
/* @internal */
|
||||
export const libMap = createMapFromEntries(libEntries);
|
||||
|
||||
const commonOptionsWithBuild: CommandLineOption[] = [
|
||||
/* @internal */
|
||||
export const commonOptionsWithBuild: CommandLineOption[] = [
|
||||
{
|
||||
name: "help",
|
||||
shortName: "h",
|
||||
@@ -76,6 +78,14 @@ namespace ts {
|
||||
shortName: "?",
|
||||
type: "boolean"
|
||||
},
|
||||
{
|
||||
name: "watch",
|
||||
shortName: "w",
|
||||
type: "boolean",
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Command_line_Options,
|
||||
description: Diagnostics.Watch_input_files,
|
||||
},
|
||||
{
|
||||
name: "preserveWatchOutput",
|
||||
type: "boolean",
|
||||
@@ -84,12 +94,30 @@ namespace ts {
|
||||
description: Diagnostics.Whether_to_keep_outdated_console_output_in_watch_mode_instead_of_clearing_the_screen,
|
||||
},
|
||||
{
|
||||
name: "watch",
|
||||
shortName: "w",
|
||||
name: "listFiles",
|
||||
type: "boolean",
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Print_names_of_files_part_of_the_compilation
|
||||
},
|
||||
{
|
||||
name: "listEmittedFiles",
|
||||
type: "boolean",
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Print_names_of_generated_files_part_of_the_compilation
|
||||
},
|
||||
{
|
||||
name: "pretty",
|
||||
type: "boolean",
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Command_line_Options,
|
||||
description: Diagnostics.Watch_input_files,
|
||||
description: Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental
|
||||
},
|
||||
|
||||
{
|
||||
name: "traceResolution",
|
||||
type: "boolean",
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Enable_tracing_of_the_name_resolution_process
|
||||
},
|
||||
];
|
||||
|
||||
@@ -138,11 +166,11 @@ namespace ts {
|
||||
description: Diagnostics.Build_one_or_more_projects_and_their_dependencies_if_out_of_date
|
||||
},
|
||||
{
|
||||
name: "pretty",
|
||||
name: "showConfig",
|
||||
type: "boolean",
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Command_line_Options,
|
||||
description: Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental
|
||||
isCommandLineOnly: true,
|
||||
description: Diagnostics.Print_the_final_configuration_instead_of_building
|
||||
},
|
||||
|
||||
// Basic
|
||||
@@ -159,6 +187,8 @@ namespace ts {
|
||||
es2018: ScriptTarget.ES2018,
|
||||
esnext: ScriptTarget.ESNext,
|
||||
}),
|
||||
affectsSourceFile: true,
|
||||
affectsModuleResolution: true,
|
||||
paramType: Diagnostics.VERSION,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Basic_Options,
|
||||
@@ -177,6 +207,7 @@ namespace ts {
|
||||
es2015: ModuleKind.ES2015,
|
||||
esnext: ModuleKind.ESNext
|
||||
}),
|
||||
affectsModuleResolution: true,
|
||||
paramType: Diagnostics.KIND,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Basic_Options,
|
||||
@@ -189,6 +220,7 @@ namespace ts {
|
||||
name: "lib",
|
||||
type: libMap
|
||||
},
|
||||
affectsModuleResolution: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Basic_Options,
|
||||
description: Diagnostics.Specify_library_files_to_be_included_in_the_compilation
|
||||
@@ -196,6 +228,7 @@ namespace ts {
|
||||
{
|
||||
name: "allowJs",
|
||||
type: "boolean",
|
||||
affectsModuleResolution: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Basic_Options,
|
||||
description: Diagnostics.Allow_javascript_files_to_be_compiled
|
||||
@@ -213,6 +246,7 @@ namespace ts {
|
||||
"react-native": JsxEmit.ReactNative,
|
||||
"react": JsxEmit.React
|
||||
}),
|
||||
affectsSourceFile: true,
|
||||
paramType: Diagnostics.KIND,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Basic_Options,
|
||||
@@ -323,6 +357,7 @@ namespace ts {
|
||||
{
|
||||
name: "noImplicitAny",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
strictFlag: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
@@ -331,6 +366,7 @@ namespace ts {
|
||||
{
|
||||
name: "strictNullChecks",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
strictFlag: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
@@ -339,14 +375,24 @@ namespace ts {
|
||||
{
|
||||
name: "strictFunctionTypes",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
strictFlag: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
description: Diagnostics.Enable_strict_checking_of_function_types
|
||||
},
|
||||
{
|
||||
name: "strictBindCallApply",
|
||||
type: "boolean",
|
||||
strictFlag: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
description: Diagnostics.Enable_strict_bind_call_and_apply_methods_on_functions
|
||||
},
|
||||
{
|
||||
name: "strictPropertyInitialization",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
strictFlag: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
@@ -355,6 +401,7 @@ namespace ts {
|
||||
{
|
||||
name: "noImplicitThis",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
strictFlag: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
@@ -363,6 +410,7 @@ namespace ts {
|
||||
{
|
||||
name: "alwaysStrict",
|
||||
type: "boolean",
|
||||
affectsSourceFile: true,
|
||||
strictFlag: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
@@ -397,6 +445,7 @@ namespace ts {
|
||||
{
|
||||
name: "noFallthroughCasesInSwitch",
|
||||
type: "boolean",
|
||||
affectsBindDiagnostics: true,
|
||||
affectsSemanticDiagnostics: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Additional_Checks,
|
||||
@@ -410,6 +459,7 @@ namespace ts {
|
||||
node: ModuleResolutionKind.NodeJs,
|
||||
classic: ModuleResolutionKind.Classic,
|
||||
}),
|
||||
affectsModuleResolution: true,
|
||||
paramType: Diagnostics.STRATEGY,
|
||||
category: Diagnostics.Module_Resolution_Options,
|
||||
description: Diagnostics.Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6,
|
||||
@@ -417,6 +467,7 @@ namespace ts {
|
||||
{
|
||||
name: "baseUrl",
|
||||
type: "string",
|
||||
affectsModuleResolution: true,
|
||||
isFilePath: true,
|
||||
category: Diagnostics.Module_Resolution_Options,
|
||||
description: Diagnostics.Base_directory_to_resolve_non_absolute_module_names
|
||||
@@ -426,6 +477,7 @@ namespace ts {
|
||||
// use type = object to copy the value as-is
|
||||
name: "paths",
|
||||
type: "object",
|
||||
affectsModuleResolution: true,
|
||||
isTSConfigOnly: true,
|
||||
category: Diagnostics.Module_Resolution_Options,
|
||||
description: Diagnostics.A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl
|
||||
@@ -441,6 +493,7 @@ namespace ts {
|
||||
type: "string",
|
||||
isFilePath: true
|
||||
},
|
||||
affectsModuleResolution: true,
|
||||
category: Diagnostics.Module_Resolution_Options,
|
||||
description: Diagnostics.List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime
|
||||
},
|
||||
@@ -452,6 +505,7 @@ namespace ts {
|
||||
type: "string",
|
||||
isFilePath: true
|
||||
},
|
||||
affectsModuleResolution: true,
|
||||
category: Diagnostics.Module_Resolution_Options,
|
||||
description: Diagnostics.List_of_folders_to_include_type_definitions_from
|
||||
},
|
||||
@@ -462,6 +516,7 @@ namespace ts {
|
||||
name: "types",
|
||||
type: "string"
|
||||
},
|
||||
affectsModuleResolution: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Module_Resolution_Options,
|
||||
description: Diagnostics.Type_declaration_files_to_be_included_in_compilation
|
||||
@@ -549,30 +604,12 @@ namespace ts {
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Show_verbose_diagnostic_information
|
||||
},
|
||||
{
|
||||
name: "traceResolution",
|
||||
type: "boolean",
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Enable_tracing_of_the_name_resolution_process
|
||||
},
|
||||
{
|
||||
name: "resolveJsonModule",
|
||||
type: "boolean",
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Include_modules_imported_with_json_extension
|
||||
},
|
||||
{
|
||||
name: "listFiles",
|
||||
type: "boolean",
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Print_names_of_files_part_of_the_compilation
|
||||
},
|
||||
{
|
||||
name: "listEmittedFiles",
|
||||
type: "boolean",
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Print_names_of_generated_files_part_of_the_compilation
|
||||
},
|
||||
|
||||
{
|
||||
name: "out",
|
||||
@@ -632,12 +669,14 @@ namespace ts {
|
||||
{
|
||||
name: "noLib",
|
||||
type: "boolean",
|
||||
affectsModuleResolution: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Do_not_include_the_default_library_file_lib_d_ts
|
||||
},
|
||||
{
|
||||
name: "noResolve",
|
||||
type: "boolean",
|
||||
affectsModuleResolution: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files
|
||||
},
|
||||
@@ -650,6 +689,7 @@ namespace ts {
|
||||
{
|
||||
name: "disableSizeLimit",
|
||||
type: "boolean",
|
||||
affectsSourceFile: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Disable_size_limitations_on_JavaScript_projects
|
||||
},
|
||||
@@ -695,6 +735,7 @@ namespace ts {
|
||||
{
|
||||
name: "allowUnusedLabels",
|
||||
type: "boolean",
|
||||
affectsBindDiagnostics: true,
|
||||
affectsSemanticDiagnostics: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Do_not_report_errors_on_unused_labels
|
||||
@@ -702,6 +743,7 @@ namespace ts {
|
||||
{
|
||||
name: "allowUnreachableCode",
|
||||
type: "boolean",
|
||||
affectsBindDiagnostics: true,
|
||||
affectsSemanticDiagnostics: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Do_not_report_errors_on_unreachable_code
|
||||
@@ -729,6 +771,7 @@ namespace ts {
|
||||
{
|
||||
name: "maxNodeModuleJsDepth",
|
||||
type: "number",
|
||||
affectsModuleResolution: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files
|
||||
},
|
||||
@@ -758,6 +801,18 @@ namespace ts {
|
||||
}
|
||||
];
|
||||
|
||||
/* @internal */
|
||||
export const semanticDiagnosticsOptionDeclarations: ReadonlyArray<CommandLineOption> =
|
||||
optionDeclarations.filter(option => !!option.affectsSemanticDiagnostics);
|
||||
|
||||
/* @internal */
|
||||
export const moduleResolutionOptionDeclarations: ReadonlyArray<CommandLineOption> =
|
||||
optionDeclarations.filter(option => !!option.affectsModuleResolution);
|
||||
|
||||
/* @internal */
|
||||
export const sourceFileAffectingCompilerOptions: ReadonlyArray<CommandLineOption> = optionDeclarations.filter(option =>
|
||||
!!option.affectsSourceFile || !!option.affectsModuleResolution || !!option.affectsBindDiagnostics);
|
||||
|
||||
/* @internal */
|
||||
export const buildOpts: CommandLineOption[] = [
|
||||
...commonOptionsWithBuild,
|
||||
@@ -903,17 +958,27 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function parseCommandLine(commandLine: ReadonlyArray<string>, readFile?: (path: string) => string | undefined): ParsedCommandLine {
|
||||
const options: CompilerOptions = {};
|
||||
/* @internal */
|
||||
export interface OptionsBase {
|
||||
[option: string]: CompilerOptionsValue | undefined;
|
||||
}
|
||||
|
||||
/** Tuple with error messages for 'unknown compiler option', 'option requires type' */
|
||||
type ParseCommandLineWorkerDiagnostics = [DiagnosticMessage, DiagnosticMessage];
|
||||
|
||||
function parseCommandLineWorker(
|
||||
getOptionNameMap: () => OptionNameMap,
|
||||
[unknownOptionDiagnostic, optionTypeMismatchDiagnostic]: ParseCommandLineWorkerDiagnostics,
|
||||
commandLine: ReadonlyArray<string>,
|
||||
readFile?: (path: string) => string | undefined) {
|
||||
const options = {} as OptionsBase;
|
||||
const fileNames: string[] = [];
|
||||
const projectReferences: ProjectReference[] | undefined = undefined;
|
||||
const errors: Diagnostic[] = [];
|
||||
|
||||
parseStrings(commandLine);
|
||||
return {
|
||||
options,
|
||||
fileNames,
|
||||
projectReferences,
|
||||
errors
|
||||
};
|
||||
|
||||
@@ -926,7 +991,7 @@ namespace ts {
|
||||
parseResponseFile(s.slice(1));
|
||||
}
|
||||
else if (s.charCodeAt(0) === CharacterCodes.minus) {
|
||||
const opt = getOptionFromName(s.slice(s.charCodeAt(1) === CharacterCodes.minus ? 2 : 1), /*allowShort*/ true);
|
||||
const opt = getOptionDeclarationFromName(getOptionNameMap, s.slice(s.charCodeAt(1) === CharacterCodes.minus ? 2 : 1), /*allowShort*/ true);
|
||||
if (opt) {
|
||||
if (opt.isTSConfigOnly) {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file, opt.name));
|
||||
@@ -934,7 +999,7 @@ namespace ts {
|
||||
else {
|
||||
// Check to see if no argument was provided (e.g. "--locale" is the last command-line argument).
|
||||
if (!args[i] && opt.type !== "boolean") {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_expects_an_argument, opt.name));
|
||||
errors.push(createCompilerDiagnostic(optionTypeMismatchDiagnostic, opt.name));
|
||||
}
|
||||
|
||||
switch (opt.type) {
|
||||
@@ -956,7 +1021,7 @@ namespace ts {
|
||||
i++;
|
||||
break;
|
||||
case "list":
|
||||
const result = parseListTypeOption(<CommandLineOptionOfListType>opt, args[i], errors);
|
||||
const result = parseListTypeOption(opt, args[i], errors);
|
||||
options[opt.name] = result || [];
|
||||
if (result) {
|
||||
i++;
|
||||
@@ -971,7 +1036,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Unknown_compiler_option_0, s));
|
||||
errors.push(createCompilerDiagnostic(unknownOptionDiagnostic, s));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1014,13 +1079,19 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function parseCommandLine(commandLine: ReadonlyArray<string>, readFile?: (path: string) => string | undefined): ParsedCommandLine {
|
||||
return parseCommandLineWorker(getOptionNameMap, [
|
||||
Diagnostics.Unknown_compiler_option_0,
|
||||
Diagnostics.Compiler_option_0_expects_an_argument
|
||||
], commandLine, readFile);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function getOptionFromName(optionName: string, allowShort?: boolean): CommandLineOption | undefined {
|
||||
return getOptionDeclarationFromName(getOptionNameMap, optionName, allowShort);
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function getOptionDeclarationFromName(getOptionNameMap: () => OptionNameMap, optionName: string, allowShort = false): CommandLineOption | undefined {
|
||||
function getOptionDeclarationFromName(getOptionNameMap: () => OptionNameMap, optionName: string, allowShort = false): CommandLineOption | undefined {
|
||||
optionName = optionName.toLowerCase();
|
||||
const { optionNameMap, shortOptionNames } = getOptionNameMap();
|
||||
// Try to translate short option names to their full equivalents.
|
||||
@@ -1044,25 +1115,11 @@ namespace ts {
|
||||
export function parseBuildCommand(args: string[]): ParsedBuildCommand {
|
||||
let buildOptionNameMap: OptionNameMap | undefined;
|
||||
const returnBuildOptionNameMap = () => (buildOptionNameMap || (buildOptionNameMap = createOptionNameMap(buildOpts)));
|
||||
|
||||
const buildOptions: BuildOptions = {};
|
||||
const projects: string[] = [];
|
||||
let errors: Diagnostic[] | undefined;
|
||||
for (const arg of args) {
|
||||
if (arg.charCodeAt(0) === CharacterCodes.minus) {
|
||||
const opt = getOptionDeclarationFromName(returnBuildOptionNameMap, arg.slice(arg.charCodeAt(1) === CharacterCodes.minus ? 2 : 1), /*allowShort*/ true);
|
||||
if (opt) {
|
||||
buildOptions[opt.name as keyof BuildOptions] = true;
|
||||
}
|
||||
else {
|
||||
(errors || (errors = [])).push(createCompilerDiagnostic(Diagnostics.Unknown_build_option_0, arg));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Not a flag, parse as filename
|
||||
projects.push(arg);
|
||||
}
|
||||
}
|
||||
const { options, fileNames: projects, errors } = parseCommandLineWorker(returnBuildOptionNameMap, [
|
||||
Diagnostics.Unknown_build_option_0,
|
||||
Diagnostics.Build_option_0_requires_a_value_of_type_1
|
||||
], args);
|
||||
const buildOptions = options as BuildOptions;
|
||||
|
||||
if (projects.length === 0) {
|
||||
// tsc -b invoked with no extra arguments; act as if invoked with "tsc -b ."
|
||||
@@ -1071,19 +1128,19 @@ namespace ts {
|
||||
|
||||
// Nonsensical combinations
|
||||
if (buildOptions.clean && buildOptions.force) {
|
||||
(errors || (errors = [])).push(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "force"));
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "force"));
|
||||
}
|
||||
if (buildOptions.clean && buildOptions.verbose) {
|
||||
(errors || (errors = [])).push(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "verbose"));
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "verbose"));
|
||||
}
|
||||
if (buildOptions.clean && buildOptions.watch) {
|
||||
(errors || (errors = [])).push(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "watch"));
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "watch"));
|
||||
}
|
||||
if (buildOptions.watch && buildOptions.dry) {
|
||||
(errors || (errors = [])).push(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "watch", "dry"));
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "watch", "dry"));
|
||||
}
|
||||
|
||||
return { buildOptions, projects, errors: errors || emptyArray };
|
||||
return { buildOptions, projects, errors };
|
||||
}
|
||||
|
||||
function getDiagnosticText(_message: DiagnosticMessage, ..._args: any[]): string {
|
||||
@@ -1097,7 +1154,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function printHelp(optionsList: CommandLineOption[], syntaxPrefix = "") {
|
||||
export function printHelp(optionsList: ReadonlyArray<CommandLineOption>, syntaxPrefix = "") {
|
||||
const output: string[] = [];
|
||||
|
||||
// We want to align our "syntax" and "examples" commands to a certain margin.
|
||||
@@ -1244,6 +1301,9 @@ namespace ts {
|
||||
|
||||
const result = parseJsonText(configFileName, configFileText);
|
||||
const cwd = host.getCurrentDirectory();
|
||||
result.path = toPath(configFileName, cwd, createGetCanonicalFileName(host.useCaseSensitiveFileNames));
|
||||
result.resolvedPath = result.path;
|
||||
result.originalFileName = result.fileName;
|
||||
return parseJsonSourceFileConfigFileContent(result, host, getNormalizedAbsolutePath(getDirectoryPath(configFileName), cwd), optionsToExtend, getNormalizedAbsolutePath(configFileName, cwd));
|
||||
}
|
||||
|
||||
@@ -1480,7 +1540,12 @@ namespace ts {
|
||||
elements: NodeArray<Expression>,
|
||||
elementOption: CommandLineOption | undefined
|
||||
): any[] | void {
|
||||
return (returnValue ? elements.map : elements.forEach).call(elements, (element: Expression) => convertPropertyValueToJson(element, elementOption));
|
||||
if (!returnValue) {
|
||||
return elements.forEach(element => convertPropertyValueToJson(element, elementOption));
|
||||
}
|
||||
|
||||
// Filter out invalid values
|
||||
return filter(elements.map(element => convertPropertyValueToJson(element, elementOption)), v => v !== undefined);
|
||||
}
|
||||
|
||||
function convertPropertyValueToJson(valueExpression: Expression, option: CommandLineOption | undefined): any {
|
||||
@@ -1596,6 +1661,137 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an uncommented, complete tsconfig for use with "--showConfig"
|
||||
* @param configParseResult options to be generated into tsconfig.json
|
||||
* @param configFileName name of the parsed config file - output paths will be generated relative to this
|
||||
* @param host provides current directory and case sensitivity services
|
||||
*/
|
||||
/** @internal */
|
||||
export function convertToTSConfig(configParseResult: ParsedCommandLine, configFileName: string, host: { getCurrentDirectory(): string, useCaseSensitiveFileNames: boolean }): object {
|
||||
const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames);
|
||||
const files = map(
|
||||
filter(
|
||||
configParseResult.fileNames,
|
||||
!configParseResult.configFileSpecs ? _ => false : matchesSpecs(
|
||||
configFileName,
|
||||
configParseResult.configFileSpecs.validatedIncludeSpecs,
|
||||
configParseResult.configFileSpecs.validatedExcludeSpecs
|
||||
)
|
||||
),
|
||||
f => getRelativePathFromFile(getNormalizedAbsolutePath(configFileName, host.getCurrentDirectory()), f, getCanonicalFileName)
|
||||
);
|
||||
const optionMap = serializeCompilerOptions(configParseResult.options, { configFilePath: getNormalizedAbsolutePath(configFileName, host.getCurrentDirectory()), useCaseSensitiveFileNames: host.useCaseSensitiveFileNames });
|
||||
const config = {
|
||||
compilerOptions: {
|
||||
...arrayFrom(optionMap.entries()).reduce((prev, cur) => ({ ...prev, [cur[0]]: cur[1] }), {}),
|
||||
showConfig: undefined,
|
||||
configFile: undefined,
|
||||
configFilePath: undefined,
|
||||
help: undefined,
|
||||
init: undefined,
|
||||
listFiles: undefined,
|
||||
listEmittedFiles: undefined,
|
||||
project: undefined,
|
||||
},
|
||||
references: map(configParseResult.projectReferences, r => ({ ...r, path: r.originalPath, originalPath: undefined })),
|
||||
files: length(files) ? files : undefined,
|
||||
...(configParseResult.configFileSpecs ? {
|
||||
include: filterSameAsDefaultInclude(configParseResult.configFileSpecs.validatedIncludeSpecs),
|
||||
exclude: configParseResult.configFileSpecs.validatedExcludeSpecs
|
||||
} : {}),
|
||||
compilerOnSave: !!configParseResult.compileOnSave ? true : undefined
|
||||
};
|
||||
return config;
|
||||
}
|
||||
|
||||
function filterSameAsDefaultInclude(specs: ReadonlyArray<string> | undefined) {
|
||||
if (!length(specs)) return undefined;
|
||||
if (length(specs) !== 1) return specs;
|
||||
if (specs![0] === "**/*") return undefined;
|
||||
return specs;
|
||||
}
|
||||
|
||||
function matchesSpecs(path: string, includeSpecs: ReadonlyArray<string> | undefined, excludeSpecs: ReadonlyArray<string> | undefined): (path: string) => boolean {
|
||||
if (!includeSpecs) return _ => false;
|
||||
const patterns = getFileMatcherPatterns(path, excludeSpecs, includeSpecs, sys.useCaseSensitiveFileNames, sys.getCurrentDirectory());
|
||||
const excludeRe = patterns.excludePattern && getRegexFromPattern(patterns.excludePattern, sys.useCaseSensitiveFileNames);
|
||||
const includeRe = patterns.includeFilePattern && getRegexFromPattern(patterns.includeFilePattern, sys.useCaseSensitiveFileNames);
|
||||
if (includeRe) {
|
||||
if (excludeRe) {
|
||||
return path => includeRe.test(path) && !excludeRe.test(path);
|
||||
}
|
||||
return path => includeRe.test(path);
|
||||
}
|
||||
if (excludeRe) {
|
||||
return path => !excludeRe.test(path);
|
||||
}
|
||||
return _ => false;
|
||||
}
|
||||
|
||||
function getCustomTypeMapOfCommandLineOption(optionDefinition: CommandLineOption): Map<string | number> | undefined {
|
||||
if (optionDefinition.type === "string" || optionDefinition.type === "number" || optionDefinition.type === "boolean") {
|
||||
// this is of a type CommandLineOptionOfPrimitiveType
|
||||
return undefined;
|
||||
}
|
||||
else if (optionDefinition.type === "list") {
|
||||
return getCustomTypeMapOfCommandLineOption(optionDefinition.element);
|
||||
}
|
||||
else {
|
||||
return (<CommandLineOptionOfCustomType>optionDefinition).type;
|
||||
}
|
||||
}
|
||||
|
||||
function getNameOfCompilerOptionValue(value: CompilerOptionsValue, customTypeMap: Map<string | number>): string | undefined {
|
||||
// There is a typeMap associated with this command-line option so use it to map value back to its name
|
||||
return forEachEntry(customTypeMap, (mapValue, key) => {
|
||||
if (mapValue === value) {
|
||||
return key;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function serializeCompilerOptions(options: CompilerOptions, pathOptions?: { configFilePath: string, useCaseSensitiveFileNames: boolean }): Map<CompilerOptionsValue> {
|
||||
const result = createMap<CompilerOptionsValue>();
|
||||
const optionsNameMap = getOptionNameMap().optionNameMap;
|
||||
const getCanonicalFileName = pathOptions && createGetCanonicalFileName(pathOptions.useCaseSensitiveFileNames);
|
||||
|
||||
for (const name in options) {
|
||||
if (hasProperty(options, name)) {
|
||||
// tsconfig only options cannot be specified via command line,
|
||||
// so we can assume that only types that can appear here string | number | boolean
|
||||
if (optionsNameMap.has(name) && optionsNameMap.get(name)!.category === Diagnostics.Command_line_Options) {
|
||||
continue;
|
||||
}
|
||||
const value = <CompilerOptionsValue>options[name];
|
||||
const optionDefinition = optionsNameMap.get(name.toLowerCase());
|
||||
if (optionDefinition) {
|
||||
const customTypeMap = getCustomTypeMapOfCommandLineOption(optionDefinition);
|
||||
if (!customTypeMap) {
|
||||
// There is no map associated with this compiler option then use the value as-is
|
||||
// This is the case if the value is expect to be string, number, boolean or list of string
|
||||
if (pathOptions && optionDefinition.isFilePath) {
|
||||
result.set(name, getRelativePathFromFile(pathOptions.configFilePath, getNormalizedAbsolutePath(value as string, getDirectoryPath(pathOptions.configFilePath)), getCanonicalFileName!));
|
||||
}
|
||||
else {
|
||||
result.set(name, value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (optionDefinition.type === "list") {
|
||||
result.set(name, (value as ReadonlyArray<string | number>).map(element => getNameOfCompilerOptionValue(element, customTypeMap)!)); // TODO: GH#18217
|
||||
}
|
||||
else {
|
||||
// There is a typeMap associated with this command-line option so use it to map value back to its name
|
||||
result.set(name, getNameOfCompilerOptionValue(value, customTypeMap));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate tsconfig configuration when running command line "--init"
|
||||
* @param options commandlineOptions to be generated into tsconfig.json
|
||||
@@ -1607,63 +1803,6 @@ namespace ts {
|
||||
const compilerOptionsMap = serializeCompilerOptions(compilerOptions);
|
||||
return writeConfigurations();
|
||||
|
||||
function getCustomTypeMapOfCommandLineOption(optionDefinition: CommandLineOption): Map<string | number> | undefined {
|
||||
if (optionDefinition.type === "string" || optionDefinition.type === "number" || optionDefinition.type === "boolean") {
|
||||
// this is of a type CommandLineOptionOfPrimitiveType
|
||||
return undefined;
|
||||
}
|
||||
else if (optionDefinition.type === "list") {
|
||||
return getCustomTypeMapOfCommandLineOption((<CommandLineOptionOfListType>optionDefinition).element);
|
||||
}
|
||||
else {
|
||||
return (<CommandLineOptionOfCustomType>optionDefinition).type;
|
||||
}
|
||||
}
|
||||
|
||||
function getNameOfCompilerOptionValue(value: CompilerOptionsValue, customTypeMap: Map<string | number>): string | undefined {
|
||||
// There is a typeMap associated with this command-line option so use it to map value back to its name
|
||||
return forEachEntry(customTypeMap, (mapValue, key) => {
|
||||
if (mapValue === value) {
|
||||
return key;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function serializeCompilerOptions(options: CompilerOptions): Map<CompilerOptionsValue> {
|
||||
const result = createMap<CompilerOptionsValue>();
|
||||
const optionsNameMap = getOptionNameMap().optionNameMap;
|
||||
|
||||
for (const name in options) {
|
||||
if (hasProperty(options, name)) {
|
||||
// tsconfig only options cannot be specified via command line,
|
||||
// so we can assume that only types that can appear here string | number | boolean
|
||||
if (optionsNameMap.has(name) && optionsNameMap.get(name)!.category === Diagnostics.Command_line_Options) {
|
||||
continue;
|
||||
}
|
||||
const value = <CompilerOptionsValue>options[name];
|
||||
const optionDefinition = optionsNameMap.get(name.toLowerCase());
|
||||
if (optionDefinition) {
|
||||
const customTypeMap = getCustomTypeMapOfCommandLineOption(optionDefinition);
|
||||
if (!customTypeMap) {
|
||||
// There is no map associated with this compiler option then use the value as-is
|
||||
// This is the case if the value is expect to be string, number, boolean or list of string
|
||||
result.set(name, value);
|
||||
}
|
||||
else {
|
||||
if (optionDefinition.type === "list") {
|
||||
result.set(name, (value as ReadonlyArray<string | number>).map(element => getNameOfCompilerOptionValue(element, customTypeMap)!)); // TODO: GH#18217
|
||||
}
|
||||
else {
|
||||
// There is a typeMap associated with this command-line option so use it to map value back to its name
|
||||
result.set(name, getNameOfCompilerOptionValue(value, customTypeMap));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getDefaultValueForOption(option: CommandLineOption) {
|
||||
switch (option.type) {
|
||||
case "number":
|
||||
@@ -1677,7 +1816,7 @@ namespace ts {
|
||||
case "object":
|
||||
return {};
|
||||
default:
|
||||
return (option as CommandLineOptionOfCustomType).type.keys().next().value;
|
||||
return option.type.keys().next().value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1825,7 +1964,8 @@ namespace ts {
|
||||
const options = extend(existingOptions, parsedConfig.options || {});
|
||||
options.configFilePath = configFileName && normalizeSlashes(configFileName);
|
||||
setConfigFileInOptions(options, sourceFile);
|
||||
const { fileNames, wildcardDirectories, spec, projectReferences } = getFileNames();
|
||||
let projectReferences: ProjectReference[] | undefined;
|
||||
const { fileNames, wildcardDirectories, spec } = getFileNames();
|
||||
return {
|
||||
options,
|
||||
fileNames,
|
||||
@@ -1845,7 +1985,8 @@ namespace ts {
|
||||
filesSpecs = <ReadonlyArray<string>>raw.files;
|
||||
const hasReferences = hasProperty(raw, "references") && !isNullOrUndefined(raw.references);
|
||||
const hasZeroOrNoReferences = !hasReferences || raw.references.length === 0;
|
||||
if (filesSpecs.length === 0 && hasZeroOrNoReferences) {
|
||||
const hasExtends = hasProperty(raw, "extends");
|
||||
if (filesSpecs.length === 0 && hasZeroOrNoReferences && !hasExtends) {
|
||||
if (sourceFile) {
|
||||
const fileName = configFileName || "tsconfig.json";
|
||||
const diagnosticMessage = Diagnostics.The_files_list_in_config_file_0_is_empty;
|
||||
@@ -1898,19 +2039,18 @@ namespace ts {
|
||||
}
|
||||
|
||||
const result = matchFileNames(filesSpecs, includeSpecs, excludeSpecs, configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath, options, host, errors, extraFileExtensions, sourceFile);
|
||||
if (result.fileNames.length === 0 && !hasProperty(raw, "files") && resolutionStack.length === 0 && !hasProperty(raw, "references")) {
|
||||
if (shouldReportNoInputFiles(result, canJsonReportNoInutFiles(raw), resolutionStack)) {
|
||||
errors.push(getErrorForNoInputFiles(result.spec, configFileName));
|
||||
}
|
||||
|
||||
if (hasProperty(raw, "references") && !isNullOrUndefined(raw.references)) {
|
||||
if (isArray(raw.references)) {
|
||||
const references: ProjectReference[] = [];
|
||||
for (const ref of raw.references) {
|
||||
if (typeof ref.path !== "string") {
|
||||
createCompilerDiagnosticOnlyIfJson(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "reference.path", "string");
|
||||
}
|
||||
else {
|
||||
references.push({
|
||||
(projectReferences || (projectReferences = [])).push({
|
||||
path: getNormalizedAbsolutePath(ref.path, basePath),
|
||||
originalPath: ref.path,
|
||||
prepend: ref.prepend,
|
||||
@@ -1918,7 +2058,6 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
}
|
||||
result.projectReferences = references;
|
||||
}
|
||||
else {
|
||||
createCompilerDiagnosticOnlyIfJson(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "references", "Array");
|
||||
@@ -1935,13 +2074,11 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function isErrorNoInputFiles(error: Diagnostic) {
|
||||
function isErrorNoInputFiles(error: Diagnostic) {
|
||||
return error.code === Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function getErrorForNoInputFiles({ includeSpecs, excludeSpecs }: ConfigFileSpecs, configFileName: string | undefined) {
|
||||
function getErrorForNoInputFiles({ includeSpecs, excludeSpecs }: ConfigFileSpecs, configFileName: string | undefined) {
|
||||
return createCompilerDiagnostic(
|
||||
Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
|
||||
configFileName || "tsconfig.json",
|
||||
@@ -1949,6 +2086,27 @@ namespace ts {
|
||||
JSON.stringify(excludeSpecs || []));
|
||||
}
|
||||
|
||||
function shouldReportNoInputFiles(result: ExpandResult, canJsonReportNoInutFiles: boolean, resolutionStack?: Path[]) {
|
||||
return result.fileNames.length === 0 && canJsonReportNoInutFiles && (!resolutionStack || resolutionStack.length === 0);
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function canJsonReportNoInutFiles(raw: any) {
|
||||
return !hasProperty(raw, "files") && !hasProperty(raw, "references");
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function updateErrorForNoInputFiles(result: ExpandResult, configFileName: string, configFileSpecs: ConfigFileSpecs, configParseDiagnostics: Diagnostic[], canJsonReportNoInutFiles: boolean) {
|
||||
const existingErrors = configParseDiagnostics.length;
|
||||
if (shouldReportNoInputFiles(result, canJsonReportNoInutFiles)) {
|
||||
configParseDiagnostics.push(getErrorForNoInputFiles(configFileSpecs, configFileName));
|
||||
}
|
||||
else {
|
||||
filterMutate(configParseDiagnostics, error => !isErrorNoInputFiles(error));
|
||||
}
|
||||
return existingErrors !== configParseDiagnostics.length;
|
||||
}
|
||||
|
||||
interface ParsedTsconfig {
|
||||
raw: any;
|
||||
options?: CompilerOptions;
|
||||
@@ -1991,7 +2149,7 @@ namespace ts {
|
||||
if (ownConfig.extendedConfigPath) {
|
||||
// copy the resolution stack so it is never reused between branches in potential diamond-problem scenarios.
|
||||
resolutionStack = resolutionStack.concat([resolvedPath]);
|
||||
const extendedConfig = getExtendedConfig(sourceFile!, ownConfig.extendedConfigPath, host, basePath, resolutionStack, errors);
|
||||
const extendedConfig = getExtendedConfig(sourceFile, ownConfig.extendedConfigPath, host, basePath, resolutionStack, errors);
|
||||
if (extendedConfig && isSuccessfulParsedTsconfig(extendedConfig)) {
|
||||
const baseRaw = extendedConfig.raw;
|
||||
const raw = ownConfig.raw;
|
||||
@@ -2115,24 +2273,28 @@ namespace ts {
|
||||
errors: Push<Diagnostic>,
|
||||
createDiagnostic: (message: DiagnosticMessage, arg1?: string) => Diagnostic) {
|
||||
extendedConfig = normalizeSlashes(extendedConfig);
|
||||
// If the path isn't a rooted or relative path, don't try to resolve it (we reserve the right to special case module-id like paths in the future)
|
||||
if (!(isRootedDiskPath(extendedConfig) || startsWith(extendedConfig, "./") || startsWith(extendedConfig, "../"))) {
|
||||
errors.push(createDiagnostic(Diagnostics.A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not, extendedConfig));
|
||||
return undefined;
|
||||
}
|
||||
let extendedConfigPath = getNormalizedAbsolutePath(extendedConfig, basePath);
|
||||
if (!host.fileExists(extendedConfigPath) && !endsWith(extendedConfigPath, Extension.Json)) {
|
||||
extendedConfigPath = `${extendedConfigPath}.json`;
|
||||
if (!host.fileExists(extendedConfigPath)) {
|
||||
errors.push(createDiagnostic(Diagnostics.File_0_does_not_exist, extendedConfig));
|
||||
return undefined;
|
||||
if (isRootedDiskPath(extendedConfig) || startsWith(extendedConfig, "./") || startsWith(extendedConfig, "../")) {
|
||||
let extendedConfigPath = getNormalizedAbsolutePath(extendedConfig, basePath);
|
||||
if (!host.fileExists(extendedConfigPath) && !endsWith(extendedConfigPath, Extension.Json)) {
|
||||
extendedConfigPath = `${extendedConfigPath}.json`;
|
||||
if (!host.fileExists(extendedConfigPath)) {
|
||||
errors.push(createDiagnostic(Diagnostics.File_0_does_not_exist, extendedConfig));
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
return extendedConfigPath;
|
||||
}
|
||||
return extendedConfigPath;
|
||||
// If the path isn't a rooted or relative path, resolve like a module
|
||||
const resolved = nodeModuleNameResolver(extendedConfig, combinePaths(basePath, "tsconfig.json"), { moduleResolution: ModuleResolutionKind.NodeJs }, host, /*cache*/ undefined, /*projectRefs*/ undefined, /*lookupConfig*/ true);
|
||||
if (resolved.resolvedModule) {
|
||||
return resolved.resolvedModule.resolvedFileName;
|
||||
}
|
||||
errors.push(createDiagnostic(Diagnostics.File_0_does_not_exist, extendedConfig));
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getExtendedConfig(
|
||||
sourceFile: TsConfigSourceFile,
|
||||
sourceFile: TsConfigSourceFile | undefined,
|
||||
extendedConfigPath: string,
|
||||
host: ParseConfigHost,
|
||||
basePath: string,
|
||||
@@ -2141,7 +2303,7 @@ namespace ts {
|
||||
): ParsedTsconfig | undefined {
|
||||
const extendedResult = readJsonConfigFile(extendedConfigPath, path => host.readFile(path));
|
||||
if (sourceFile) {
|
||||
(sourceFile.extendedSourceFiles || (sourceFile.extendedSourceFiles = [])).push(extendedResult.fileName);
|
||||
sourceFile.extendedSourceFiles = [extendedResult.fileName];
|
||||
}
|
||||
if (extendedResult.parseDiagnostics.length) {
|
||||
errors.push(...extendedResult.parseDiagnostics);
|
||||
@@ -2151,8 +2313,8 @@ namespace ts {
|
||||
const extendedDirname = getDirectoryPath(extendedConfigPath);
|
||||
const extendedConfig = parseConfig(/*json*/ undefined, extendedResult, host, extendedDirname,
|
||||
getBaseFileName(extendedConfigPath), resolutionStack, errors);
|
||||
if (sourceFile) {
|
||||
sourceFile.extendedSourceFiles!.push(...extendedResult.extendedSourceFiles!);
|
||||
if (sourceFile && extendedResult.extendedSourceFiles) {
|
||||
sourceFile.extendedSourceFiles!.push(...extendedResult.extendedSourceFiles);
|
||||
}
|
||||
|
||||
if (isSuccessfulParsedTsconfig(extendedConfig)) {
|
||||
@@ -2265,7 +2427,7 @@ namespace ts {
|
||||
function normalizeOptionValue(option: CommandLineOption, basePath: string, value: any): CompilerOptionsValue {
|
||||
if (isNullOrUndefined(value)) return undefined;
|
||||
if (option.type === "list") {
|
||||
const listOption = <CommandLineOptionOfListType>option;
|
||||
const listOption = option;
|
||||
if (listOption.element.isFilePath || !isString(listOption.element.type)) {
|
||||
return <CompilerOptionsValue>filter(map(value, v => normalizeOptionValue(listOption.element, basePath, v)), v => !!v);
|
||||
}
|
||||
@@ -2407,7 +2569,7 @@ namespace ts {
|
||||
// new entries in these paths.
|
||||
const wildcardDirectories = getWildcardDirectories(validatedIncludeSpecs, validatedExcludeSpecs, basePath, host.useCaseSensitiveFileNames);
|
||||
|
||||
const spec: ConfigFileSpecs = { filesSpecs, referencesSpecs: undefined, includeSpecs, excludeSpecs, validatedIncludeSpecs, validatedExcludeSpecs, wildcardDirectories };
|
||||
const spec: ConfigFileSpecs = { filesSpecs, includeSpecs, excludeSpecs, validatedIncludeSpecs, validatedExcludeSpecs, wildcardDirectories };
|
||||
return getFileNamesFromConfigSpecs(spec, basePath, options, host, extraFileExtensions);
|
||||
}
|
||||
|
||||
@@ -2436,11 +2598,16 @@ namespace ts {
|
||||
// via wildcard, and to handle extension priority.
|
||||
const wildcardFileMap = createMap<string>();
|
||||
|
||||
// Wildcard paths of json files (provided via the "includes" array in tsconfig.json) are stored in a
|
||||
// file map with a possibly case insensitive key. We use this map to store paths matched
|
||||
// via wildcard of *.json kind
|
||||
const wildCardJsonFileMap = createMap<string>();
|
||||
const { filesSpecs, validatedIncludeSpecs, validatedExcludeSpecs, wildcardDirectories } = spec;
|
||||
|
||||
// Rather than requery this for each file and filespec, we query the supported extensions
|
||||
// once and store it on the expansion context.
|
||||
const supportedExtensions = getSupportedExtensions(options, extraFileExtensions);
|
||||
const supportedExtensionsWithJsonIfResolveJsonModule = getSuppoertedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions);
|
||||
|
||||
// Literal files are always included verbatim. An "include" or "exclude" specification cannot
|
||||
// remove a literal file.
|
||||
@@ -2451,8 +2618,25 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
let jsonOnlyIncludeRegexes: ReadonlyArray<RegExp> | undefined;
|
||||
if (validatedIncludeSpecs && validatedIncludeSpecs.length > 0) {
|
||||
for (const file of host.readDirectory(basePath, supportedExtensions, validatedExcludeSpecs, validatedIncludeSpecs, /*depth*/ undefined)) {
|
||||
for (const file of host.readDirectory(basePath, supportedExtensionsWithJsonIfResolveJsonModule, validatedExcludeSpecs, validatedIncludeSpecs, /*depth*/ undefined)) {
|
||||
if (fileExtensionIs(file, Extension.Json)) {
|
||||
// Valid only if *.json specified
|
||||
if (!jsonOnlyIncludeRegexes) {
|
||||
const includes = validatedIncludeSpecs.filter(s => endsWith(s, Extension.Json));
|
||||
const includeFilePatterns = map(getRegularExpressionsForWildcards(includes, basePath, "files"), pattern => `^${pattern}$`);
|
||||
jsonOnlyIncludeRegexes = includeFilePatterns ? includeFilePatterns.map(pattern => getRegexFromPattern(pattern, host.useCaseSensitiveFileNames)) : emptyArray;
|
||||
}
|
||||
const includeIndex = findIndex(jsonOnlyIncludeRegexes, re => re.test(file));
|
||||
if (includeIndex !== -1) {
|
||||
const key = keyMapper(file);
|
||||
if (!literalFileMap.has(key) && !wildCardJsonFileMap.has(key)) {
|
||||
wildCardJsonFileMap.set(key, file);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// If we have already included a literal or wildcard path with a
|
||||
// higher priority extension, we should skip this file.
|
||||
//
|
||||
@@ -2478,16 +2662,9 @@ namespace ts {
|
||||
|
||||
const literalFiles = arrayFrom(literalFileMap.values());
|
||||
const wildcardFiles = arrayFrom(wildcardFileMap.values());
|
||||
const projectReferences = spec.referencesSpecs && spec.referencesSpecs.map((r): ProjectReference => {
|
||||
return {
|
||||
...r,
|
||||
path: getNormalizedAbsolutePath(r.path, basePath)
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
fileNames: literalFiles.concat(wildcardFiles),
|
||||
projectReferences,
|
||||
fileNames: literalFiles.concat(wildcardFiles, arrayFrom(wildCardJsonFileMap.values())),
|
||||
wildcardDirectories,
|
||||
spec
|
||||
};
|
||||
@@ -2629,7 +2806,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces a cleaned version of compiler options with personally identifiying info (aka, paths) removed.
|
||||
* Produces a cleaned version of compiler options with personally identifying info (aka, paths) removed.
|
||||
* Also converts enum values back to strings.
|
||||
*/
|
||||
/* @internal */
|
||||
@@ -2657,7 +2834,7 @@ namespace ts {
|
||||
case "boolean":
|
||||
return typeof value === "boolean" ? value : "";
|
||||
case "list":
|
||||
const elementType = (option as CommandLineOptionOfListType).element;
|
||||
const elementType = option.element;
|
||||
return isArray(value) ? value.map(v => getOptionValueWithEmptyStrings(v, elementType)) : "";
|
||||
default:
|
||||
return forEachEntry(option.type, (optionEnumValue, optionStringValue) => {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+67
-25
@@ -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.2";
|
||||
/** 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;
|
||||
}
|
||||
@@ -511,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) {
|
||||
@@ -800,8 +819,8 @@ namespace ts {
|
||||
/**
|
||||
* Deduplicates an array that has already been sorted.
|
||||
*/
|
||||
function deduplicateSorted<T>(array: ReadonlyArray<T>, comparer: EqualityComparer<T> | Comparer<T>): T[] {
|
||||
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];
|
||||
@@ -823,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 {
|
||||
@@ -838,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;
|
||||
}
|
||||
@@ -852,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;
|
||||
}
|
||||
}
|
||||
@@ -1020,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> {
|
||||
@@ -1040,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) {
|
||||
@@ -1135,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]);
|
||||
@@ -1234,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);
|
||||
@@ -1409,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;
|
||||
@@ -1534,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;
|
||||
@@ -1598,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) {
|
||||
@@ -2026,7 +2065,6 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** Represents a "prefix*suffix" pattern. */
|
||||
/* @internal */
|
||||
export interface Pattern {
|
||||
prefix: string;
|
||||
suffix: string;
|
||||
@@ -2125,4 +2163,8 @@ namespace ts {
|
||||
deleted(oldItems[oldIndex++]);
|
||||
}
|
||||
}
|
||||
|
||||
export function fill<T>(length: number, cb: (index: number) => T): T[] {
|
||||
return new Array(length).fill(0).map((_, i) => cb(i));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1007,6 +1007,10 @@
|
||||
"category": "Error",
|
||||
"code": 1349
|
||||
},
|
||||
"Print the final configuration instead of building.": {
|
||||
"category": "Message",
|
||||
"code": 1350
|
||||
},
|
||||
|
||||
"Duplicate identifier '{0}'.": {
|
||||
"category": "Error",
|
||||
@@ -1056,7 +1060,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
|
||||
},
|
||||
@@ -1232,7 +1236,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
|
||||
},
|
||||
@@ -1256,11 +1260,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
|
||||
},
|
||||
@@ -1484,7 +1488,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
|
||||
},
|
||||
@@ -1816,7 +1820,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
|
||||
},
|
||||
@@ -1940,7 +1944,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
|
||||
},
|
||||
@@ -2088,15 +2092,15 @@
|
||||
"category": "Error",
|
||||
"code": 2577
|
||||
},
|
||||
"Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i @types/node`.": {
|
||||
"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`.": {
|
||||
"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`.": {
|
||||
"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
|
||||
},
|
||||
@@ -2112,6 +2116,18 @@
|
||||
"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
|
||||
@@ -2477,14 +2493,42 @@
|
||||
"category": "Error",
|
||||
"code": 2732
|
||||
},
|
||||
"Index '{0}' is out-of-bounds in tuple of length {1}.": {
|
||||
"category": "Error",
|
||||
"code": 2733
|
||||
},
|
||||
"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
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
@@ -2948,7 +2992,10 @@
|
||||
"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",
|
||||
@@ -3748,10 +3795,26 @@
|
||||
"category": "Message",
|
||||
"code": 6212
|
||||
},
|
||||
"Did you mean to use `new` with this expression?": {
|
||||
"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",
|
||||
@@ -3874,10 +3937,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",
|
||||
@@ -3887,6 +3946,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",
|
||||
@@ -3916,6 +3979,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
|
||||
@@ -4026,6 +4093,43 @@
|
||||
"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
|
||||
@@ -4146,6 +4250,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
|
||||
@@ -4404,6 +4512,10 @@
|
||||
"category": "Message",
|
||||
"code": 90033
|
||||
},
|
||||
"Add parameter name": {
|
||||
"category": "Message",
|
||||
"code": 90034
|
||||
},
|
||||
"Convert function to an ES2015 class": {
|
||||
"category": "Message",
|
||||
"code": 95001
|
||||
@@ -4644,7 +4756,6 @@
|
||||
"category": "Message",
|
||||
"code": 95062
|
||||
},
|
||||
|
||||
"Add missing enum member '{0}'": {
|
||||
"category": "Message",
|
||||
"code": 95063
|
||||
@@ -4653,12 +4764,40 @@
|
||||
"category": "Message",
|
||||
"code": 95064
|
||||
},
|
||||
"Convert to async function":{
|
||||
"Convert to async function": {
|
||||
"category": "Message",
|
||||
"code": 95065
|
||||
"code": 95065
|
||||
},
|
||||
"Convert all to async functions": {
|
||||
"category": "Message",
|
||||
"code": 95066
|
||||
"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
|
||||
}
|
||||
}
|
||||
|
||||
+1010
-265
File diff suppressed because it is too large
Load Diff
+64
-4
@@ -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:
|
||||
|
||||
@@ -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 = new Set<unknown>();
|
||||
const nameStack: string[] = [];
|
||||
return (obj, name, cbOk, cbFail) => {
|
||||
if (seen.has(obj) || nameStack.length > 4) {
|
||||
return cbFail(seen.has(obj), nameStack);
|
||||
}
|
||||
|
||||
seen.add(obj);
|
||||
nameStack.push(name);
|
||||
const res = cbOk();
|
||||
nameStack.pop();
|
||||
seen.delete(obj);
|
||||
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: ReadonlySet<string> = new Set(["arguments", "caller", "constructor", "eval", "super_"]);
|
||||
const reservedFunctionProperties: ReadonlySet<string> = new Set(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.has(key) &&
|
||||
(typeof obj !== "function" || !reservedFunctionProperties.has(key)) &&
|
||||
// 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 name.startsWith("_");
|
||||
}
|
||||
|
||||
function tryRequire(fileNameToRequire: string): unknown {
|
||||
try {
|
||||
return require(fileNameToRequire);
|
||||
}
|
||||
catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
+192
-101
@@ -62,6 +62,7 @@ namespace ts {
|
||||
TypeScript, /** '.ts', '.tsx', or '.d.ts' */
|
||||
JavaScript, /** '.js' or '.jsx' */
|
||||
Json, /** '.json' */
|
||||
TSConfig, /** '.json' with `tsconfig` used instead of `index` */
|
||||
DtsOnly /** Only '.d.ts' */
|
||||
}
|
||||
|
||||
@@ -74,7 +75,7 @@ namespace ts {
|
||||
if (!resolved) {
|
||||
return undefined;
|
||||
}
|
||||
Debug.assert(extensionIsTypeScript(resolved.extension));
|
||||
Debug.assert(extensionIsTS(resolved.extension));
|
||||
return { fileName: resolved.path, packageId: resolved.packageId };
|
||||
}
|
||||
|
||||
@@ -98,6 +99,7 @@ namespace ts {
|
||||
types?: string;
|
||||
typesVersions?: MapLike<MapLike<string[]>>;
|
||||
main?: string;
|
||||
tsconfig?: string;
|
||||
}
|
||||
|
||||
interface PackageJson extends PackageJsonPathFields {
|
||||
@@ -126,7 +128,7 @@ namespace ts {
|
||||
return value;
|
||||
}
|
||||
|
||||
function readPackageJsonPathField<K extends "typings" | "types" | "main">(jsonContent: PackageJson, fieldName: K, baseDirectory: string, state: ModuleResolutionState): PackageJson[K] | undefined {
|
||||
function readPackageJsonPathField<K extends "typings" | "types" | "main" | "tsconfig">(jsonContent: PackageJson, fieldName: K, baseDirectory: string, state: ModuleResolutionState): PackageJson[K] | undefined {
|
||||
const fileName = readPackageJsonField(jsonContent, fieldName, "string", state);
|
||||
if (fileName === undefined) return;
|
||||
const path = normalizePath(combinePaths(baseDirectory, fileName));
|
||||
@@ -141,6 +143,10 @@ namespace ts {
|
||||
|| readPackageJsonPathField(jsonContent, "types", baseDirectory, state);
|
||||
}
|
||||
|
||||
function readPackageJsonTSConfigField(jsonContent: PackageJson, baseDirectory: string, state: ModuleResolutionState) {
|
||||
return readPackageJsonPathField(jsonContent, "tsconfig", baseDirectory, state);
|
||||
}
|
||||
|
||||
function readPackageJsonMainField(jsonContent: PackageJson, baseDirectory: string, state: ModuleResolutionState) {
|
||||
return readPackageJsonPathField(jsonContent, "main", baseDirectory, state);
|
||||
}
|
||||
@@ -258,8 +264,11 @@ namespace ts {
|
||||
* This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
|
||||
* is assumed to be the same as root directory of the project.
|
||||
*/
|
||||
export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost): ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
|
||||
export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference): ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
|
||||
const traceEnabled = isTraceEnabled(options, host);
|
||||
if (redirectedReference) {
|
||||
options = redirectedReference.commandLine.options;
|
||||
}
|
||||
const failedLookupLocations: string[] = [];
|
||||
const moduleResolutionState: ModuleResolutionState = { compilerOptions: options, host, traceEnabled, failedLookupLocations };
|
||||
|
||||
@@ -281,6 +290,9 @@ namespace ts {
|
||||
trace(host, Diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_2, typeReferenceDirectiveName, containingFile, typeRoots);
|
||||
}
|
||||
}
|
||||
if (redirectedReference) {
|
||||
trace(host, Diagnostics.Using_compiler_options_of_project_reference_redirect_0, redirectedReference.sourceFile.fileName);
|
||||
}
|
||||
}
|
||||
|
||||
let resolved = primaryLookup();
|
||||
@@ -292,14 +304,12 @@ namespace ts {
|
||||
|
||||
let resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective | undefined;
|
||||
if (resolved) {
|
||||
if (!options.preserveSymlinks) {
|
||||
resolved = { ...resolved, fileName: realPath(resolved.fileName, host, traceEnabled) };
|
||||
}
|
||||
|
||||
const { fileName, packageId } = resolved;
|
||||
const resolvedFileName = options.preserveSymlinks ? fileName : realPath(fileName, host, traceEnabled);
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolved.fileName, primary);
|
||||
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolvedFileName, primary);
|
||||
}
|
||||
resolvedTypeReferenceDirective = { primary, resolvedFileName: resolved.fileName, packageId: resolved.packageId };
|
||||
resolvedTypeReferenceDirective = { primary, resolvedFileName, packageId, isExternalLibraryImport: pathContainsNodeModules(fileName) };
|
||||
}
|
||||
|
||||
return { resolvedTypeReferenceDirective, failedLookupLocations };
|
||||
@@ -310,7 +320,7 @@ namespace ts {
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Resolving_with_primary_search_path_0, typeRoots.join(", "));
|
||||
}
|
||||
return forEach(typeRoots, typeRoot => {
|
||||
return firstDefined(typeRoots, typeRoot => {
|
||||
const candidate = combinePaths(typeRoot, typeReferenceDirectiveName);
|
||||
const candidateDirectory = getDirectoryPath(candidate);
|
||||
const directoryExists = directoryProbablyExists(candidateDirectory, host);
|
||||
@@ -337,8 +347,16 @@ namespace ts {
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Looking_up_in_node_modules_folder_initial_location_0, initialLocationForSecondaryLookup);
|
||||
}
|
||||
const result = loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined);
|
||||
const resolvedFile = resolvedTypeScriptOnly(result && result.value);
|
||||
let result: Resolved | undefined;
|
||||
if (!isExternalModuleNameRelative(typeReferenceDirectiveName)) {
|
||||
const searchResult = loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined, /*redirectedReference*/ undefined);
|
||||
result = searchResult && searchResult.value;
|
||||
}
|
||||
else {
|
||||
const { path: candidate } = normalizePathAndParts(combinePaths(initialLocationForSecondaryLookup, typeReferenceDirectiveName));
|
||||
result = nodeLoadModuleByRelativeName(Extensions.DtsOnly, candidate, /*onlyRecordFailures*/ false, moduleResolutionState, /*considerPackageJson*/ true);
|
||||
}
|
||||
const resolvedFile = resolvedTypeScriptOnly(result);
|
||||
if (!resolvedFile && traceEnabled) {
|
||||
trace(host, Diagnostics.Type_reference_directive_0_was_not_resolved, typeReferenceDirectiveName);
|
||||
}
|
||||
@@ -381,8 +399,13 @@ namespace ts {
|
||||
// tslint:disable-next-line:no-null-keyword
|
||||
const isNotNeededPackage = host.fileExists(packageJsonPath) && (readJson(packageJsonPath, host) as PackageJson).typings === null;
|
||||
if (!isNotNeededPackage) {
|
||||
// Return just the type directive names
|
||||
result.push(getBaseFileName(normalized));
|
||||
const baseFileName = getBaseFileName(normalized);
|
||||
|
||||
// At this stage, skip results with leading dot.
|
||||
if (baseFileName.charCodeAt(0) !== CharacterCodes.dot) {
|
||||
// Return just the type directive names
|
||||
result.push(baseFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -397,7 +420,7 @@ namespace ts {
|
||||
* This assumes that any module id will have the same resolution for sibling files located in the same folder.
|
||||
*/
|
||||
export interface ModuleResolutionCache extends NonRelativeModuleNameResolutionCache {
|
||||
getOrCreateCacheForDirectory(directoryName: string): Map<ResolvedModuleWithFailedLookupLocations>;
|
||||
getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): Map<ResolvedModuleWithFailedLookupLocations>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -405,7 +428,7 @@ namespace ts {
|
||||
* We support only non-relative module names because resolution of relative module names is usually more deterministic and thus less expensive.
|
||||
*/
|
||||
export interface NonRelativeModuleNameResolutionCache {
|
||||
getOrCreateCacheForModuleName(nonRelativeModuleName: string): PerModuleNameCache;
|
||||
getOrCreateCacheForModuleName(nonRelativeModuleName: string, redirectedReference?: ResolvedProjectReference): PerModuleNameCache;
|
||||
}
|
||||
|
||||
export interface PerModuleNameCache {
|
||||
@@ -415,40 +438,78 @@ namespace ts {
|
||||
|
||||
export function createModuleResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string): ModuleResolutionCache {
|
||||
return createModuleResolutionCacheWithMaps(
|
||||
createMap<Map<ResolvedModuleWithFailedLookupLocations>>(),
|
||||
createMap<PerModuleNameCache>(),
|
||||
createCacheWithRedirects(),
|
||||
createCacheWithRedirects(),
|
||||
currentDirectory,
|
||||
getCanonicalFileName
|
||||
);
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export interface CacheWithRedirects<T> {
|
||||
ownMap: Map<T>;
|
||||
redirectsMap: Map<Map<T>>;
|
||||
getOrCreateMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined): Map<T>;
|
||||
clear(): void;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function createCacheWithRedirects<T>(): CacheWithRedirects<T> {
|
||||
const ownMap: Map<T> = createMap();
|
||||
const redirectsMap: Map<Map<T>> = createMap();
|
||||
return {
|
||||
ownMap,
|
||||
redirectsMap,
|
||||
getOrCreateMapOfCacheRedirects,
|
||||
clear
|
||||
};
|
||||
|
||||
function getOrCreateMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined) {
|
||||
if (!redirectedReference) {
|
||||
return ownMap;
|
||||
}
|
||||
const path = redirectedReference.sourceFile.path;
|
||||
let redirects = redirectsMap.get(path);
|
||||
if (!redirects) {
|
||||
redirects = createMap();
|
||||
redirectsMap.set(path, redirects);
|
||||
}
|
||||
return redirects;
|
||||
}
|
||||
|
||||
function clear() {
|
||||
ownMap.clear();
|
||||
redirectsMap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function createModuleResolutionCacheWithMaps(
|
||||
directoryToModuleNameMap: Map<Map<ResolvedModuleWithFailedLookupLocations>>,
|
||||
moduleNameToDirectoryMap: Map<PerModuleNameCache>,
|
||||
directoryToModuleNameMap: CacheWithRedirects<Map<ResolvedModuleWithFailedLookupLocations>>,
|
||||
moduleNameToDirectoryMap: CacheWithRedirects<PerModuleNameCache>,
|
||||
currentDirectory: string,
|
||||
getCanonicalFileName: GetCanonicalFileName): ModuleResolutionCache {
|
||||
|
||||
return { getOrCreateCacheForDirectory, getOrCreateCacheForModuleName };
|
||||
|
||||
function getOrCreateCacheForDirectory(directoryName: string) {
|
||||
function getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference) {
|
||||
const path = toPath(directoryName, currentDirectory, getCanonicalFileName);
|
||||
let perFolderCache = directoryToModuleNameMap.get(path);
|
||||
if (!perFolderCache) {
|
||||
perFolderCache = createMap<ResolvedModuleWithFailedLookupLocations>();
|
||||
directoryToModuleNameMap.set(path, perFolderCache);
|
||||
}
|
||||
return perFolderCache;
|
||||
return getOrCreateCache<Map<ResolvedModuleWithFailedLookupLocations>>(directoryToModuleNameMap, redirectedReference, path, createMap);
|
||||
}
|
||||
|
||||
function getOrCreateCacheForModuleName(nonRelativeModuleName: string): PerModuleNameCache {
|
||||
function getOrCreateCacheForModuleName(nonRelativeModuleName: string, redirectedReference?: ResolvedProjectReference): PerModuleNameCache {
|
||||
Debug.assert(!isExternalModuleNameRelative(nonRelativeModuleName));
|
||||
let perModuleNameCache = moduleNameToDirectoryMap.get(nonRelativeModuleName);
|
||||
if (!perModuleNameCache) {
|
||||
perModuleNameCache = createPerModuleNameCache();
|
||||
moduleNameToDirectoryMap.set(nonRelativeModuleName, perModuleNameCache);
|
||||
return getOrCreateCache(moduleNameToDirectoryMap, redirectedReference, nonRelativeModuleName, createPerModuleNameCache);
|
||||
}
|
||||
|
||||
function getOrCreateCache<T>(cacheWithRedirects: CacheWithRedirects<T>, redirectedReference: ResolvedProjectReference | undefined, key: string, create: () => T): T {
|
||||
const cache = cacheWithRedirects.getOrCreateMapOfCacheRedirects(redirectedReference);
|
||||
let result = cache.get(key);
|
||||
if (!result) {
|
||||
result = create();
|
||||
cache.set(key, result);
|
||||
}
|
||||
return perModuleNameCache;
|
||||
return result;
|
||||
}
|
||||
|
||||
function createPerModuleNameCache(): PerModuleNameCache {
|
||||
@@ -530,13 +591,19 @@ namespace ts {
|
||||
return perFolderCache && perFolderCache.get(moduleName);
|
||||
}
|
||||
|
||||
export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations {
|
||||
export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations {
|
||||
const traceEnabled = isTraceEnabled(compilerOptions, host);
|
||||
if (redirectedReference) {
|
||||
compilerOptions = redirectedReference.commandLine.options;
|
||||
}
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Resolving_module_0_from_1, moduleName, containingFile);
|
||||
if (redirectedReference) {
|
||||
trace(host, Diagnostics.Using_compiler_options_of_project_reference_redirect_0, redirectedReference.sourceFile.fileName);
|
||||
}
|
||||
}
|
||||
const containingDirectory = getDirectoryPath(containingFile);
|
||||
const perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory);
|
||||
const perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory, redirectedReference);
|
||||
let result = perFolderCache && perFolderCache.get(moduleName);
|
||||
|
||||
if (result) {
|
||||
@@ -560,10 +627,10 @@ namespace ts {
|
||||
|
||||
switch (moduleResolution) {
|
||||
case ModuleResolutionKind.NodeJs:
|
||||
result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache);
|
||||
result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference);
|
||||
break;
|
||||
case ModuleResolutionKind.Classic:
|
||||
result = classicNameResolver(moduleName, containingFile, compilerOptions, host, cache);
|
||||
result = classicNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference);
|
||||
break;
|
||||
default:
|
||||
return Debug.fail(`Unexpected moduleResolution: ${moduleResolution}`);
|
||||
@@ -573,7 +640,7 @@ namespace ts {
|
||||
perFolderCache.set(moduleName, result);
|
||||
if (!isExternalModuleNameRelative(moduleName)) {
|
||||
// put result in per-module name cache
|
||||
cache!.getOrCreateCacheForModuleName(moduleName).set(containingDirectory, result);
|
||||
cache!.getOrCreateCacheForModuleName(moduleName, redirectedReference).set(containingDirectory, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -663,6 +730,9 @@ namespace ts {
|
||||
function tryLoadModuleUsingOptionalResolutionSettings(extensions: Extensions, moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader,
|
||||
state: ModuleResolutionState): Resolved | undefined {
|
||||
|
||||
const resolved = tryLoadModuleUsingPathsIfEligible(extensions, moduleName, loader, state);
|
||||
if (resolved) return resolved.value;
|
||||
|
||||
if (!isExternalModuleNameRelative(moduleName)) {
|
||||
return tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, state);
|
||||
}
|
||||
@@ -671,6 +741,17 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function tryLoadModuleUsingPathsIfEligible(extensions: Extensions, moduleName: string, loader: ResolutionKindSpecificLoader, state: ModuleResolutionState) {
|
||||
const { baseUrl, paths } = state.compilerOptions;
|
||||
if (baseUrl && paths && !pathIsRelative(moduleName)) {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, baseUrl, moduleName);
|
||||
trace(state.host, Diagnostics.paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0, moduleName);
|
||||
}
|
||||
return tryLoadModuleUsingPaths(extensions, moduleName, baseUrl, paths, loader, /*onlyRecordFailures*/ false, state);
|
||||
}
|
||||
}
|
||||
|
||||
function tryLoadModuleUsingRootDirs(extensions: Extensions, moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader,
|
||||
state: ModuleResolutionState): Resolved | undefined {
|
||||
|
||||
@@ -749,22 +830,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
function tryLoadModuleUsingBaseUrl(extensions: Extensions, moduleName: string, loader: ResolutionKindSpecificLoader, state: ModuleResolutionState): Resolved | undefined {
|
||||
const { baseUrl, paths } = state.compilerOptions;
|
||||
const { baseUrl } = state.compilerOptions;
|
||||
if (!baseUrl) {
|
||||
return undefined;
|
||||
}
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, baseUrl, moduleName);
|
||||
}
|
||||
if (paths) {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0, moduleName);
|
||||
}
|
||||
const resolved = tryLoadModuleUsingPaths(extensions, moduleName, baseUrl, paths, loader, /*onlyRecordFailures*/ false, state);
|
||||
if (resolved) {
|
||||
return resolved.value;
|
||||
}
|
||||
}
|
||||
const candidate = normalizePath(combinePaths(baseUrl, moduleName));
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.Resolving_module_name_0_relative_to_base_url_1_2, moduleName, baseUrl, candidate);
|
||||
@@ -778,30 +850,41 @@ namespace ts {
|
||||
* Throws an error if the module can't be resolved.
|
||||
*/
|
||||
/* @internal */
|
||||
export function resolveJavascriptModule(moduleName: string, initialDir: string, host: ModuleResolutionHost): string {
|
||||
const { resolvedModule, failedLookupLocations } =
|
||||
nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, /*jsOnly*/ true);
|
||||
export function resolveJSModule(moduleName: string, initialDir: string, host: ModuleResolutionHost): string {
|
||||
const { resolvedModule, failedLookupLocations } = tryResolveJSModuleWorker(moduleName, initialDir, host);
|
||||
if (!resolvedModule) {
|
||||
throw new Error(`Could not resolve JS module '${moduleName}' starting at '${initialDir}'. Looked in: ${failedLookupLocations.join(", ")}`);
|
||||
}
|
||||
return resolvedModule.resolvedFileName;
|
||||
}
|
||||
|
||||
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations {
|
||||
return nodeModuleNameResolverWorker(moduleName, getDirectoryPath(containingFile), compilerOptions, host, cache, /*jsOnly*/ false);
|
||||
/* @internal */
|
||||
export function tryResolveJSModule(moduleName: string, initialDir: string, host: ModuleResolutionHost): string | undefined {
|
||||
const { resolvedModule } = tryResolveJSModuleWorker(moduleName, initialDir, host);
|
||||
return resolvedModule && resolvedModule.resolvedFileName;
|
||||
}
|
||||
|
||||
function nodeModuleNameResolverWorker(moduleName: string, containingDirectory: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache | undefined, jsOnly: boolean): ResolvedModuleWithFailedLookupLocations {
|
||||
const jsOnlyExtensions = [Extensions.JavaScript];
|
||||
const tsExtensions = [Extensions.TypeScript, Extensions.JavaScript];
|
||||
const tsPlusJsonExtensions = [...tsExtensions, Extensions.Json];
|
||||
const tsconfigExtensions = [Extensions.TSConfig];
|
||||
function tryResolveJSModuleWorker(moduleName: string, initialDir: string, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
|
||||
return nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, jsOnlyExtensions, /*redirectedReferences*/ undefined);
|
||||
}
|
||||
|
||||
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations;
|
||||
/* @internal */ export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, lookupConfig?: boolean): ResolvedModuleWithFailedLookupLocations; // tslint:disable-line unified-signatures
|
||||
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, lookupConfig?: boolean): ResolvedModuleWithFailedLookupLocations {
|
||||
return nodeModuleNameResolverWorker(moduleName, getDirectoryPath(containingFile), compilerOptions, host, cache, lookupConfig ? tsconfigExtensions : (compilerOptions.resolveJsonModule ? tsPlusJsonExtensions : tsExtensions), redirectedReference);
|
||||
}
|
||||
|
||||
function nodeModuleNameResolverWorker(moduleName: string, containingDirectory: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache | undefined, extensions: Extensions[], redirectedReference: ResolvedProjectReference | undefined): ResolvedModuleWithFailedLookupLocations {
|
||||
const traceEnabled = isTraceEnabled(compilerOptions, host);
|
||||
|
||||
const failedLookupLocations: string[] = [];
|
||||
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations };
|
||||
|
||||
const result = jsOnly ?
|
||||
tryResolve(Extensions.JavaScript) :
|
||||
(tryResolve(Extensions.TypeScript) ||
|
||||
tryResolve(Extensions.JavaScript) ||
|
||||
(compilerOptions.resolveJsonModule ? tryResolve(Extensions.Json) : undefined));
|
||||
const result = forEach(extensions, ext => tryResolve(ext));
|
||||
if (result && result.value) {
|
||||
const { resolved, isExternalLibraryImport } = result.value;
|
||||
return createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations);
|
||||
@@ -812,14 +895,14 @@ namespace ts {
|
||||
const loader: ResolutionKindSpecificLoader = (extensions, candidate, onlyRecordFailures, state) => nodeLoadModuleByRelativeName(extensions, candidate, onlyRecordFailures, state, /*considerPackageJson*/ true);
|
||||
const resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, state);
|
||||
if (resolved) {
|
||||
return toSearchResult({ resolved, isExternalLibraryImport: stringContains(resolved.path, nodeModulesPathPart) });
|
||||
return toSearchResult({ resolved, isExternalLibraryImport: pathContainsNodeModules(resolved.path) });
|
||||
}
|
||||
|
||||
if (!isExternalModuleNameRelative(moduleName)) {
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]);
|
||||
}
|
||||
const resolved = loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache);
|
||||
const resolved = loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference);
|
||||
if (!resolved) return undefined;
|
||||
|
||||
let resolvedValue = resolved.value;
|
||||
@@ -889,6 +972,10 @@ namespace ts {
|
||||
|
||||
/*@internal*/
|
||||
export const nodeModulesPathPart = "/node_modules/";
|
||||
/*@internal*/
|
||||
export function pathContainsNodeModules(path: string): boolean {
|
||||
return stringContains(path, nodeModulesPathPart);
|
||||
}
|
||||
|
||||
/**
|
||||
* This will be called on the successfully resolved path from `loadModuleFromFile`.
|
||||
@@ -945,9 +1032,9 @@ namespace ts {
|
||||
* in cases when we know upfront that all load attempts will fail (because containing folder does not exists) however we still need to record all failed lookup locations.
|
||||
*/
|
||||
function loadModuleFromFile(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined {
|
||||
if (extensions === Extensions.Json) {
|
||||
if (extensions === Extensions.Json || extensions === Extensions.TSConfig) {
|
||||
const extensionLess = tryRemoveExtension(candidate, Extension.Json);
|
||||
return extensionLess === undefined ? undefined : tryAddingExtensions(extensionLess, extensions, onlyRecordFailures, state);
|
||||
return (extensionLess === undefined && extensions === Extensions.Json) ? undefined : tryAddingExtensions(extensionLess || candidate, extensions, onlyRecordFailures, state);
|
||||
}
|
||||
|
||||
// First, try adding an extension. An import of "foo" could be matched by a file "foo.ts", or "foo.js" by "foo.js.ts"
|
||||
@@ -958,7 +1045,7 @@ namespace ts {
|
||||
|
||||
// If that didn't work, try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one;
|
||||
// e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts"
|
||||
if (hasJavascriptFileExtension(candidate)) {
|
||||
if (hasJSFileExtension(candidate)) {
|
||||
const extensionless = removeFileExtension(candidate);
|
||||
if (state.traceEnabled) {
|
||||
const extension = candidate.substring(extensionless.length);
|
||||
@@ -985,6 +1072,7 @@ namespace ts {
|
||||
return tryExtension(Extension.Ts) || tryExtension(Extension.Tsx) || tryExtension(Extension.Dts);
|
||||
case Extensions.JavaScript:
|
||||
return tryExtension(Extension.Js) || tryExtension(Extension.Jsx);
|
||||
case Extensions.TSConfig:
|
||||
case Extensions.Json:
|
||||
return tryExtension(Extension.Json);
|
||||
}
|
||||
@@ -1022,15 +1110,6 @@ namespace ts {
|
||||
return withPackageId(packageId, loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageJsonContent, versionPaths));
|
||||
}
|
||||
|
||||
function loadNodeModuleFromDirectoryWorker(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState, packageJsonContent: PackageJsonPathFields | undefined, versionPaths: VersionPaths | undefined): PathAndExtension | undefined {
|
||||
const fromPackageJson = packageJsonContent && loadModuleFromPackageJson(packageJsonContent, versionPaths, extensions, candidate, state);
|
||||
if (fromPackageJson) {
|
||||
return fromPackageJson;
|
||||
}
|
||||
const directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host);
|
||||
return loadModuleFromFile(extensions, combinePaths(candidate, "index"), !directoryExists, state);
|
||||
}
|
||||
|
||||
interface PackageJsonInfo {
|
||||
packageJsonContent: PackageJsonPathFields | undefined;
|
||||
packageId: PackageId | undefined;
|
||||
@@ -1052,7 +1131,7 @@ namespace ts {
|
||||
const jsPath = readPackageJsonMainField(packageJsonContent, packageDirectory, state);
|
||||
if (typeof jsPath === "string" && jsPath.length > packageDirectory.length) {
|
||||
const potentialSubModule = jsPath.substring(packageDirectory.length + 1);
|
||||
subModuleName = (forEach(supportedJavascriptExtensions, extension =>
|
||||
subModuleName = (forEach(supportedJSExtensions, extension =>
|
||||
tryRemoveExtension(potentialSubModule, extension)) || potentialSubModule) + Extension.Dts;
|
||||
}
|
||||
else {
|
||||
@@ -1090,20 +1169,26 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function loadModuleFromPackageJson(jsonContent: PackageJsonPathFields, versionPaths: VersionPaths | undefined, extensions: Extensions, candidate: string, state: ModuleResolutionState): PathAndExtension | undefined {
|
||||
let file = extensions !== Extensions.JavaScript && extensions !== Extensions.Json
|
||||
? readPackageJsonTypesFields(jsonContent, candidate, state)
|
||||
: readPackageJsonMainField(jsonContent, candidate, state);
|
||||
if (!file) {
|
||||
if (extensions === Extensions.TypeScript) {
|
||||
// When resolving typescript modules, try resolving using main field as well
|
||||
file = readPackageJsonMainField(jsonContent, candidate, state);
|
||||
if (!file) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
function loadNodeModuleFromDirectoryWorker(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState, jsonContent: PackageJsonPathFields | undefined, versionPaths: VersionPaths | undefined): PathAndExtension | undefined {
|
||||
let packageFile: string | undefined;
|
||||
if (jsonContent) {
|
||||
switch (extensions) {
|
||||
case Extensions.JavaScript:
|
||||
case Extensions.Json:
|
||||
packageFile = readPackageJsonMainField(jsonContent, candidate, state);
|
||||
break;
|
||||
case Extensions.TypeScript:
|
||||
// When resolving typescript modules, try resolving using main field as well
|
||||
packageFile = readPackageJsonTypesFields(jsonContent, candidate, state) || readPackageJsonMainField(jsonContent, candidate, state);
|
||||
break;
|
||||
case Extensions.DtsOnly:
|
||||
packageFile = readPackageJsonTypesFields(jsonContent, candidate, state);
|
||||
break;
|
||||
case Extensions.TSConfig:
|
||||
packageFile = readPackageJsonTSConfigField(jsonContent, candidate, state);
|
||||
break;
|
||||
default:
|
||||
return Debug.assertNever(extensions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1125,21 +1210,26 @@ namespace ts {
|
||||
return nodeLoadModuleByRelativeName(nextExtensions, candidate, onlyRecordFailures, state, /*considerPackageJson*/ false);
|
||||
};
|
||||
|
||||
const onlyRecordFailures = !directoryProbablyExists(getDirectoryPath(file), state.host);
|
||||
const onlyRecordFailuresForPackageFile = packageFile ? !directoryProbablyExists(getDirectoryPath(packageFile), state.host) : undefined;
|
||||
const onlyRecordFailuresForIndex = onlyRecordFailures || !directoryProbablyExists(candidate, state.host);
|
||||
const indexPath = combinePaths(candidate, extensions === Extensions.TSConfig ? "tsconfig" : "index");
|
||||
|
||||
if (versionPaths && containsPath(candidate, file)) {
|
||||
const moduleName = getRelativePathFromDirectory(candidate, file, /*ignoreCase*/ false);
|
||||
if (versionPaths && (!packageFile || containsPath(candidate, packageFile))) {
|
||||
const moduleName = getRelativePathFromDirectory(candidate, packageFile || indexPath, /*ignoreCase*/ false);
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2, versionPaths.version, version, moduleName);
|
||||
}
|
||||
const result = tryLoadModuleUsingPaths(extensions, moduleName, candidate, versionPaths.paths, loader, onlyRecordFailures, state);
|
||||
const result = tryLoadModuleUsingPaths(extensions, moduleName, candidate, versionPaths.paths, loader, onlyRecordFailuresForPackageFile || onlyRecordFailuresForIndex, state);
|
||||
if (result) {
|
||||
return removeIgnoredPackageId(result.value);
|
||||
}
|
||||
}
|
||||
|
||||
// It won't have a `packageId` set, because we disabled `considerPackageJson`.
|
||||
return removeIgnoredPackageId(loader(extensions, file, onlyRecordFailures, state));
|
||||
const packageFileResult = packageFile && removeIgnoredPackageId(loader(extensions, packageFile, onlyRecordFailuresForPackageFile!, state));
|
||||
if (packageFileResult) return packageFileResult;
|
||||
|
||||
return loadModuleFromFile(extensions, indexPath, onlyRecordFailuresForIndex, state);
|
||||
}
|
||||
|
||||
/** Resolve from an arbitrarily specified file. Return `undefined` if it has an unsupported extension. */
|
||||
@@ -1153,6 +1243,7 @@ namespace ts {
|
||||
switch (extensions) {
|
||||
case Extensions.JavaScript:
|
||||
return extension === Extension.Js || extension === Extension.Jsx;
|
||||
case Extensions.TSConfig:
|
||||
case Extensions.Json:
|
||||
return extension === Extension.Json;
|
||||
case Extensions.TypeScript:
|
||||
@@ -1171,17 +1262,17 @@ namespace ts {
|
||||
return idx === -1 ? { packageName: moduleName, rest: "" } : { packageName: moduleName.slice(0, idx), rest: moduleName.slice(idx + 1) };
|
||||
}
|
||||
|
||||
function loadModuleFromNearestNodeModulesDirectory(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, cache: NonRelativeModuleNameResolutionCache | undefined): SearchResult<Resolved> {
|
||||
return loadModuleFromNearestNodeModulesDirectoryWorker(extensions, moduleName, directory, state, /*typesScopeOnly*/ false, cache);
|
||||
function loadModuleFromNearestNodeModulesDirectory(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, cache: NonRelativeModuleNameResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult<Resolved> {
|
||||
return loadModuleFromNearestNodeModulesDirectoryWorker(extensions, moduleName, directory, state, /*typesScopeOnly*/ false, cache, redirectedReference);
|
||||
}
|
||||
|
||||
function loadModuleFromNearestNodeModulesDirectoryTypesScope(moduleName: string, directory: string, state: ModuleResolutionState): SearchResult<Resolved> {
|
||||
// Extensions parameter here doesn't actually matter, because typesOnly ensures we're just doing @types lookup, which is always DtsOnly.
|
||||
return loadModuleFromNearestNodeModulesDirectoryWorker(Extensions.DtsOnly, moduleName, directory, state, /*typesScopeOnly*/ true, /*cache*/ undefined);
|
||||
return loadModuleFromNearestNodeModulesDirectoryWorker(Extensions.DtsOnly, moduleName, directory, state, /*typesScopeOnly*/ true, /*cache*/ undefined, /*redirectedReference*/ undefined);
|
||||
}
|
||||
|
||||
function loadModuleFromNearestNodeModulesDirectoryWorker(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, typesScopeOnly: boolean, cache: NonRelativeModuleNameResolutionCache | undefined): SearchResult<Resolved> {
|
||||
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName);
|
||||
function loadModuleFromNearestNodeModulesDirectoryWorker(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, typesScopeOnly: boolean, cache: NonRelativeModuleNameResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult<Resolved> {
|
||||
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName, redirectedReference);
|
||||
return forEachAncestorDirectory(normalizeSlashes(directory), ancestorDirectory => {
|
||||
if (getBaseFileName(ancestorDirectory) !== "node_modules") {
|
||||
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, ancestorDirectory, state);
|
||||
@@ -1204,7 +1295,7 @@ namespace ts {
|
||||
if (packageResult) {
|
||||
return packageResult;
|
||||
}
|
||||
if (extensions !== Extensions.JavaScript && extensions !== Extensions.Json) {
|
||||
if (extensions === Extensions.TypeScript || extensions === Extensions.DtsOnly) {
|
||||
const nodeModulesAtTypes = combinePaths(nodeModulesFolder, "@types");
|
||||
let nodeModulesAtTypesExists = nodeModulesFolderExists;
|
||||
if (nodeModulesFolderExists && !directoryProbablyExists(nodeModulesAtTypes, state.host)) {
|
||||
@@ -1349,7 +1440,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache): ResolvedModuleWithFailedLookupLocations {
|
||||
export function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations {
|
||||
const traceEnabled = isTraceEnabled(compilerOptions, host);
|
||||
const failedLookupLocations: string[] = [];
|
||||
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations };
|
||||
@@ -1366,7 +1457,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (!isExternalModuleNameRelative(moduleName)) {
|
||||
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName);
|
||||
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName, redirectedReference);
|
||||
// Climb up parent directories looking for a module.
|
||||
const resolved = forEachAncestorDirectory(containingDirectory, directory => {
|
||||
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, directory, state);
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace ts.moduleSpecifiers {
|
||||
function getPreferencesForUpdate(compilerOptions: CompilerOptions, oldImportSpecifier: string): Preferences {
|
||||
return {
|
||||
relativePreference: isExternalModuleNameRelative(oldImportSpecifier) ? RelativePreference.Relative : RelativePreference.NonRelative,
|
||||
ending: hasJavascriptOrJsonFileExtension(oldImportSpecifier) ? Ending.JsExtension
|
||||
ending: hasJSOrJsonFileExtension(oldImportSpecifier) ? Ending.JsExtension
|
||||
: getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeJs || endsWith(oldImportSpecifier, "index") ? Ending.Index : Ending.Minimal,
|
||||
};
|
||||
}
|
||||
@@ -139,7 +139,7 @@ namespace ts.moduleSpecifiers {
|
||||
return isPathRelativeToParent(nonRelative) || countPathComponents(relativePath) < countPathComponents(nonRelative) ? relativePath : nonRelative;
|
||||
}
|
||||
|
||||
function countPathComponents(path: string): number {
|
||||
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++;
|
||||
@@ -148,7 +148,7 @@ namespace ts.moduleSpecifiers {
|
||||
}
|
||||
|
||||
function usesJsExtensionOnImports({ imports }: SourceFile): boolean {
|
||||
return firstDefined(imports, ({ text }) => pathIsRelative(text) ? hasJavascriptOrJsonFileExtension(text) : undefined) || false;
|
||||
return firstDefined(imports, ({ text }) => pathIsRelative(text) ? hasJSOrJsonFileExtension(text) : undefined) || false;
|
||||
}
|
||||
|
||||
function stringsEqual(a: string, b: string, getCanonicalFileName: GetCanonicalFileName): boolean {
|
||||
@@ -260,6 +260,9 @@ namespace ts.moduleSpecifiers {
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -267,8 +270,8 @@ namespace ts.moduleSpecifiers {
|
||||
|
||||
const packageRootPath = moduleFileName.substring(0, parts.packageRootIndex);
|
||||
const packageJsonPath = combinePaths(packageRootPath, "package.json");
|
||||
const packageJsonContent = host.fileExists!(packageJsonPath)
|
||||
? JSON.parse(host.readFile!(packageJsonPath)!)
|
||||
const packageJsonContent = host.fileExists(packageJsonPath)
|
||||
? JSON.parse(host.readFile(packageJsonPath)!)
|
||||
: undefined;
|
||||
const versionPaths = packageJsonContent && packageJsonContent.typesVersions
|
||||
? getPackageJsonTypesVersionsPaths(packageJsonContent.typesVersions)
|
||||
@@ -325,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;
|
||||
}
|
||||
}
|
||||
@@ -415,13 +419,13 @@ namespace ts.moduleSpecifiers {
|
||||
case Ending.Index:
|
||||
return noExtension;
|
||||
case Ending.JsExtension:
|
||||
return noExtension + getJavascriptExtensionForFile(fileName, options);
|
||||
return noExtension + getJSExtensionForFile(fileName, options);
|
||||
default:
|
||||
return Debug.assertNever(ending);
|
||||
}
|
||||
}
|
||||
|
||||
function getJavascriptExtensionForFile(fileName: string, options: CompilerOptions): Extension {
|
||||
function getJSExtensionForFile(fileName: string, options: CompilerOptions): Extension {
|
||||
const ext = extensionFromPath(fileName);
|
||||
switch (ext) {
|
||||
case Extension.Ts:
|
||||
|
||||
+112
-123
@@ -462,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 visitNode(cbNode, (<JSDocTemplateTag>node).constraint) || 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);
|
||||
}
|
||||
@@ -1482,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:
|
||||
@@ -1510,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:
|
||||
@@ -2237,8 +2241,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;
|
||||
@@ -2882,8 +2885,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 {
|
||||
@@ -2892,6 +2896,7 @@ namespace ts {
|
||||
case SyntaxKind.UnknownKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
case SyntaxKind.NumberKeyword:
|
||||
case SyntaxKind.BigIntKeyword:
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
case SyntaxKind.BooleanKeyword:
|
||||
case SyntaxKind.UndefinedKeyword:
|
||||
@@ -2912,11 +2917,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>();
|
||||
@@ -2950,6 +2956,7 @@ namespace ts {
|
||||
case SyntaxKind.UnknownKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
case SyntaxKind.NumberKeyword:
|
||||
case SyntaxKind.BigIntKeyword:
|
||||
case SyntaxKind.BooleanKeyword:
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
case SyntaxKind.UniqueKeyword:
|
||||
@@ -2967,6 +2974,7 @@ namespace ts {
|
||||
case SyntaxKind.NewKeyword:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
case SyntaxKind.ObjectKeyword:
|
||||
@@ -2980,7 +2988,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.
|
||||
@@ -3205,6 +3213,7 @@ namespace ts {
|
||||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
case SyntaxKind.TemplateHead:
|
||||
@@ -4614,6 +4623,7 @@ namespace ts {
|
||||
function parsePrimaryExpression(): PrimaryExpression {
|
||||
switch (token()) {
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
return parseLiteralNode();
|
||||
@@ -4728,8 +4738,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);
|
||||
@@ -5130,7 +5139,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 {
|
||||
@@ -6308,7 +6317,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);
|
||||
@@ -6441,13 +6450,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();
|
||||
@@ -6462,7 +6464,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;
|
||||
@@ -6538,51 +6542,50 @@ namespace ts {
|
||||
|
||||
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();
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -6665,9 +6668,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);
|
||||
}
|
||||
@@ -6724,7 +6726,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function parseParameterOrPropertyTag(atToken: AtToken, tagName: Identifier, target: PropertyLikeParse, indent: number): JSDocParameterTag | JSDocPropertyTag {
|
||||
function parseParameterOrPropertyTag(start: number, tagName: Identifier, target: PropertyLikeParse, indent: number): JSDocParameterTag | JSDocPropertyTag {
|
||||
let typeExpression = tryParseTypeExpression();
|
||||
let isNameFirst = !typeExpression;
|
||||
skipWhitespaceOrAsterisk();
|
||||
@@ -6737,15 +6739,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
const result = target === PropertyLikeParse.Property ?
|
||||
<JSDocPropertyTag>createNode(SyntaxKind.JSDocPropertyTag, atToken.pos) :
|
||||
<JSDocParameterTag>createNode(SyntaxKind.JSDocParameterTag, atToken.pos);
|
||||
const comment = parseTagComments(indent + scanner.getStartPos() - atToken.pos);
|
||||
<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;
|
||||
@@ -6779,33 +6780,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);
|
||||
@@ -6834,37 +6832,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();
|
||||
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);
|
||||
@@ -6877,7 +6871,6 @@ namespace ts {
|
||||
let child: JSDocTypeTag | JSDocPropertyTag | false;
|
||||
let jsdocTypeLiteral: JSDocTypeLiteral | undefined;
|
||||
let childTypeTag: JSDocTypeTag | undefined;
|
||||
const start = atToken.pos;
|
||||
while (child = tryParse(() => parseChildPropertyTag(indent))) {
|
||||
if (!jsdocTypeLiteral) {
|
||||
jsdocTypeLiteral = <JSDocTypeLiteral>createNode(SyntaxKind.JSDocTypeLiteral, start);
|
||||
@@ -6931,9 +6924,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);
|
||||
@@ -6941,7 +6933,6 @@ 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, indent) as JSDocParameterTag)) {
|
||||
@@ -7029,8 +7020,7 @@ namespace ts {
|
||||
|
||||
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();
|
||||
@@ -7038,7 +7028,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;
|
||||
@@ -7054,10 +7044,10 @@ namespace ts {
|
||||
if (!(target & t)) {
|
||||
return false;
|
||||
}
|
||||
return parseParameterOrPropertyTag(atToken, tagName, target, indent);
|
||||
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) {
|
||||
@@ -7075,8 +7065,7 @@ namespace ts {
|
||||
typeParameters.push(typeParameter);
|
||||
} while (parseOptionalJsdoc(SyntaxKind.CommaToken));
|
||||
|
||||
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);
|
||||
@@ -7724,7 +7713,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
|
||||
@@ -7779,7 +7768,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;
|
||||
@@ -7802,7 +7791,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": {
|
||||
@@ -7812,11 +7801,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;
|
||||
}
|
||||
@@ -7852,10 +7841,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;
|
||||
@@ -7882,10 +7871,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;
|
||||
}
|
||||
@@ -7904,9 +7893,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;
|
||||
@@ -7914,7 +7903,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.
|
||||
*
|
||||
|
||||
+424
-248
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, nodeModulesPathPart)) {
|
||||
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 {
|
||||
|
||||
+165
-138
@@ -60,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,
|
||||
@@ -913,7 +920,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;
|
||||
@@ -937,18 +944,29 @@ 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) {
|
||||
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
|
||||
return { type, value: tokenValue };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -965,24 +983,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) {
|
||||
@@ -999,29 +1017,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 {
|
||||
@@ -1201,7 +1215,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
|
||||
@@ -1288,28 +1303,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) {
|
||||
@@ -1331,27 +1343,42 @@ 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;
|
||||
@@ -1500,7 +1527,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) {
|
||||
@@ -1576,36 +1603,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))) {
|
||||
@@ -1626,8 +1653,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;
|
||||
@@ -2016,7 +2043,7 @@ namespace ts {
|
||||
pos++;
|
||||
}
|
||||
tokenValue = text.substring(tokenPos, pos);
|
||||
return token = SyntaxKind.Identifier;
|
||||
return token = getIdentifierToken();
|
||||
}
|
||||
else {
|
||||
return token = SyntaxKind.Unknown;
|
||||
|
||||
+642
-546
File diff suppressed because it is too large
Load Diff
@@ -1,377 +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);
|
||||
// file returned here could be .d.ts when asked for .ts file if projectReferences and module resolution created this source file
|
||||
if (!file || file.resolvedPath !== path) {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
+14
-28
@@ -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;
|
||||
@@ -792,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);
|
||||
@@ -843,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[] = [];
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace ts {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ namespace ts {
|
||||
reportInaccessibleThisError,
|
||||
reportInaccessibleUniqueSymbolError,
|
||||
reportPrivateInBaseOfClassExpression,
|
||||
reportLikelyUnsafeImportRequiredError,
|
||||
moduleResolverHost: host,
|
||||
trackReferencedAmbientModule,
|
||||
trackExternalModuleSymbolOfImportTypeNode
|
||||
@@ -153,6 +154,14 @@ 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;
|
||||
@@ -275,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) {
|
||||
@@ -373,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;
|
||||
}
|
||||
@@ -1043,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 => {
|
||||
|
||||
@@ -434,7 +434,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 +446,7 @@ namespace ts {
|
||||
return {
|
||||
diagnosticMessage,
|
||||
errorNode: node,
|
||||
typeName: getNameOfDeclaration((node as ExpressionWithTypeArguments).parent.parent)
|
||||
typeName: getNameOfDeclaration(node.parent.parent as Declaration)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -466,4 +466,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);
|
||||
|
||||
+458
-161
@@ -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);
|
||||
@@ -2610,7 +2620,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;
|
||||
}
|
||||
|
||||
@@ -2639,7 +2682,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
|
||||
@@ -2658,7 +2701,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:
|
||||
@@ -2670,74 +2808,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(
|
||||
@@ -2752,11 +3127,11 @@ namespace ts {
|
||||
containsYield ? createToken(SyntaxKind.AsteriskToken) : undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
loopParameters,
|
||||
currentState.loopParameters,
|
||||
/*type*/ undefined,
|
||||
<Block>loopBody
|
||||
loopBody
|
||||
),
|
||||
loopBodyFlags
|
||||
emitFlags
|
||||
)
|
||||
)
|
||||
]
|
||||
@@ -2765,106 +3140,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 {
|
||||
@@ -2873,14 +3150,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
|
||||
@@ -2891,8 +3180,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)
|
||||
@@ -2900,7 +3189,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");
|
||||
@@ -2911,12 +3200,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 {
|
||||
@@ -2949,8 +3238,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,
|
||||
@@ -2998,20 +3287,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 });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3432,7 +3729,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))) {
|
||||
|
||||
@@ -3442,7 +3739,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)
|
||||
@@ -3505,7 +3802,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)
|
||||
@@ -4079,7 +4376,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]
|
||||
),
|
||||
|
||||
@@ -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
|
||||
|
||||
+504
-467
File diff suppressed because it is too large
Load Diff
@@ -25,7 +25,7 @@
|
||||
"checker.ts",
|
||||
"factory.ts",
|
||||
"visitor.ts",
|
||||
"sourcemapDecoder.ts",
|
||||
"sourcemap.ts",
|
||||
"transformers/utilities.ts",
|
||||
"transformers/destructuring.ts",
|
||||
"transformers/ts.ts",
|
||||
@@ -42,8 +42,6 @@
|
||||
"transformers/declarations/diagnostics.ts",
|
||||
"transformers/declarations.ts",
|
||||
"transformer.ts",
|
||||
"sourcemap.ts",
|
||||
"comments.ts",
|
||||
"emitter.ts",
|
||||
"watchUtilities.ts",
|
||||
"program.ts",
|
||||
@@ -52,6 +50,7 @@
|
||||
"resolutionCache.ts",
|
||||
"moduleSpecifiers.ts",
|
||||
"watch.ts",
|
||||
"tsbuild.ts"
|
||||
"tsbuild.ts",
|
||||
"inspectValue.ts",
|
||||
]
|
||||
}
|
||||
|
||||
+382
-143
File diff suppressed because it is too large
Load Diff
+354
-144
@@ -7,7 +7,7 @@ namespace ts {
|
||||
return pathIsRelative(moduleName) || isRootedDiskPath(moduleName);
|
||||
}
|
||||
|
||||
export function sortAndDeduplicateDiagnostics<T extends Diagnostic>(diagnostics: ReadonlyArray<T>): T[] {
|
||||
export function sortAndDeduplicateDiagnostics<T extends Diagnostic>(diagnostics: ReadonlyArray<T>): SortedReadonlyArray<T> {
|
||||
return sortAndDeduplicate<T>(diagnostics, compareDiagnostics);
|
||||
}
|
||||
}
|
||||
@@ -64,7 +64,6 @@ namespace ts {
|
||||
getText: () => str,
|
||||
write: writeText,
|
||||
rawWrite: writeText,
|
||||
writeTextOfNode: writeText,
|
||||
writeKeyword: writeText,
|
||||
writeOperator: writeText,
|
||||
writePunctuation: writeText,
|
||||
@@ -73,7 +72,9 @@ namespace ts {
|
||||
writeLiteral: writeText,
|
||||
writeParameter: writeText,
|
||||
writeProperty: writeText,
|
||||
writeSymbol: writeText,
|
||||
writeSymbol: (s, _) => writeText(s),
|
||||
writeTrailingSemicolon: writeText,
|
||||
writeComment: writeText,
|
||||
getTextPos: () => str.length,
|
||||
getLine: () => 0,
|
||||
getColumn: () => 0,
|
||||
@@ -101,22 +102,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function changesAffectModuleResolution(oldOptions: CompilerOptions, newOptions: CompilerOptions): boolean {
|
||||
return !oldOptions ||
|
||||
(oldOptions.module !== newOptions.module) ||
|
||||
(oldOptions.moduleResolution !== newOptions.moduleResolution) ||
|
||||
(oldOptions.noResolve !== newOptions.noResolve) ||
|
||||
(oldOptions.target !== newOptions.target) ||
|
||||
(oldOptions.noLib !== newOptions.noLib) ||
|
||||
(oldOptions.jsx !== newOptions.jsx) ||
|
||||
(oldOptions.allowJs !== newOptions.allowJs) ||
|
||||
(oldOptions.rootDir !== newOptions.rootDir) ||
|
||||
(oldOptions.configFilePath !== newOptions.configFilePath) ||
|
||||
(oldOptions.baseUrl !== newOptions.baseUrl) ||
|
||||
(oldOptions.maxNodeModuleJsDepth !== newOptions.maxNodeModuleJsDepth) ||
|
||||
!arrayIsEqualTo(oldOptions.lib, newOptions.lib) ||
|
||||
!arrayIsEqualTo(oldOptions.typeRoots, newOptions.typeRoots) ||
|
||||
!arrayIsEqualTo(oldOptions.rootDirs, newOptions.rootDirs) ||
|
||||
!equalOwnProperties(oldOptions.paths, newOptions.paths);
|
||||
return oldOptions.configFilePath !== newOptions.configFilePath || moduleResolutionOptionDeclarations.some(o =>
|
||||
!isJsonEqual(getCompilerOptionValue(oldOptions, o), getCompilerOptionValue(newOptions, o)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -241,14 +228,20 @@ namespace ts {
|
||||
sourceFile.resolvedModules.set(moduleNameText, resolvedModule);
|
||||
}
|
||||
|
||||
export function setResolvedTypeReferenceDirective(sourceFile: SourceFile, typeReferenceDirectiveName: string, resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective): void {
|
||||
export function setResolvedTypeReferenceDirective(sourceFile: SourceFile, typeReferenceDirectiveName: string, resolvedTypeReferenceDirective?: ResolvedTypeReferenceDirective): void {
|
||||
if (!sourceFile.resolvedTypeReferenceDirectiveNames) {
|
||||
sourceFile.resolvedTypeReferenceDirectiveNames = createMap<ResolvedTypeReferenceDirective>();
|
||||
sourceFile.resolvedTypeReferenceDirectiveNames = createMap<ResolvedTypeReferenceDirective | undefined>();
|
||||
}
|
||||
|
||||
sourceFile.resolvedTypeReferenceDirectiveNames.set(typeReferenceDirectiveName, resolvedTypeReferenceDirective);
|
||||
}
|
||||
|
||||
export function projectReferenceIsEqualTo(oldRef: ProjectReference, newRef: ProjectReference) {
|
||||
return oldRef.path === newRef.path &&
|
||||
!oldRef.prepend === !newRef.prepend &&
|
||||
!oldRef.circular === !newRef.circular;
|
||||
}
|
||||
|
||||
export function moduleResolutionIsEqualTo(oldResolution: ResolvedModuleFull, newResolution: ResolvedModuleFull): boolean {
|
||||
return oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport &&
|
||||
oldResolution.extension === newResolution.extension &&
|
||||
@@ -532,14 +525,17 @@ namespace ts {
|
||||
return emitNode && emitNode.flags || 0;
|
||||
}
|
||||
|
||||
export function getLiteralText(node: LiteralLikeNode, sourceFile: SourceFile) {
|
||||
export function getLiteralText(node: LiteralLikeNode, sourceFile: SourceFile, neverAsciiEscape: boolean | undefined) {
|
||||
// If we don't need to downlevel and we can reach the original source text using
|
||||
// the node's parent reference, then simply get the text as it was originally written.
|
||||
if (!nodeIsSynthesized(node) && node.parent && !(isNumericLiteral(node) && node.numericLiteralFlags & TokenFlags.ContainsSeparator)) {
|
||||
if (!nodeIsSynthesized(node) && node.parent && !(
|
||||
(isNumericLiteral(node) && node.numericLiteralFlags & TokenFlags.ContainsSeparator) ||
|
||||
isBigIntLiteral(node)
|
||||
)) {
|
||||
return getSourceTextOfNodeFromSourceFile(sourceFile, node);
|
||||
}
|
||||
|
||||
const escapeText = getEmitFlags(node) & EmitFlags.NoAsciiEscaping ? escapeString : escapeNonAsciiString;
|
||||
const escapeText = neverAsciiEscape || (getEmitFlags(node) & EmitFlags.NoAsciiEscaping) ? escapeString : escapeNonAsciiString;
|
||||
|
||||
// If we can't reach the original source text, use the canonical form if it's a number,
|
||||
// or a (possibly escaped) quoted form of the original text if it's string-like.
|
||||
@@ -562,6 +558,7 @@ namespace ts {
|
||||
case SyntaxKind.TemplateTail:
|
||||
return "}" + escapeText(node.text, CharacterCodes.backtick) + "`";
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
case SyntaxKind.RegularExpressionLiteral:
|
||||
return node.text;
|
||||
}
|
||||
@@ -773,12 +770,13 @@ namespace ts {
|
||||
return info.declaration ? declarationNameToString(info.declaration.parameters[0].name) : undefined;
|
||||
}
|
||||
|
||||
export function getTextOfPropertyName(name: PropertyName): __String {
|
||||
export function getTextOfPropertyName(name: PropertyName | NoSubstitutionTemplateLiteral): __String {
|
||||
switch (name.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return name.escapedText;
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
return escapeLeadingUnderscores(name.text);
|
||||
case SyntaxKind.ComputedPropertyName:
|
||||
return isStringOrNumericLiteralLike(name.expression) ? escapeLeadingUnderscores(name.expression.text) : undefined!; // TODO: GH#18217 Almost all uses of this assume the result to be defined!
|
||||
@@ -983,9 +981,11 @@ namespace ts {
|
||||
case SyntaxKind.AnyKeyword:
|
||||
case SyntaxKind.UnknownKeyword:
|
||||
case SyntaxKind.NumberKeyword:
|
||||
case SyntaxKind.BigIntKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
case SyntaxKind.BooleanKeyword:
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
case SyntaxKind.ObjectKeyword:
|
||||
case SyntaxKind.UndefinedKeyword:
|
||||
case SyntaxKind.NeverKeyword:
|
||||
return true;
|
||||
@@ -1605,6 +1605,7 @@ namespace ts {
|
||||
}
|
||||
// falls through
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.ThisKeyword:
|
||||
return isInExpressionContext(node);
|
||||
@@ -1682,7 +1683,7 @@ namespace ts {
|
||||
return isInJSFile(file);
|
||||
}
|
||||
|
||||
export function isSourceFileNotJavascript(file: SourceFile): boolean {
|
||||
export function isSourceFileNotJS(file: SourceFile): boolean {
|
||||
return !isInJSFile(file);
|
||||
}
|
||||
|
||||
@@ -1777,7 +1778,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function isAssignmentDeclaration(decl: Declaration) {
|
||||
return isBinaryExpression(decl) || isPropertyAccessExpression(decl) || isIdentifier(decl);
|
||||
return isBinaryExpression(decl) || isPropertyAccessExpression(decl) || isIdentifier(decl) || isCallExpression(decl);
|
||||
}
|
||||
|
||||
/** Get the initializer, taking into account defaulted Javascript initializers */
|
||||
@@ -1796,16 +1797,26 @@ namespace ts {
|
||||
return init && getExpandoInitializer(init, isPrototypeAccess(node.name));
|
||||
}
|
||||
|
||||
function hasExpandoValueProperty(node: ObjectLiteralExpression, isPrototypeAssignment: boolean) {
|
||||
return forEach(node.properties, p => isPropertyAssignment(p) && isIdentifier(p.name) && p.name.escapedText === "value" && p.initializer && getExpandoInitializer(p.initializer, isPrototypeAssignment));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the assignment 'initializer' -- the righthand side-- when the initializer is container-like (See getExpandoInitializer).
|
||||
* We treat the right hand side of assignments with container-like initalizers as declarations.
|
||||
*/
|
||||
export function getAssignedExpandoInitializer(node: Node) {
|
||||
export function getAssignedExpandoInitializer(node: Node | undefined) {
|
||||
if (node && node.parent && isBinaryExpression(node.parent) && node.parent.operatorToken.kind === SyntaxKind.EqualsToken) {
|
||||
const isPrototypeAssignment = isPrototypeAccess(node.parent.left);
|
||||
return getExpandoInitializer(node.parent.right, isPrototypeAssignment) ||
|
||||
getDefaultedExpandoInitializer(node.parent.left as EntityNameExpression, node.parent.right, isPrototypeAssignment);
|
||||
}
|
||||
if (node && isCallExpression(node) && isBindableObjectDefinePropertyCall(node)) {
|
||||
const result = hasExpandoValueProperty(node.arguments[2], node.arguments[1].text === "prototype");
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1912,12 +1923,35 @@ namespace ts {
|
||||
|
||||
/// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property
|
||||
/// assignments we treat as special in the binder
|
||||
export function getAssignmentDeclarationKind(expr: BinaryExpression): AssignmentDeclarationKind {
|
||||
export function getAssignmentDeclarationKind(expr: BinaryExpression | CallExpression): AssignmentDeclarationKind {
|
||||
const special = getAssignmentDeclarationKindWorker(expr);
|
||||
return special === AssignmentDeclarationKind.Property || isInJSFile(expr) ? special : AssignmentDeclarationKind.None;
|
||||
}
|
||||
|
||||
function getAssignmentDeclarationKindWorker(expr: BinaryExpression): AssignmentDeclarationKind {
|
||||
export function isBindableObjectDefinePropertyCall(expr: CallExpression): expr is BindableObjectDefinePropertyCall {
|
||||
return length(expr.arguments) === 3 &&
|
||||
isPropertyAccessExpression(expr.expression) &&
|
||||
isIdentifier(expr.expression.expression) &&
|
||||
idText(expr.expression.expression) === "Object" &&
|
||||
idText(expr.expression.name) === "defineProperty" &&
|
||||
isStringOrNumericLiteralLike(expr.arguments[1]) &&
|
||||
isEntityNameExpression(expr.arguments[0]);
|
||||
}
|
||||
|
||||
function getAssignmentDeclarationKindWorker(expr: BinaryExpression | CallExpression): AssignmentDeclarationKind {
|
||||
if (isCallExpression(expr)) {
|
||||
if (!isBindableObjectDefinePropertyCall(expr)) {
|
||||
return AssignmentDeclarationKind.None;
|
||||
}
|
||||
const entityName = expr.arguments[0];
|
||||
if (isExportsIdentifier(entityName) || isModuleExportsPropertyAccessExpression(entityName)) {
|
||||
return AssignmentDeclarationKind.ObjectDefinePropertyExports;
|
||||
}
|
||||
if (isPropertyAccessExpression(entityName) && entityName.name.escapedText === "prototype" && isEntityNameExpression(entityName.expression)) {
|
||||
return AssignmentDeclarationKind.ObjectDefinePrototypeProperty;
|
||||
}
|
||||
return AssignmentDeclarationKind.ObjectDefinePropertyValue;
|
||||
}
|
||||
if (expr.operatorToken.kind !== SyntaxKind.EqualsToken ||
|
||||
!isPropertyAccessExpression(expr.left)) {
|
||||
return AssignmentDeclarationKind.None;
|
||||
@@ -1934,7 +1968,7 @@ namespace ts {
|
||||
if (lhs.expression.kind === SyntaxKind.ThisKeyword) {
|
||||
return AssignmentDeclarationKind.ThisProperty;
|
||||
}
|
||||
else if (isIdentifier(lhs.expression) && lhs.expression.escapedText === "module" && lhs.name.escapedText === "exports") {
|
||||
else if (isModuleExportsPropertyAccessExpression(lhs)) {
|
||||
// module.exports = expr
|
||||
return AssignmentDeclarationKind.ModuleExports;
|
||||
}
|
||||
@@ -1999,7 +2033,7 @@ namespace ts {
|
||||
case SyntaxKind.ExternalModuleReference:
|
||||
return (node.parent as ExternalModuleReference).parent as AnyValidImportOrReExport;
|
||||
case SyntaxKind.CallExpression:
|
||||
return node.parent as AnyValidImportOrReExport;
|
||||
return isImportCall(node.parent) || isRequireCall(node.parent, /*checkArg*/ false) ? node.parent as RequireOrImportCall : undefined;
|
||||
case SyntaxKind.LiteralType:
|
||||
Debug.assert(isStringLiteral(node));
|
||||
return tryCast(node.parent.parent, isImportTypeNode) as ValidImportTypeNode | undefined;
|
||||
@@ -2057,10 +2091,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function isJSDocConstructSignature(node: Node) {
|
||||
return node.kind === SyntaxKind.JSDocFunctionType &&
|
||||
(node as JSDocFunctionType).parameters.length > 0 &&
|
||||
(node as JSDocFunctionType).parameters[0].name &&
|
||||
((node as JSDocFunctionType).parameters[0].name as Identifier).escapedText === "new";
|
||||
const param = isJSDocFunctionType(node) ? firstOrUndefined(node.parameters) : undefined;
|
||||
const name = tryCast(param && param.name, isIdentifier);
|
||||
return !!name && name.escapedText === "new";
|
||||
}
|
||||
|
||||
export function isJSDocTypeAlias(node: Node): node is JSDocTypedefTag | JSDocCallbackTag {
|
||||
@@ -2463,6 +2496,7 @@ namespace ts {
|
||||
// export { x as <symbol> } from ...
|
||||
// export = <EntityNameExpression>
|
||||
// export default <EntityNameExpression>
|
||||
// module.exports = <EntityNameExpression>
|
||||
export function isAliasSymbolDeclaration(node: Node): boolean {
|
||||
return node.kind === SyntaxKind.ImportEqualsDeclaration ||
|
||||
node.kind === SyntaxKind.NamespaceExportDeclaration ||
|
||||
@@ -2471,7 +2505,7 @@ namespace ts {
|
||||
node.kind === SyntaxKind.ImportSpecifier ||
|
||||
node.kind === SyntaxKind.ExportSpecifier ||
|
||||
node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(<ExportAssignment>node) ||
|
||||
isBinaryExpression(node) && getAssignmentDeclarationKind(node) === AssignmentDeclarationKind.ModuleExports;
|
||||
isBinaryExpression(node) && getAssignmentDeclarationKind(node) === AssignmentDeclarationKind.ModuleExports && exportAssignmentIsAlias(node);
|
||||
}
|
||||
|
||||
export function exportAssignmentIsAlias(node: ExportAssignment | BinaryExpression): boolean {
|
||||
@@ -2558,6 +2592,10 @@ namespace ts {
|
||||
return token !== undefined && isNonContextualKeyword(token);
|
||||
}
|
||||
|
||||
export function isIdentifierANonContextualKeyword({ originalKeywordKind }: Identifier): boolean {
|
||||
return !!originalKeywordKind && !isContextualKeyword(originalKeywordKind);
|
||||
}
|
||||
|
||||
export type TriviaKind = SyntaxKind.SingleLineCommentTrivia
|
||||
| SyntaxKind.MultiLineCommentTrivia
|
||||
| SyntaxKind.NewLineTrivia
|
||||
@@ -2873,6 +2911,7 @@ namespace ts {
|
||||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
@@ -2894,7 +2933,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function getBinaryOperatorPrecedence(kind: SyntaxKind): number {
|
||||
switch (kind) {
|
||||
case SyntaxKind.BarBarToken:
|
||||
@@ -3011,7 +3049,7 @@ namespace ts {
|
||||
return fileDiagnostics.get(fileName) || [];
|
||||
}
|
||||
|
||||
const fileDiags: Diagnostic[] = flatMap(filesWithDiagnostics, f => fileDiagnostics.get(f));
|
||||
const fileDiags: Diagnostic[] = flatMapToMutable(filesWithDiagnostics, f => fileDiagnostics.get(f));
|
||||
if (!nonFileDiagnostics.length) {
|
||||
return fileDiags;
|
||||
}
|
||||
@@ -3072,7 +3110,7 @@ namespace ts {
|
||||
|
||||
export function isIntrinsicJsxName(name: __String | string) {
|
||||
const ch = (name as string).charCodeAt(0);
|
||||
return (ch >= CharacterCodes.a && ch <= CharacterCodes.z) || (name as string).indexOf("-") > -1;
|
||||
return (ch >= CharacterCodes.a && ch <= CharacterCodes.z) || stringContains((name as string), "-");
|
||||
}
|
||||
|
||||
function get16BitUnicodeEscapeSequence(charCode: number): string {
|
||||
@@ -3163,18 +3201,11 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function writeTextOfNode(text: string, node: Node) {
|
||||
const s = getTextOfNodeFromSourceText(text, node);
|
||||
write(s);
|
||||
updateLineCountAndPosFor(s);
|
||||
}
|
||||
|
||||
reset();
|
||||
|
||||
return {
|
||||
write,
|
||||
rawWrite,
|
||||
writeTextOfNode,
|
||||
writeLiteral,
|
||||
writeLine,
|
||||
increaseIndent: () => { indent++; },
|
||||
@@ -3197,7 +3228,79 @@ namespace ts {
|
||||
writePunctuation: write,
|
||||
writeSpace: write,
|
||||
writeStringLiteral: write,
|
||||
writeSymbol: write
|
||||
writeSymbol: (s, _) => write(s),
|
||||
writeTrailingSemicolon: write,
|
||||
writeComment: write
|
||||
};
|
||||
}
|
||||
|
||||
export function getTrailingSemicolonOmittingWriter(writer: EmitTextWriter): EmitTextWriter {
|
||||
let pendingTrailingSemicolon = false;
|
||||
|
||||
function commitPendingTrailingSemicolon() {
|
||||
if (pendingTrailingSemicolon) {
|
||||
writer.writeTrailingSemicolon(";");
|
||||
pendingTrailingSemicolon = false;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...writer,
|
||||
writeTrailingSemicolon() {
|
||||
pendingTrailingSemicolon = true;
|
||||
},
|
||||
writeLiteral(s) {
|
||||
commitPendingTrailingSemicolon();
|
||||
writer.writeLiteral(s);
|
||||
},
|
||||
writeStringLiteral(s) {
|
||||
commitPendingTrailingSemicolon();
|
||||
writer.writeStringLiteral(s);
|
||||
},
|
||||
writeSymbol(s, sym) {
|
||||
commitPendingTrailingSemicolon();
|
||||
writer.writeSymbol(s, sym);
|
||||
},
|
||||
writePunctuation(s) {
|
||||
commitPendingTrailingSemicolon();
|
||||
writer.writePunctuation(s);
|
||||
},
|
||||
writeKeyword(s) {
|
||||
commitPendingTrailingSemicolon();
|
||||
writer.writeKeyword(s);
|
||||
},
|
||||
writeOperator(s) {
|
||||
commitPendingTrailingSemicolon();
|
||||
writer.writeOperator(s);
|
||||
},
|
||||
writeParameter(s) {
|
||||
commitPendingTrailingSemicolon();
|
||||
writer.writeParameter(s);
|
||||
},
|
||||
writeSpace(s) {
|
||||
commitPendingTrailingSemicolon();
|
||||
writer.writeSpace(s);
|
||||
},
|
||||
writeProperty(s) {
|
||||
commitPendingTrailingSemicolon();
|
||||
writer.writeProperty(s);
|
||||
},
|
||||
writeComment(s) {
|
||||
commitPendingTrailingSemicolon();
|
||||
writer.writeComment(s);
|
||||
},
|
||||
writeLine() {
|
||||
commitPendingTrailingSemicolon();
|
||||
writer.writeLine();
|
||||
},
|
||||
increaseIndent() {
|
||||
commitPendingTrailingSemicolon();
|
||||
writer.increaseIndent();
|
||||
},
|
||||
decreaseIndent() {
|
||||
commitPendingTrailingSemicolon();
|
||||
writer.decreaseIndent();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3252,7 +3355,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export interface EmitFileNames {
|
||||
jsFilePath: string;
|
||||
jsFilePath: string | undefined;
|
||||
sourceMapFilePath: string | undefined;
|
||||
declarationFilePath: string | undefined;
|
||||
declarationMapPath: string | undefined;
|
||||
@@ -3273,7 +3376,7 @@ namespace ts {
|
||||
const isSourceFileFromExternalLibrary = (file: SourceFile) => host.isSourceFileFromExternalLibrary(file);
|
||||
if (options.outFile || options.out) {
|
||||
const moduleKind = getEmitModuleKind(options);
|
||||
const moduleEmitEnabled = moduleKind === ModuleKind.AMD || moduleKind === ModuleKind.System;
|
||||
const moduleEmitEnabled = options.emitDeclarationOnly || moduleKind === ModuleKind.AMD || moduleKind === ModuleKind.System;
|
||||
// Can emit only sources that are not declaration file and are either non module code or module with --module or --target es6 specified
|
||||
return filter(host.getSourceFiles(), sourceFile =>
|
||||
(moduleEmitEnabled || !isExternalModule(sourceFile)) && sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary));
|
||||
@@ -3477,13 +3580,13 @@ namespace ts {
|
||||
writeComment: (text: string, lineMap: ReadonlyArray<number>, writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) => void) {
|
||||
if (comments && comments.length > 0) {
|
||||
if (leadingSeparator) {
|
||||
writer.write(" ");
|
||||
writer.writeSpace(" ");
|
||||
}
|
||||
|
||||
let emitInterveningSeparator = false;
|
||||
for (const comment of comments) {
|
||||
if (emitInterveningSeparator) {
|
||||
writer.write(" ");
|
||||
writer.writeSpace(" ");
|
||||
emitInterveningSeparator = false;
|
||||
}
|
||||
|
||||
@@ -3497,7 +3600,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (emitInterveningSeparator && trailingSeparator) {
|
||||
writer.write(" ");
|
||||
writer.writeSpace(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3631,7 +3734,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
// Single line comment of style //....
|
||||
writer.write(text.substring(commentPos, commentEnd));
|
||||
writer.writeComment(text.substring(commentPos, commentEnd));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3640,14 +3743,14 @@ namespace ts {
|
||||
const currentLineText = text.substring(pos, end).replace(/^\s+|\s+$/g, "");
|
||||
if (currentLineText) {
|
||||
// trimmed forward and ending spaces text
|
||||
writer.write(currentLineText);
|
||||
writer.writeComment(currentLineText);
|
||||
if (end !== commentEnd) {
|
||||
writer.writeLine();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Empty string - make sure we write empty line
|
||||
writer.writeLiteral(newLine);
|
||||
writer.rawWrite(newLine);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3742,11 +3845,20 @@ namespace ts {
|
||||
|
||||
/** Get `C` given `N` if `N` is in the position `class C extends N` where `N` is an ExpressionWithTypeArguments. */
|
||||
export function tryGetClassExtendingExpressionWithTypeArguments(node: Node): ClassLikeDeclaration | undefined {
|
||||
if (isExpressionWithTypeArguments(node) &&
|
||||
node.parent.token === SyntaxKind.ExtendsKeyword &&
|
||||
isClassLike(node.parent.parent)) {
|
||||
return node.parent.parent;
|
||||
}
|
||||
const cls = tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node);
|
||||
return cls && !cls.isImplements ? cls.class : undefined;
|
||||
}
|
||||
|
||||
export interface ClassImplementingOrExtendingExpressionWithTypeArguments {
|
||||
readonly class: ClassLikeDeclaration;
|
||||
readonly isImplements: boolean;
|
||||
}
|
||||
export function tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node: Node): ClassImplementingOrExtendingExpressionWithTypeArguments | undefined {
|
||||
return isExpressionWithTypeArguments(node)
|
||||
&& isHeritageClause(node.parent)
|
||||
&& isClassLike(node.parent.parent)
|
||||
? { class: node.parent.parent, isImplements: node.parent.token === SyntaxKind.ImplementsKeyword }
|
||||
: undefined;
|
||||
}
|
||||
|
||||
export function isAssignmentExpression(node: Node, excludeCompoundAssignment: true): node is AssignmentExpression<EqualsToken>;
|
||||
@@ -3773,15 +3885,6 @@ namespace ts {
|
||||
return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined;
|
||||
}
|
||||
|
||||
export function isExpressionWithTypeArgumentsInClassImplementsClause(node: Node): node is ExpressionWithTypeArguments {
|
||||
return node.kind === SyntaxKind.ExpressionWithTypeArguments
|
||||
&& isEntityNameExpression((node as ExpressionWithTypeArguments).expression)
|
||||
&& node.parent
|
||||
&& (<HeritageClause>node.parent).token === SyntaxKind.ImplementsKeyword
|
||||
&& node.parent.parent
|
||||
&& isClassLike(node.parent.parent);
|
||||
}
|
||||
|
||||
export function isEntityNameExpression(node: Node): node is EntityNameExpression {
|
||||
return node.kind === SyntaxKind.Identifier || isPropertyAccessEntityNameExpression(node);
|
||||
}
|
||||
@@ -3818,8 +3921,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** Return ".ts", ".d.ts", or ".tsx", if that is the extension. */
|
||||
export function tryExtractTypeScriptExtension(fileName: string): string | undefined {
|
||||
return find(supportedTypescriptExtensionsForExtractExtension, extension => fileExtensionIs(fileName, extension));
|
||||
export function tryExtractTSExtension(fileName: string): string | undefined {
|
||||
return find(supportedTSExtensionsForExtractExtension, extension => fileExtensionIs(fileName, extension));
|
||||
}
|
||||
/**
|
||||
* Replace each instance of non-ascii characters by one, two, three, or four escape sequences
|
||||
@@ -4329,7 +4432,7 @@ namespace ts {
|
||||
/**
|
||||
* clears already present map by calling onDeleteExistingValue callback before deleting that key/value
|
||||
*/
|
||||
export function clearMap<T>(map: Map<T>, onDeleteValue: (valueInMap: T, key: string) => void) {
|
||||
export function clearMap<T>(map: { forEach: Map<T>["forEach"]; clear: Map<T>["clear"]; }, onDeleteValue: (valueInMap: T, key: string) => void) {
|
||||
// Remove all
|
||||
map.forEach(onDeleteValue);
|
||||
map.clear();
|
||||
@@ -4463,6 +4566,31 @@ namespace ts {
|
||||
export function isObjectTypeDeclaration(node: Node): node is ObjectTypeDeclaration {
|
||||
return isClassLike(node) || isInterfaceDeclaration(node) || isTypeLiteralNode(node);
|
||||
}
|
||||
|
||||
export function isTypeNodeKind(kind: SyntaxKind) {
|
||||
return (kind >= SyntaxKind.FirstTypeNode && kind <= SyntaxKind.LastTypeNode)
|
||||
|| kind === SyntaxKind.AnyKeyword
|
||||
|| kind === SyntaxKind.UnknownKeyword
|
||||
|| kind === SyntaxKind.NumberKeyword
|
||||
|| kind === SyntaxKind.BigIntKeyword
|
||||
|| kind === SyntaxKind.ObjectKeyword
|
||||
|| kind === SyntaxKind.BooleanKeyword
|
||||
|| kind === SyntaxKind.StringKeyword
|
||||
|| kind === SyntaxKind.SymbolKeyword
|
||||
|| kind === SyntaxKind.ThisKeyword
|
||||
|| kind === SyntaxKind.VoidKeyword
|
||||
|| kind === SyntaxKind.UndefinedKeyword
|
||||
|| kind === SyntaxKind.NullKeyword
|
||||
|| kind === SyntaxKind.NeverKeyword
|
||||
|| kind === SyntaxKind.ExpressionWithTypeArguments
|
||||
|| kind === SyntaxKind.JSDocAllType
|
||||
|| kind === SyntaxKind.JSDocUnknownType
|
||||
|| kind === SyntaxKind.JSDocNullableType
|
||||
|| kind === SyntaxKind.JSDocNonNullableType
|
||||
|| kind === SyntaxKind.JSDocOptionalType
|
||||
|| kind === SyntaxKind.JSDocFunctionType
|
||||
|| kind === SyntaxKind.JSDocVariadicType;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ts {
|
||||
@@ -4984,14 +5112,19 @@ namespace ts {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.BinaryExpression: {
|
||||
const expr = declaration as BinaryExpression;
|
||||
const expr = declaration as BinaryExpression | CallExpression;
|
||||
switch (getAssignmentDeclarationKind(expr)) {
|
||||
case AssignmentDeclarationKind.ExportsProperty:
|
||||
case AssignmentDeclarationKind.ThisProperty:
|
||||
case AssignmentDeclarationKind.Property:
|
||||
case AssignmentDeclarationKind.PrototypeProperty:
|
||||
return (expr.left as PropertyAccessExpression).name;
|
||||
return ((expr as BinaryExpression).left as PropertyAccessExpression).name;
|
||||
case AssignmentDeclarationKind.ObjectDefinePropertyValue:
|
||||
case AssignmentDeclarationKind.ObjectDefinePropertyExports:
|
||||
case AssignmentDeclarationKind.ObjectDefinePrototypeProperty:
|
||||
return (expr as BindableObjectDefinePropertyCall).arguments[1];
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
@@ -5202,7 +5335,7 @@ namespace ts {
|
||||
}
|
||||
if (isJSDocTypeAlias(node)) {
|
||||
Debug.assert(node.parent.kind === SyntaxKind.JSDocComment);
|
||||
return flatMap(node.parent.tags, tag => isJSDocTemplateTag(tag) ? tag.typeParameters : undefined) as ReadonlyArray<TypeParameterDeclaration>;
|
||||
return flatMap(node.parent.tags, tag => isJSDocTemplateTag(tag) ? tag.typeParameters : undefined);
|
||||
}
|
||||
if (node.typeParameters) {
|
||||
return node.typeParameters;
|
||||
@@ -5235,6 +5368,10 @@ namespace ts {
|
||||
return node.kind === SyntaxKind.NumericLiteral;
|
||||
}
|
||||
|
||||
export function isBigIntLiteral(node: Node): node is BigIntLiteral {
|
||||
return node.kind === SyntaxKind.BigIntLiteral;
|
||||
}
|
||||
|
||||
export function isStringLiteral(node: Node): node is StringLiteral {
|
||||
return node.kind === SyntaxKind.StringLiteral;
|
||||
}
|
||||
@@ -5999,6 +6136,10 @@ namespace ts {
|
||||
|| kind === SyntaxKind.TemplateTail;
|
||||
}
|
||||
|
||||
export function isImportOrExportSpecifier(node: Node): node is ImportSpecifier | ExportSpecifier {
|
||||
return isImportSpecifier(node) || isExportSpecifier(node);
|
||||
}
|
||||
|
||||
export function isStringTextContainingNode(node: Node): node is StringLiteral | TemplateLiteralToken {
|
||||
return node.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(node.kind);
|
||||
}
|
||||
@@ -6173,30 +6314,6 @@ namespace ts {
|
||||
|
||||
// Type
|
||||
|
||||
function isTypeNodeKind(kind: SyntaxKind) {
|
||||
return (kind >= SyntaxKind.FirstTypeNode && kind <= SyntaxKind.LastTypeNode)
|
||||
|| kind === SyntaxKind.AnyKeyword
|
||||
|| kind === SyntaxKind.UnknownKeyword
|
||||
|| kind === SyntaxKind.NumberKeyword
|
||||
|| kind === SyntaxKind.ObjectKeyword
|
||||
|| kind === SyntaxKind.BooleanKeyword
|
||||
|| kind === SyntaxKind.StringKeyword
|
||||
|| kind === SyntaxKind.SymbolKeyword
|
||||
|| kind === SyntaxKind.ThisKeyword
|
||||
|| kind === SyntaxKind.VoidKeyword
|
||||
|| kind === SyntaxKind.UndefinedKeyword
|
||||
|| kind === SyntaxKind.NullKeyword
|
||||
|| kind === SyntaxKind.NeverKeyword
|
||||
|| kind === SyntaxKind.ExpressionWithTypeArguments
|
||||
|| kind === SyntaxKind.JSDocAllType
|
||||
|| kind === SyntaxKind.JSDocUnknownType
|
||||
|| kind === SyntaxKind.JSDocNullableType
|
||||
|| kind === SyntaxKind.JSDocNonNullableType
|
||||
|| kind === SyntaxKind.JSDocOptionalType
|
||||
|| kind === SyntaxKind.JSDocFunctionType
|
||||
|| kind === SyntaxKind.JSDocVariadicType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Node test that determines whether a node is a valid type node.
|
||||
* This differs from the `isPartOfTypeNode` function which determines whether a node is *part*
|
||||
@@ -6360,6 +6477,7 @@ namespace ts {
|
||||
case SyntaxKind.Identifier:
|
||||
case SyntaxKind.RegularExpressionLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
case SyntaxKind.TemplateExpression:
|
||||
@@ -6723,7 +6841,7 @@ namespace ts {
|
||||
|
||||
// TODO: determine what this does before making it public.
|
||||
/* @internal */
|
||||
export function isJSDocTag(node: Node): boolean {
|
||||
export function isJSDocTag(node: Node): node is JSDocTag {
|
||||
return node.kind >= SyntaxKind.FirstJSDocTagNode && node.kind <= SyntaxKind.LastJSDocTagNode;
|
||||
}
|
||||
|
||||
@@ -6802,7 +6920,6 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
/** @internal */
|
||||
export function isNamedImportsOrExports(node: Node): node is NamedImportsOrExports {
|
||||
return node.kind === SyntaxKind.NamedImports || node.kind === SyntaxKind.NamedExports;
|
||||
}
|
||||
@@ -6866,9 +6983,8 @@ namespace ts {
|
||||
getSourceMapSourceConstructor: () => <any>SourceMapSource,
|
||||
};
|
||||
|
||||
/* @internal */
|
||||
export function formatStringFromArgs(text: string, args: ArrayLike<string>, baseIndex = 0): string {
|
||||
return text.replace(/{(\d+)}/g, (_match, index: string) => Debug.assertDefined(args[+index + baseIndex]));
|
||||
export function formatStringFromArgs(text: string, args: ArrayLike<string | number>, baseIndex = 0): string {
|
||||
return text.replace(/{(\d+)}/g, (_match, index: string) => "" + Debug.assertDefined(args[+index + baseIndex]));
|
||||
}
|
||||
|
||||
export let localizedDiagnosticMessages: MapLike<string> | undefined;
|
||||
@@ -6877,7 +6993,6 @@ namespace ts {
|
||||
return localizedDiagnosticMessages && localizedDiagnosticMessages[message.key] || message.message;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithLocation;
|
||||
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage): DiagnosticWithLocation {
|
||||
Debug.assertGreaterThanOrEqual(start, 0);
|
||||
@@ -6906,7 +7021,6 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function formatMessage(_dummy: any, message: DiagnosticMessage): string {
|
||||
let text = getLocaleSpecificMessage(message);
|
||||
|
||||
@@ -6917,7 +7031,6 @@ namespace ts {
|
||||
return text;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: (string | number | undefined)[]): Diagnostic;
|
||||
export function createCompilerDiagnostic(message: DiagnosticMessage): Diagnostic {
|
||||
let text = getLocaleSpecificMessage(message);
|
||||
@@ -6938,7 +7051,6 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createCompilerDiagnosticFromMessageChain(chain: DiagnosticMessageChain): Diagnostic {
|
||||
return {
|
||||
file: undefined,
|
||||
@@ -6951,8 +7063,7 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain | undefined, message: DiagnosticMessage, ...args: (string | undefined)[]): DiagnosticMessageChain;
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticMessageChain;
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain | undefined, message: DiagnosticMessage): DiagnosticMessageChain {
|
||||
let text = getLocaleSpecificMessage(message);
|
||||
|
||||
@@ -6983,14 +7094,12 @@ namespace ts {
|
||||
return diagnostic.file ? diagnostic.file.path : undefined;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function compareDiagnostics(d1: Diagnostic, d2: Diagnostic): Comparison {
|
||||
return compareDiagnosticsSkipRelatedInformation(d1, d2) ||
|
||||
compareRelatedInformation(d1, d2) ||
|
||||
Comparison.EqualTo;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function compareDiagnosticsSkipRelatedInformation(d1: Diagnostic, d2: Diagnostic): Comparison {
|
||||
return compareStringsCaseSensitive(getDiagnosticFilePath(d1), getDiagnosticFilePath(d2)) ||
|
||||
compareValues(d1.start, d2.start) ||
|
||||
@@ -7085,28 +7194,27 @@ namespace ts {
|
||||
const moduleKind = getEmitModuleKind(compilerOptions);
|
||||
return compilerOptions.allowSyntheticDefaultImports !== undefined
|
||||
? compilerOptions.allowSyntheticDefaultImports
|
||||
: compilerOptions.esModuleInterop
|
||||
? moduleKind !== ModuleKind.None && moduleKind < ModuleKind.ES2015
|
||||
: moduleKind === ModuleKind.System;
|
||||
: compilerOptions.esModuleInterop ||
|
||||
moduleKind === ModuleKind.System;
|
||||
}
|
||||
|
||||
export function getEmitDeclarations(compilerOptions: CompilerOptions): boolean {
|
||||
return !!(compilerOptions.declaration || compilerOptions.composite);
|
||||
}
|
||||
|
||||
export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "strictPropertyInitialization" | "alwaysStrict";
|
||||
export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "strictBindCallApply" | "strictPropertyInitialization" | "alwaysStrict";
|
||||
|
||||
export function getStrictOptionValue(compilerOptions: CompilerOptions, flag: StrictOptionName): boolean {
|
||||
return compilerOptions[flag] === undefined ? !!compilerOptions.strict : !!compilerOptions[flag];
|
||||
}
|
||||
|
||||
export function compilerOptionsAffectSemanticDiagnostics(newOptions: CompilerOptions, oldOptions: CompilerOptions) {
|
||||
if (oldOptions === newOptions) {
|
||||
return false;
|
||||
}
|
||||
export function compilerOptionsAffectSemanticDiagnostics(newOptions: CompilerOptions, oldOptions: CompilerOptions): boolean {
|
||||
return oldOptions !== newOptions &&
|
||||
semanticDiagnosticsOptionDeclarations.some(option => !isJsonEqual(getCompilerOptionValue(oldOptions, option), getCompilerOptionValue(newOptions, option)));
|
||||
}
|
||||
|
||||
return optionDeclarations.some(option => (!!option.strictFlag && getStrictOptionValue(newOptions, option.name as StrictOptionName) !== getStrictOptionValue(oldOptions, option.name as StrictOptionName)) ||
|
||||
(!!option.affectsSemanticDiagnostics && !newOptions[option.name] !== !oldOptions[option.name]));
|
||||
export function getCompilerOptionValue(options: CompilerOptions, option: CommandLineOption): unknown {
|
||||
return option.strictFlag ? getStrictOptionValue(options, option.name as StrictOptionName) : options[option.name];
|
||||
}
|
||||
|
||||
export function hasZeroOrOneAsteriskCharacter(str: string): boolean {
|
||||
@@ -7329,7 +7437,6 @@ namespace ts {
|
||||
return rootLength > 0 && rootLength === path.length;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function convertToRelativePath(absoluteOrRelativePath: string, basePath: string, getCanonicalFileName: (path: string) => string): string {
|
||||
return !isRootedDiskPath(absoluteOrRelativePath)
|
||||
? absoluteOrRelativePath
|
||||
@@ -7746,7 +7853,7 @@ namespace ts {
|
||||
return `^(${pattern})${terminator}`;
|
||||
}
|
||||
|
||||
function getRegularExpressionsForWildcards(specs: ReadonlyArray<string> | undefined, basePath: string, usage: "files" | "directories" | "exclude"): string[] | undefined {
|
||||
export function getRegularExpressionsForWildcards(specs: ReadonlyArray<string> | undefined, basePath: string, usage: "files" | "directories" | "exclude"): ReadonlyArray<string> | undefined {
|
||||
if (specs === undefined || specs.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -8010,48 +8117,60 @@ namespace ts {
|
||||
/**
|
||||
* List of supported extensions in order of file resolution precedence.
|
||||
*/
|
||||
export const supportedTypescriptExtensions: ReadonlyArray<Extension> = [Extension.Ts, Extension.Tsx, Extension.Dts];
|
||||
export const supportedTSExtensions: ReadonlyArray<Extension> = [Extension.Ts, Extension.Tsx, Extension.Dts];
|
||||
export const supportedTSExtensionsWithJson: ReadonlyArray<Extension> = [Extension.Ts, Extension.Tsx, Extension.Dts, Extension.Json];
|
||||
/** Must have ".d.ts" first because if ".ts" goes first, that will be detected as the extension instead of ".d.ts". */
|
||||
export const supportedTypescriptExtensionsForExtractExtension: ReadonlyArray<Extension> = [Extension.Dts, Extension.Ts, Extension.Tsx];
|
||||
export const supportedJavascriptExtensions: ReadonlyArray<Extension> = [Extension.Js, Extension.Jsx];
|
||||
export const supportedJavascriptAndJsonExtensions: ReadonlyArray<Extension> = [Extension.Js, Extension.Jsx, Extension.Json];
|
||||
const allSupportedExtensions: ReadonlyArray<Extension> = [...supportedTypescriptExtensions, ...supportedJavascriptExtensions];
|
||||
export const supportedTSExtensionsForExtractExtension: ReadonlyArray<Extension> = [Extension.Dts, Extension.Ts, Extension.Tsx];
|
||||
export const supportedJSExtensions: ReadonlyArray<Extension> = [Extension.Js, Extension.Jsx];
|
||||
export const supportedJSAndJsonExtensions: ReadonlyArray<Extension> = [Extension.Js, Extension.Jsx, Extension.Json];
|
||||
const allSupportedExtensions: ReadonlyArray<Extension> = [...supportedTSExtensions, ...supportedJSExtensions];
|
||||
const allSupportedExtensionsWithJson: ReadonlyArray<Extension> = [...supportedTSExtensions, ...supportedJSExtensions, Extension.Json];
|
||||
|
||||
export function getSupportedExtensions(options?: CompilerOptions): ReadonlyArray<Extension>;
|
||||
export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: ReadonlyArray<FileExtensionInfo>): ReadonlyArray<string>;
|
||||
export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: ReadonlyArray<FileExtensionInfo>): ReadonlyArray<string> {
|
||||
const needJsExtensions = options && options.allowJs;
|
||||
|
||||
if (!extraFileExtensions || extraFileExtensions.length === 0) {
|
||||
return needJsExtensions ? allSupportedExtensions : supportedTypescriptExtensions;
|
||||
return needJsExtensions ? allSupportedExtensions : supportedTSExtensions;
|
||||
}
|
||||
|
||||
const extensions = [
|
||||
...needJsExtensions ? allSupportedExtensions : supportedTypescriptExtensions,
|
||||
...mapDefined(extraFileExtensions, x => x.scriptKind === ScriptKind.Deferred || needJsExtensions && isJavascriptLike(x.scriptKind) ? x.extension : undefined)
|
||||
...needJsExtensions ? allSupportedExtensions : supportedTSExtensions,
|
||||
...mapDefined(extraFileExtensions, x => x.scriptKind === ScriptKind.Deferred || needJsExtensions && isJSLike(x.scriptKind) ? x.extension : undefined)
|
||||
];
|
||||
|
||||
return deduplicate<string>(extensions, equateStringsCaseSensitive, compareStringsCaseSensitive);
|
||||
}
|
||||
|
||||
function isJavascriptLike(scriptKind: ScriptKind | undefined): boolean {
|
||||
export function getSuppoertedExtensionsWithJsonIfResolveJsonModule(options: CompilerOptions | undefined, supportedExtensions: ReadonlyArray<string>): ReadonlyArray<string> {
|
||||
if (!options || !options.resolveJsonModule) { return supportedExtensions; }
|
||||
if (supportedExtensions === allSupportedExtensions) { return allSupportedExtensionsWithJson; }
|
||||
if (supportedExtensions === supportedTSExtensions) { return supportedTSExtensionsWithJson; }
|
||||
return [...supportedExtensions, Extension.Json];
|
||||
}
|
||||
|
||||
function isJSLike(scriptKind: ScriptKind | undefined): boolean {
|
||||
return scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSX;
|
||||
}
|
||||
|
||||
export function hasJavascriptFileExtension(fileName: string): boolean {
|
||||
return some(supportedJavascriptExtensions, extension => fileExtensionIs(fileName, extension));
|
||||
export function hasJSFileExtension(fileName: string): boolean {
|
||||
return some(supportedJSExtensions, extension => fileExtensionIs(fileName, extension));
|
||||
}
|
||||
|
||||
export function hasJavascriptOrJsonFileExtension(fileName: string): boolean {
|
||||
return supportedJavascriptAndJsonExtensions.some(ext => fileExtensionIs(fileName, ext));
|
||||
export function hasJSOrJsonFileExtension(fileName: string): boolean {
|
||||
return supportedJSAndJsonExtensions.some(ext => fileExtensionIs(fileName, ext));
|
||||
}
|
||||
|
||||
export function hasTypescriptFileExtension(fileName: string): boolean {
|
||||
return some(supportedTypescriptExtensions, extension => fileExtensionIs(fileName, extension));
|
||||
export function hasTSFileExtension(fileName: string): boolean {
|
||||
return some(supportedTSExtensions, extension => fileExtensionIs(fileName, extension));
|
||||
}
|
||||
|
||||
export function isSupportedSourceFileName(fileName: string, compilerOptions?: CompilerOptions, extraFileExtensions?: ReadonlyArray<FileExtensionInfo>) {
|
||||
if (!fileName) { return false; }
|
||||
|
||||
for (const extension of getSupportedExtensions(compilerOptions, extraFileExtensions)) {
|
||||
const supportedExtensions = getSupportedExtensions(compilerOptions, extraFileExtensions);
|
||||
for (const extension of getSuppoertedExtensionsWithJsonIfResolveJsonModule(compilerOptions, supportedExtensions)) {
|
||||
if (fileExtensionIs(fileName, extension)) {
|
||||
return true;
|
||||
}
|
||||
@@ -8181,12 +8300,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** True if an extension is one of the supported TypeScript extensions. */
|
||||
export function extensionIsTypeScript(ext: Extension): boolean {
|
||||
export function extensionIsTS(ext: Extension): boolean {
|
||||
return ext === Extension.Ts || ext === Extension.Tsx || ext === Extension.Dts;
|
||||
}
|
||||
|
||||
export function resolutionExtensionIsTypeScriptOrJson(ext: Extension) {
|
||||
return extensionIsTypeScript(ext) || ext === Extension.Json;
|
||||
export function resolutionExtensionIsTSOrJson(ext: Extension) {
|
||||
return extensionIsTS(ext) || ext === Extension.Json;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -8374,4 +8493,95 @@ namespace ts {
|
||||
// '/// <reference no-default-lib="true"/>' directive.
|
||||
return options.skipLibCheck && sourceFile.isDeclarationFile || options.skipDefaultLibCheck && sourceFile.hasNoDefaultLib;
|
||||
}
|
||||
|
||||
export function isJsonEqual(a: unknown, b: unknown): boolean {
|
||||
return a === b || typeof a === "object" && a !== null && typeof b === "object" && b !== null && equalOwnProperties(a as MapLike<unknown>, b as MapLike<unknown>, isJsonEqual);
|
||||
}
|
||||
|
||||
export function getOrUpdate<T>(map: Map<T>, key: string, getDefault: () => T): T {
|
||||
const got = map.get(key);
|
||||
if (got === undefined) {
|
||||
const value = getDefault();
|
||||
map.set(key, value);
|
||||
return value;
|
||||
}
|
||||
else {
|
||||
return got;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a bigint literal string, e.g. `0x1234n`,
|
||||
* to its decimal string representation, e.g. `4660`.
|
||||
*/
|
||||
export function parsePseudoBigInt(stringValue: string): string {
|
||||
let log2Base: number;
|
||||
switch (stringValue.charCodeAt(1)) { // "x" in "0x123"
|
||||
case CharacterCodes.b:
|
||||
case CharacterCodes.B: // 0b or 0B
|
||||
log2Base = 1;
|
||||
break;
|
||||
case CharacterCodes.o:
|
||||
case CharacterCodes.O: // 0o or 0O
|
||||
log2Base = 3;
|
||||
break;
|
||||
case CharacterCodes.x:
|
||||
case CharacterCodes.X: // 0x or 0X
|
||||
log2Base = 4;
|
||||
break;
|
||||
default: // already in decimal; omit trailing "n"
|
||||
const nIndex = stringValue.length - 1;
|
||||
// Skip leading 0s
|
||||
let nonZeroStart = 0;
|
||||
while (stringValue.charCodeAt(nonZeroStart) === CharacterCodes._0) {
|
||||
nonZeroStart++;
|
||||
}
|
||||
return stringValue.slice(nonZeroStart, nIndex) || "0";
|
||||
}
|
||||
|
||||
// Omit leading "0b", "0o", or "0x", and trailing "n"
|
||||
const startIndex = 2, endIndex = stringValue.length - 1;
|
||||
const bitsNeeded = (endIndex - startIndex) * log2Base;
|
||||
// Stores the value specified by the string as a LE array of 16-bit integers
|
||||
// using Uint16 instead of Uint32 so combining steps can use bitwise operators
|
||||
const segments = new Uint16Array((bitsNeeded >>> 4) + (bitsNeeded & 15 ? 1 : 0));
|
||||
// Add the digits, one at a time
|
||||
for (let i = endIndex - 1, bitOffset = 0; i >= startIndex; i--, bitOffset += log2Base) {
|
||||
const segment = bitOffset >>> 4;
|
||||
const digitChar = stringValue.charCodeAt(i);
|
||||
// Find character range: 0-9 < A-F < a-f
|
||||
const digit = digitChar <= CharacterCodes._9
|
||||
? digitChar - CharacterCodes._0
|
||||
: 10 + digitChar -
|
||||
(digitChar <= CharacterCodes.F ? CharacterCodes.A : CharacterCodes.a);
|
||||
const shiftedDigit = digit << (bitOffset & 15);
|
||||
segments[segment] |= shiftedDigit;
|
||||
const residual = shiftedDigit >>> 16;
|
||||
if (residual) segments[segment + 1] |= residual; // overflows segment
|
||||
}
|
||||
// Repeatedly divide segments by 10 and add remainder to base10Value
|
||||
let base10Value = "";
|
||||
let firstNonzeroSegment = segments.length - 1;
|
||||
let segmentsRemaining = true;
|
||||
while (segmentsRemaining) {
|
||||
let mod10 = 0;
|
||||
segmentsRemaining = false;
|
||||
for (let segment = firstNonzeroSegment; segment >= 0; segment--) {
|
||||
const newSegment = mod10 << 16 | segments[segment];
|
||||
const segmentValue = (newSegment / 10) | 0;
|
||||
segments[segment] = segmentValue;
|
||||
mod10 = newSegment - segmentValue * 10;
|
||||
if (segmentValue && !segmentsRemaining) {
|
||||
firstNonzeroSegment = segment;
|
||||
segmentsRemaining = true;
|
||||
}
|
||||
}
|
||||
base10Value = mod10 + base10Value;
|
||||
}
|
||||
return base10Value;
|
||||
}
|
||||
|
||||
export function pseudoBigIntToString({negative, base10Value}: PseudoBigInt): string {
|
||||
return (negative && base10Value !== "0" ? "-" : "") + base10Value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
+68
-44
@@ -43,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,
|
||||
@@ -101,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;
|
||||
@@ -128,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) {
|
||||
@@ -151,7 +166,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (reportSummary) {
|
||||
reportSummary(diagnostics.filter(diagnostic => diagnostic.category === DiagnosticCategory.Error).length);
|
||||
reportSummary(getErrorCountForSummary(diagnostics));
|
||||
}
|
||||
|
||||
if (emitSkipped && diagnostics.length > 0) {
|
||||
@@ -227,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
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,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;
|
||||
}
|
||||
}
|
||||
@@ -274,7 +290,7 @@ 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 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 */
|
||||
@@ -337,9 +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[];
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): (ResolvedTypeReferenceDirective | undefined)[];
|
||||
}
|
||||
|
||||
/** Internal interface used to wire emit through same host */
|
||||
@@ -360,6 +376,9 @@ namespace ts {
|
||||
|
||||
/** Compiler options */
|
||||
options: CompilerOptions;
|
||||
|
||||
/** Project References */
|
||||
projectReferences?: ReadonlyArray<ProjectReference>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -413,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);
|
||||
@@ -463,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);
|
||||
@@ -479,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
|
||||
@@ -542,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 ?
|
||||
@@ -552,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();
|
||||
@@ -589,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;
|
||||
}
|
||||
}
|
||||
@@ -620,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
|
||||
@@ -758,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
|
||||
@@ -773,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -824,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;
|
||||
@@ -861,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;
|
||||
}
|
||||
|
||||
@@ -872,6 +893,7 @@ namespace ts {
|
||||
if (eventKind === FileWatcherEventKind.Deleted && sourceFilesCache.get(path)) {
|
||||
resolutionCache.invalidateResolutionOfFile(path);
|
||||
}
|
||||
resolutionCache.removeResolutionsFromProjectReferenceRedirects(path);
|
||||
nextSourceFileVersion(path);
|
||||
|
||||
// Update the program
|
||||
@@ -931,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)) {
|
||||
|
||||
+39
-25
@@ -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 */
|
||||
@@ -390,34 +393,41 @@ 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,
|
||||
fileToRename: body.info.fileToRename,
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -684,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;
|
||||
|
||||
+667
-513
File diff suppressed because it is too large
Load Diff
@@ -490,7 +490,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 +1159,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 +1325,9 @@ namespace Harness {
|
||||
const [, content] = value;
|
||||
outputLines += content;
|
||||
}
|
||||
if (pretty) {
|
||||
outputLines += ts.getErrorSummaryText(ts.getErrorCountForSummary(diagnostics), IO.newLine());
|
||||
}
|
||||
return outputLines;
|
||||
}
|
||||
|
||||
@@ -1643,6 +1646,7 @@ namespace Harness {
|
||||
else {
|
||||
sourceMapCode = "";
|
||||
result.maps.forEach(sourceMap => {
|
||||
if (sourceMapCode) sourceMapCode += "\r\n";
|
||||
sourceMapCode += fileOutput(sourceMap, harnessSettings);
|
||||
});
|
||||
}
|
||||
@@ -1668,6 +1672,9 @@ namespace Harness {
|
||||
|
||||
let jsCode = "";
|
||||
result.js.forEach(file => {
|
||||
if (jsCode.length && jsCode.charCodeAt(jsCode.length - 1) !== ts.CharacterCodes.lineFeed) {
|
||||
jsCode += "\r\n";
|
||||
}
|
||||
jsCode += fileOutput(file, harnessSettings);
|
||||
});
|
||||
|
||||
|
||||
@@ -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,7 +282,7 @@ 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
|
||||
@@ -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(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 {
|
||||
|
||||
@@ -4,6 +4,8 @@ namespace ts.TestFSWithWatch {
|
||||
content: `/// <reference no-default-lib="true"/>
|
||||
interface Boolean {}
|
||||
interface Function {}
|
||||
interface CallableFunction {}
|
||||
interface NewableFunction {}
|
||||
interface IArguments {}
|
||||
interface Number { toExponential: any; }
|
||||
interface Object {}
|
||||
@@ -126,7 +128,7 @@ interface Array<T> {}`
|
||||
return s && isString((<FsSymLink>s).symLink);
|
||||
}
|
||||
|
||||
function invokeWatcherCallbacks<T>(callbacks: T[], invokeCallback: (cb: T) => void): void {
|
||||
function invokeWatcherCallbacks<T>(callbacks: ReadonlyArray<T> | undefined, invokeCallback: (cb: T) => void): void {
|
||||
if (callbacks) {
|
||||
// The array copy is made to ensure that even if one of the callback removes the callbacks,
|
||||
// we dont miss any callbacks following it
|
||||
@@ -187,9 +189,10 @@ interface Array<T> {}`
|
||||
}
|
||||
|
||||
export function checkArray(caption: string, actual: ReadonlyArray<string>, expected: ReadonlyArray<string>) {
|
||||
checkMapKeys(caption, arrayToMap(actual, identity), expected);
|
||||
assert.equal(actual.length, expected.length, `${caption}: incorrect actual number of files, expected:\r\n${expected.join("\r\n")}\r\ngot: ${actual.join("\r\n")}`);
|
||||
for (const f of expected) {
|
||||
assert.equal(true, contains(actual, f), `${caption}: expected to find ${f} in ${actual}`);
|
||||
assert.isTrue(contains(actual, f), `${caption}: expected to find ${f} in ${actual}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,6 +341,7 @@ interface Array<T> {}`
|
||||
private readonly currentDirectory: string;
|
||||
private readonly dynamicPriorityWatchFile: HostWatchFile | undefined;
|
||||
private readonly customRecursiveWatchDirectory: HostWatchDirectory | undefined;
|
||||
public require: (initialPath: string, moduleName: string) => server.RequireResult;
|
||||
|
||||
constructor(public withSafeList: boolean, public useCaseSensitiveFileNames: boolean, executingFilePath: string, currentDirectory: string, fileOrFolderorSymLinkList: ReadonlyArray<FileOrFolderOrSymLink>, public readonly newLine = "\n", public readonly useWindowsStylePath?: boolean, private readonly environmentVariables?: Map<string>) {
|
||||
this.getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
@@ -584,8 +588,8 @@ interface Array<T> {}`
|
||||
}
|
||||
this.invokeFileWatcher(fileOrDirectory.fullPath, FileWatcherEventKind.Created);
|
||||
if (isFsFolder(fileOrDirectory)) {
|
||||
this.invokeDirectoryWatcher(fileOrDirectory.fullPath, "");
|
||||
this.invokeWatchedDirectoriesRecursiveCallback(fileOrDirectory.fullPath, "");
|
||||
this.invokeDirectoryWatcher(fileOrDirectory.fullPath, fileOrDirectory.fullPath);
|
||||
this.invokeWatchedDirectoriesRecursiveCallback(fileOrDirectory.fullPath, fileOrDirectory.fullPath);
|
||||
}
|
||||
this.invokeDirectoryWatcher(folder.fullPath, fileOrDirectory.fullPath);
|
||||
}
|
||||
@@ -647,15 +651,15 @@ interface Array<T> {}`
|
||||
|
||||
// For overriding the methods
|
||||
invokeWatchedDirectoriesCallback(folderFullPath: string, relativePath: string) {
|
||||
invokeWatcherCallbacks(this.watchedDirectories.get(this.toPath(folderFullPath))!, cb => this.directoryCallback(cb, relativePath));
|
||||
invokeWatcherCallbacks(this.watchedDirectories.get(this.toPath(folderFullPath)), cb => this.directoryCallback(cb, relativePath));
|
||||
}
|
||||
|
||||
invokeWatchedDirectoriesRecursiveCallback(folderFullPath: string, relativePath: string) {
|
||||
invokeWatcherCallbacks(this.watchedDirectoriesRecursive.get(this.toPath(folderFullPath))!, cb => this.directoryCallback(cb, relativePath));
|
||||
invokeWatcherCallbacks(this.watchedDirectoriesRecursive.get(this.toPath(folderFullPath)), cb => this.directoryCallback(cb, relativePath));
|
||||
}
|
||||
|
||||
invokeFileWatcher(fileFullPath: string, eventKind: FileWatcherEventKind, useFileNameInCallback?: boolean) {
|
||||
invokeWatcherCallbacks(this.watchedFiles.get(this.toPath(fileFullPath))!, ({ cb, fileName }) => cb(useFileNameInCallback ? fileName : fileFullPath, eventKind));
|
||||
private invokeFileWatcher(fileFullPath: string, eventKind: FileWatcherEventKind, useFileNameInCallback?: boolean) {
|
||||
invokeWatcherCallbacks(this.watchedFiles.get(this.toPath(fileFullPath)), ({ cb, fileName }) => cb(useFileNameInCallback ? fileName : fileFullPath, eventKind));
|
||||
}
|
||||
|
||||
private getRelativePathToDirectory(directoryFullPath: string, fileFullPath: string) {
|
||||
@@ -934,7 +938,12 @@ interface Array<T> {}`
|
||||
const folder = this.fs.get(base) as FsFolder;
|
||||
Debug.assert(isFsFolder(folder));
|
||||
|
||||
this.addFileOrFolderInFolder(folder, file);
|
||||
if (!this.fs.has(file.path)) {
|
||||
this.addFileOrFolderInFolder(folder, file);
|
||||
}
|
||||
else {
|
||||
this.modifyFile(path, content);
|
||||
}
|
||||
}
|
||||
|
||||
write(message: string) {
|
||||
@@ -980,4 +989,16 @@ interface Array<T> {}`
|
||||
return this.environmentVariables && this.environmentVariables.get(name) || "";
|
||||
}
|
||||
}
|
||||
|
||||
export const tsbuildProjectsLocation = "/user/username/projects";
|
||||
export function getTsBuildProjectFilePath(project: string, file: string) {
|
||||
return `${tsbuildProjectsLocation}/${project}/${file}`;
|
||||
}
|
||||
|
||||
export function getTsBuildProjectFile(project: string, file: string): File {
|
||||
return {
|
||||
path: getTsBuildProjectFilePath(project, file),
|
||||
content: Harness.IO.readFile(`${Harness.IO.getWorkspaceRoot()}/tests/projects/${project}/${file}`)!
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@ namespace vpath {
|
||||
export import relative = ts.getRelativePathFromDirectory;
|
||||
export import beneath = ts.containsPath;
|
||||
export import changeExtension = ts.changeAnyExtension;
|
||||
export import isTypeScript = ts.hasTypescriptFileExtension;
|
||||
export import isJavaScript = ts.hasJavascriptFileExtension;
|
||||
export import isTypeScript = ts.hasTSFileExtension;
|
||||
export import isJavaScript = ts.hasJSFileExtension;
|
||||
|
||||
const invalidRootComponentRegExp = /^(?!(\/|\/\/\w+\/|[a-zA-Z]:\/?|)$)/;
|
||||
const invalidNavigableComponentRegExp = /[:*?"<>|]/;
|
||||
|
||||
@@ -24,13 +24,11 @@ namespace ts.JsTyping {
|
||||
version: Version;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isTypingUpToDate(cachedTyping: CachedTyping, availableTypingVersions: MapLike<string>) {
|
||||
const availableVersion = new Version(getProperty(availableTypingVersions, `ts${versionMajorMinor}`) || getProperty(availableTypingVersions, "latest")!);
|
||||
return availableVersion.compareTo(cachedTyping.version) <= 0;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export const nodeCoreModuleList: ReadonlyArray<string> = [
|
||||
"assert",
|
||||
"async_hooks",
|
||||
@@ -70,7 +68,6 @@ namespace ts.JsTyping {
|
||||
"zlib"
|
||||
];
|
||||
|
||||
/* @internal */
|
||||
export const nodeCoreModules = arrayToSet(nodeCoreModuleList);
|
||||
|
||||
/**
|
||||
@@ -122,7 +119,7 @@ namespace ts.JsTyping {
|
||||
// Only infer typings for .js and .jsx files
|
||||
fileNames = mapDefined(fileNames, fileName => {
|
||||
const path = normalizePath(fileName);
|
||||
if (hasJavascriptFileExtension(path)) {
|
||||
if (hasJSFileExtension(path)) {
|
||||
return path;
|
||||
}
|
||||
});
|
||||
@@ -218,7 +215,7 @@ namespace ts.JsTyping {
|
||||
*/
|
||||
function getTypingNamesFromSourceFileNames(fileNames: string[]) {
|
||||
const fromFileNames = mapDefined(fileNames, j => {
|
||||
if (!hasJavascriptFileExtension(j)) return undefined;
|
||||
if (!hasJSFileExtension(j)) return undefined;
|
||||
|
||||
const inferredTypingName = removeFileExtension(getBaseFileName(j.toLowerCase()));
|
||||
const cleanedTypingName = removeMinAndVersionNumbers(inferredTypingName);
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace ts.server {
|
||||
export const ActionSet: ActionSet = "action::set";
|
||||
export const ActionInvalidate: ActionInvalidate = "action::invalidate";
|
||||
export const ActionPackageInstalled: ActionPackageInstalled = "action::packageInstalled";
|
||||
export const ActionValueInspected: ActionValueInspected = "action::valueInspected";
|
||||
export const EventTypesRegistry: EventTypesRegistry = "event::typesRegistry";
|
||||
export const EventBeginInstallTypes: EventBeginInstallTypes = "event::beginInstallTypes";
|
||||
export const EventEndInstallTypes: EventEndInstallTypes = "event::endInstallTypes";
|
||||
@@ -33,7 +34,6 @@ namespace ts.server {
|
||||
: undefined;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function nowString() {
|
||||
// E.g. "12:34:56.789"
|
||||
const d = new Date();
|
||||
|
||||
+16
-7
@@ -2,17 +2,14 @@ declare namespace ts.server {
|
||||
export type ActionSet = "action::set";
|
||||
export type ActionInvalidate = "action::invalidate";
|
||||
export type ActionPackageInstalled = "action::packageInstalled";
|
||||
export type ActionValueInspected = "action::valueInspected";
|
||||
export type EventTypesRegistry = "event::typesRegistry";
|
||||
export type EventBeginInstallTypes = "event::beginInstallTypes";
|
||||
export type EventEndInstallTypes = "event::endInstallTypes";
|
||||
export type EventInitializationFailed = "event::initializationFailed";
|
||||
|
||||
export interface SortedReadonlyArray<T> extends ReadonlyArray<T> {
|
||||
" __sortedArrayBrand": any;
|
||||
}
|
||||
|
||||
export interface TypingInstallerResponse {
|
||||
readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | ActionPackageInstalled | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed;
|
||||
readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | ActionPackageInstalled | ActionValueInspected | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed;
|
||||
}
|
||||
|
||||
export interface TypingInstallerRequestWithProjectName {
|
||||
@@ -20,7 +17,7 @@ declare namespace ts.server {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export type TypingInstallerRequestUnion = DiscoverTypings | CloseProject | TypesRegistryRequest | InstallPackageRequest;
|
||||
export type TypingInstallerRequestUnion = DiscoverTypings | CloseProject | TypesRegistryRequest | InstallPackageRequest | InspectValueRequest;
|
||||
|
||||
export interface DiscoverTypings extends TypingInstallerRequestWithProjectName {
|
||||
readonly fileNames: string[];
|
||||
@@ -47,6 +44,12 @@ declare namespace ts.server {
|
||||
readonly projectRootPath: Path;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface InspectValueRequest {
|
||||
readonly kind: "inspectValue";
|
||||
readonly options: InspectValueOptions;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface TypesRegistryResponse extends TypingInstallerResponse {
|
||||
readonly kind: EventTypesRegistry;
|
||||
@@ -59,6 +62,12 @@ declare namespace ts.server {
|
||||
readonly message: string;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface InspectValueResponse {
|
||||
readonly kind: ActionValueInspected;
|
||||
readonly result: ValueInfo;
|
||||
}
|
||||
|
||||
export interface InitializationFailedResponse extends TypingInstallerResponse {
|
||||
readonly kind: EventInitializationFailed;
|
||||
readonly message: string;
|
||||
@@ -106,5 +115,5 @@ declare namespace ts.server {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export type TypingInstallerResponseUnion = SetTypings | InvalidateCachedTypings | TypesRegistryResponse | PackageInstalledResponse | InstallTypes | InitializationFailedResponse;
|
||||
export type TypingInstallerResponseUnion = SetTypings | InvalidateCachedTypings | TypesRegistryResponse | PackageInstalledResponse | InspectValueResponse | InstallTypes | InitializationFailedResponse;
|
||||
}
|
||||
|
||||
Vendored
+517
-299
File diff suppressed because it is too large
Load Diff
Vendored
+2
-1
@@ -9,7 +9,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
@@ -135,7 +135,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
@@ -7,7 +7,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>;
|
||||
@@ -193,4 +193,4 @@ interface PromiseConstructor {
|
||||
resolve(): Promise<void>;
|
||||
}
|
||||
|
||||
declare var Promise: PromiseConstructor;
|
||||
declare var Promise: PromiseConstructor;
|
||||
|
||||
Vendored
+11
-11
@@ -63,7 +63,7 @@ interface SymbolConstructor {
|
||||
}
|
||||
|
||||
interface Symbol {
|
||||
readonly [Symbol.toStringTag]: "Symbol";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface Array<T> {
|
||||
@@ -107,23 +107,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 {
|
||||
@@ -138,15 +138,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 {
|
||||
@@ -241,11 +241,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
+61
-1
@@ -295,6 +295,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;
|
||||
@@ -1350,7 +1410,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];
|
||||
|
||||
Vendored
+609
@@ -0,0 +1,609 @@
|
||||
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
@@ -1,5 +1,6 @@
|
||||
/// <reference lib="es2018" />
|
||||
/// <reference lib="esnext.asynciterable" />
|
||||
/// <reference lib="esnext.array" />
|
||||
/// <reference lib="esnext.bigint" />
|
||||
/// <reference lib="esnext.symbol" />
|
||||
/// <reference lib="esnext.intl" />
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
"es2018.intl",
|
||||
"esnext.asynciterable",
|
||||
"esnext.array",
|
||||
"esnext.bigint",
|
||||
"esnext.symbol",
|
||||
"esnext.intl",
|
||||
// Default libraries
|
||||
|
||||
Vendored
+1296
-13
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LCX SchemaVersion="6.0" Name="f:\ddSetup\sources\typescript\localization\compiler2.resx" PsrId="306" FileType="1" SrcCul="en-US" TgtCul="zh-TW" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
|
||||
<Props>
|
||||
<Str Name="CustomName1" Val="Custom 1" />
|
||||
@@ -3766,7 +3766,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract constant]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[解壓縮常數]]></Val>
|
||||
<Val><![CDATA[擷取常數]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -3775,7 +3775,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[解壓縮函式]]></Val>
|
||||
<Val><![CDATA[擷取函式]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -3784,7 +3784,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract to {0} in {1}]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[解壓縮至 {1} 中的 {0}]]></Val>
|
||||
<Val><![CDATA[擷取至 {1} 中的 {0}]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -3793,7 +3793,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract to {0} in {1} scope]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[解壓縮至 {1} 範圍中的 {0}]]></Val>
|
||||
<Val><![CDATA[擷取至 {1} 範圍中的 {0}]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -3802,7 +3802,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract to {0} in enclosing scope]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[解壓縮至封閉式範圍中的 {0}]]></Val>
|
||||
<Val><![CDATA[擷取至封閉式範圍中的 {0}]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -5437,7 +5437,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Move to a new file]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[移至新行]]></Val>
|
||||
<Val><![CDATA[移至新檔]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+291
-84
@@ -5,6 +5,8 @@ namespace ts.server {
|
||||
|
||||
// tslint:disable variable-name
|
||||
export const ProjectsUpdatedInBackgroundEvent = "projectsUpdatedInBackground";
|
||||
export const ProjectLoadingStartEvent = "projectLoadingStart";
|
||||
export const ProjectLoadingFinishEvent = "projectLoadingFinish";
|
||||
export const SurveyReady = "surveyReady";
|
||||
export const LargeFileReferencedEvent = "largeFileReferenced";
|
||||
export const ConfigFileDiagEvent = "configFileDiag";
|
||||
@@ -18,6 +20,16 @@ namespace ts.server {
|
||||
data: { openFiles: string[]; };
|
||||
}
|
||||
|
||||
export interface ProjectLoadingStartEvent {
|
||||
eventName: typeof ProjectLoadingStartEvent;
|
||||
data: { project: Project; reason: string; };
|
||||
}
|
||||
|
||||
export interface ProjectLoadingFinishEvent {
|
||||
eventName: typeof ProjectLoadingFinishEvent;
|
||||
data: { project: Project; };
|
||||
}
|
||||
|
||||
export interface SurveyReady {
|
||||
eventName: typeof SurveyReady;
|
||||
data: { surveyId: string; };
|
||||
@@ -44,6 +56,24 @@ namespace ts.server {
|
||||
readonly data: ProjectInfoTelemetryEventData;
|
||||
}
|
||||
|
||||
/* __GDPR__
|
||||
"projectInfo" : {
|
||||
"${include}": ["${TypeScriptCommonProperties}"],
|
||||
"projectId": { "classification": "EndUserPseudonymizedInformation", "purpose": "FeatureInsight", "endpoint": "ProjectId" },
|
||||
"fileStats": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"compilerOptions": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"extends": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"files": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"include": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"exclude": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"compileOnSave": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"typeAcquisition": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"configFileName": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"projectType": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"languageServiceEnabled": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"version": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
export interface ProjectInfoTelemetryEventData {
|
||||
/** Cryptographically secure hash of project file location. */
|
||||
readonly projectId: string;
|
||||
@@ -93,18 +123,37 @@ namespace ts.server {
|
||||
|
||||
export interface FileStats {
|
||||
readonly js: number;
|
||||
readonly jsSize?: number;
|
||||
|
||||
readonly jsx: number;
|
||||
readonly jsxSize?: number;
|
||||
|
||||
readonly ts: number;
|
||||
readonly tsSize?: number;
|
||||
|
||||
readonly tsx: number;
|
||||
readonly tsxSize?: number;
|
||||
|
||||
readonly dts: number;
|
||||
readonly dtsSize?: number;
|
||||
|
||||
readonly deferred: number;
|
||||
readonly deferredSize?: number;
|
||||
}
|
||||
|
||||
export interface OpenFileInfo {
|
||||
readonly checkJs: boolean;
|
||||
}
|
||||
|
||||
export type ProjectServiceEvent = LargeFileReferencedEvent | SurveyReady | ProjectsUpdatedInBackgroundEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent | OpenFileInfoTelemetryEvent;
|
||||
export type ProjectServiceEvent = LargeFileReferencedEvent |
|
||||
SurveyReady |
|
||||
ProjectsUpdatedInBackgroundEvent |
|
||||
ProjectLoadingStartEvent |
|
||||
ProjectLoadingFinishEvent |
|
||||
ConfigFileDiagEvent |
|
||||
ProjectLanguageServiceStateEvent |
|
||||
ProjectInfoTelemetryEvent |
|
||||
OpenFileInfoTelemetryEvent;
|
||||
|
||||
export type ProjectServiceEventHandler = (event: ProjectServiceEvent) => void;
|
||||
|
||||
@@ -291,7 +340,8 @@ namespace ts.server {
|
||||
ClosedScriptInfo = "Closed Script info",
|
||||
ConfigFileForInferredRoot = "Config file for the inferred project root",
|
||||
FailedLookupLocation = "Directory of Failed lookup locations in module resolution",
|
||||
TypeRoots = "Type root directory"
|
||||
TypeRoots = "Type root directory",
|
||||
NodeModulesForClosedScriptInfo = "node_modules for closed script infos in them",
|
||||
}
|
||||
|
||||
const enum ConfigFileWatcherStatus {
|
||||
@@ -353,10 +403,18 @@ namespace ts.server {
|
||||
return !!(infoOrFileName as ScriptInfo).containingProjects;
|
||||
}
|
||||
|
||||
interface ScriptInfoInNodeModulesWatcher extends FileWatcher {
|
||||
refCount: number;
|
||||
}
|
||||
|
||||
function getDetailWatchInfo(watchType: WatchType, project: Project | undefined) {
|
||||
return `Project: ${project ? project.getProjectName() : ""} WatchType: ${watchType}`;
|
||||
}
|
||||
|
||||
function isScriptInfoWatchedFromNodeModules(info: ScriptInfo) {
|
||||
return !info.isScriptOpen() && info.mTime !== undefined;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function updateProjectIfDirty(project: Project) {
|
||||
return project.dirty && project.updateGraph();
|
||||
@@ -380,6 +438,7 @@ namespace ts.server {
|
||||
* Container of all known scripts
|
||||
*/
|
||||
private readonly filenameToScriptInfo = createMap<ScriptInfo>();
|
||||
private readonly scriptInfoInNodeModulesWatchers = createMap <ScriptInfoInNodeModulesWatcher>();
|
||||
/**
|
||||
* Contains all the deleted script info's version information so that
|
||||
* it does not reset when creating script info again
|
||||
@@ -438,7 +497,7 @@ namespace ts.server {
|
||||
|
||||
private readonly hostConfiguration: HostConfiguration;
|
||||
private safelist: SafeList = defaultTypeSafeList;
|
||||
private legacySafelist: { [key: string]: string } = {};
|
||||
private readonly legacySafelist = createMap<string>();
|
||||
|
||||
private pendingProjectUpdates = createMap<Project>();
|
||||
/* @internal */
|
||||
@@ -461,6 +520,8 @@ namespace ts.server {
|
||||
public readonly globalPlugins: ReadonlyArray<string>;
|
||||
public readonly pluginProbeLocations: ReadonlyArray<string>;
|
||||
public readonly allowLocalPluginLoads: boolean;
|
||||
private currentPluginConfigOverrides: Map<any> | undefined;
|
||||
|
||||
public readonly typesMapLocation: string | undefined;
|
||||
|
||||
public readonly syntaxOnly?: boolean;
|
||||
@@ -513,7 +574,7 @@ namespace ts.server {
|
||||
this.typingsCache = new TypingsCache(this.typingsInstaller);
|
||||
|
||||
this.hostConfiguration = {
|
||||
formatCodeOptions: getDefaultFormatCodeSettings(this.host),
|
||||
formatCodeOptions: getDefaultFormatCodeSettings(this.host.newLine),
|
||||
preferences: emptyOptions,
|
||||
hostInfo: "Unknown host",
|
||||
extraFileExtensions: []
|
||||
@@ -590,14 +651,14 @@ namespace ts.server {
|
||||
this.safelist = raw.typesMap;
|
||||
for (const key in raw.simpleMap) {
|
||||
if (raw.simpleMap.hasOwnProperty(key)) {
|
||||
this.legacySafelist[key] = raw.simpleMap[key].toLowerCase();
|
||||
this.legacySafelist.set(key, raw.simpleMap[key].toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
this.logger.info(`Error loading types map: ${e}`);
|
||||
this.safelist = defaultTypeSafeList;
|
||||
this.legacySafelist = {};
|
||||
this.legacySafelist.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -693,6 +754,33 @@ namespace ts.server {
|
||||
this.eventHandler(event);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
sendProjectLoadingStartEvent(project: ConfiguredProject, reason: string) {
|
||||
if (!this.eventHandler) {
|
||||
return;
|
||||
}
|
||||
project.sendLoadingProjectFinish = true;
|
||||
const event: ProjectLoadingStartEvent = {
|
||||
eventName: ProjectLoadingStartEvent,
|
||||
data: { project, reason }
|
||||
};
|
||||
this.eventHandler(event);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
sendProjectLoadingFinishEvent(project: ConfiguredProject) {
|
||||
if (!this.eventHandler || !project.sendLoadingProjectFinish) {
|
||||
return;
|
||||
}
|
||||
|
||||
project.sendLoadingProjectFinish = false;
|
||||
const event: ProjectLoadingFinishEvent = {
|
||||
eventName: ProjectLoadingFinishEvent,
|
||||
data: { project }
|
||||
};
|
||||
this.eventHandler(event);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(project: Project) {
|
||||
this.delayUpdateProjectGraph(project);
|
||||
@@ -758,9 +846,9 @@ namespace ts.server {
|
||||
|
||||
/* @internal */
|
||||
private forEachProject(cb: (project: Project) => void) {
|
||||
this.inferredProjects.forEach(cb);
|
||||
this.configuredProjects.forEach(cb);
|
||||
this.externalProjects.forEach(cb);
|
||||
this.configuredProjects.forEach(cb);
|
||||
this.inferredProjects.forEach(cb);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -790,7 +878,7 @@ namespace ts.server {
|
||||
private doEnsureDefaultProjectForFile(fileName: NormalizedPath): Project {
|
||||
this.ensureProjectStructuresUptoDate();
|
||||
const scriptInfo = this.getScriptInfoForNormalizedPath(fileName);
|
||||
return scriptInfo ? scriptInfo.getDefaultProject() : Errors.ThrowNoProject();
|
||||
return scriptInfo ? scriptInfo.getDefaultProject() : (this.logErrorForScriptInfoNotFound(fileName), Errors.ThrowNoProject());
|
||||
}
|
||||
|
||||
getScriptInfoEnsuringProjectsUptoDate(uncheckedFileName: string) {
|
||||
@@ -843,15 +931,20 @@ namespace ts.server {
|
||||
if (!info) {
|
||||
this.logger.msg(`Error: got watch notification for unknown file: ${fileName}`);
|
||||
}
|
||||
else if (eventKind === FileWatcherEventKind.Deleted) {
|
||||
// File was deleted
|
||||
this.handleDeletedFile(info);
|
||||
}
|
||||
else if (!info.isScriptOpen()) {
|
||||
// file has been changed which might affect the set of referenced files in projects that include
|
||||
// this file and set of inferred projects
|
||||
info.delayReloadNonMixedContentFile();
|
||||
this.delayUpdateProjectGraphs(info.containingProjects);
|
||||
else {
|
||||
if (info.containingProjects) {
|
||||
info.containingProjects.forEach(project => project.resolutionCache.removeResolutionsFromProjectReferenceRedirects(info.path));
|
||||
}
|
||||
if (eventKind === FileWatcherEventKind.Deleted) {
|
||||
// File was deleted
|
||||
this.handleDeletedFile(info);
|
||||
}
|
||||
else if (!info.isScriptOpen()) {
|
||||
// file has been changed which might affect the set of referenced files in projects that include
|
||||
// this file and set of inferred projects
|
||||
info.delayReloadNonMixedContentFile();
|
||||
this.delayUpdateProjectGraphs(info.containingProjects);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -882,6 +975,7 @@ namespace ts.server {
|
||||
fileOrDirectory => {
|
||||
const fileOrDirectoryPath = this.toPath(fileOrDirectory);
|
||||
project.getCachedDirectoryStructureHost().addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
|
||||
if (isPathInNodeModulesStartingWithDot(fileOrDirectoryPath)) return;
|
||||
const configFilename = project.getConfigFilePath();
|
||||
|
||||
// If the the added or created file or directory is not supported file name, ignore the file
|
||||
@@ -927,6 +1021,7 @@ namespace ts.server {
|
||||
else {
|
||||
this.logConfigFileWatchUpdate(project.getConfigFilePath(), project.canonicalConfigFilePath, configFileExistenceInfo, ConfigFileWatcherStatus.ReloadingInferredRootFiles);
|
||||
project.pendingReload = ConfigFileProgramReloadLevel.Full;
|
||||
project.pendingReloadReason = "Change in config file detected";
|
||||
this.delayUpdateProjectGraph(project);
|
||||
// As we scheduled the update on configured project graph,
|
||||
// we would need to schedule the project reload for only the root of inferred projects
|
||||
@@ -953,11 +1048,12 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private removeProject(project: Project) {
|
||||
this.logger.info(`remove project: ${project.getRootFiles().toString()}`);
|
||||
this.logger.info("`remove Project::");
|
||||
project.print();
|
||||
|
||||
project.close();
|
||||
if (Debug.shouldAssert(AssertionLevel.Normal)) {
|
||||
this.filenameToScriptInfo.forEach(info => Debug.assert(!info.isAttached(project)));
|
||||
this.filenameToScriptInfo.forEach(info => Debug.assert(!info.isAttached(project), "Found script Info still attached to project", () => `${project.projectName}: ScriptInfos still attached: ${JSON.stringify(mapDefined(arrayFrom(this.filenameToScriptInfo.values()), info => info.isAttached(project) ? info : undefined))}`));
|
||||
}
|
||||
// Remove the project from pending project updates
|
||||
this.pendingProjectUpdates.delete(project.getProjectName());
|
||||
@@ -1393,19 +1489,9 @@ namespace ts.server {
|
||||
|
||||
const writeProjectFileNames = this.logger.hasLevel(LogLevel.verbose);
|
||||
this.logger.startGroup();
|
||||
let counter = 0;
|
||||
const printProjects = (projects: Project[], counter: number): number => {
|
||||
for (const project of projects) {
|
||||
this.logger.info(`Project '${project.getProjectName()}' (${ProjectKind[project.projectKind]}) ${counter}`);
|
||||
this.logger.info(project.filesToString(writeProjectFileNames));
|
||||
this.logger.info("-----------------------------------------------");
|
||||
counter++;
|
||||
}
|
||||
return counter;
|
||||
};
|
||||
counter = printProjects(this.externalProjects, counter);
|
||||
counter = printProjects(arrayFrom(this.configuredProjects.values()), counter);
|
||||
printProjects(this.inferredProjects, counter);
|
||||
let counter = printProjectsWithCounter(this.externalProjects, 0);
|
||||
counter = printProjectsWithCounter(arrayFrom(this.configuredProjects.values()), counter);
|
||||
printProjectsWithCounter(this.inferredProjects, counter);
|
||||
|
||||
this.logger.info("Open files: ");
|
||||
this.openFiles.forEach((projectRootPath, path) => {
|
||||
@@ -1447,14 +1533,14 @@ namespace ts.server {
|
||||
|
||||
for (const f of fileNames) {
|
||||
const fileName = propertyReader.getFileName(f);
|
||||
if (hasTypescriptFileExtension(fileName)) {
|
||||
if (hasTSFileExtension(fileName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
totalNonTsFileSize += this.host.getFileSize(fileName);
|
||||
|
||||
if (totalNonTsFileSize > maxProgramSizeForNonTsFiles || totalNonTsFileSize > availableSpace) {
|
||||
this.logger.info(getExceedLimitMessage({ propertyReader, hasTypescriptFileExtension, host: this.host }, totalNonTsFileSize));
|
||||
this.logger.info(getExceedLimitMessage({ propertyReader, hasTSFileExtension, host: this.host }, totalNonTsFileSize));
|
||||
// Keep the size as zero since it's disabled
|
||||
return fileName;
|
||||
}
|
||||
@@ -1464,14 +1550,14 @@ namespace ts.server {
|
||||
|
||||
return;
|
||||
|
||||
function getExceedLimitMessage(context: { propertyReader: FilePropertyReader<any>, hasTypescriptFileExtension: (filename: string) => boolean, host: ServerHost }, totalNonTsFileSize: number) {
|
||||
function getExceedLimitMessage(context: { propertyReader: FilePropertyReader<any>, hasTSFileExtension: (filename: string) => boolean, host: ServerHost }, totalNonTsFileSize: number) {
|
||||
const files = getTop5LargestFiles(context);
|
||||
|
||||
return `Non TS file size exceeded limit (${totalNonTsFileSize}). Largest files: ${files.map(file => `${file.name}:${file.size}`).join(", ")}`;
|
||||
}
|
||||
function getTop5LargestFiles({ propertyReader, hasTypescriptFileExtension, host }: { propertyReader: FilePropertyReader<any>, hasTypescriptFileExtension: (filename: string) => boolean, host: ServerHost }) {
|
||||
function getTop5LargestFiles({ propertyReader, hasTSFileExtension, host }: { propertyReader: FilePropertyReader<any>, hasTSFileExtension: (filename: string) => boolean, host: ServerHost }) {
|
||||
return fileNames.map(f => propertyReader.getFileName(f))
|
||||
.filter(name => hasTypescriptFileExtension(name))
|
||||
.filter(name => hasTSFileExtension(name))
|
||||
.map(name => ({ name, size: host.getFileSize!(name) })) // TODO: GH#18217
|
||||
.sort((a, b) => b.size - a.size)
|
||||
.slice(0, 5);
|
||||
@@ -1525,7 +1611,7 @@ namespace ts.server {
|
||||
setProjectOptionsUsed(project);
|
||||
const data: ProjectInfoTelemetryEventData = {
|
||||
projectId: this.host.createSHA256Hash(project.projectName),
|
||||
fileStats: countEachFileTypes(project.getScriptInfos()),
|
||||
fileStats: countEachFileTypes(project.getScriptInfos(), /*includeSizes*/ true),
|
||||
compilerOptions: convertCompilerOptionsForTelemetry(project.getCompilationSettings()),
|
||||
typeAcquisition: convertTypeAcquisition(project.getTypeAcquisition()),
|
||||
extends: projectOptions && projectOptions.configHasExtendsProperty,
|
||||
@@ -1585,22 +1671,23 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
private createConfiguredProjectWithDelayLoad(configFileName: NormalizedPath) {
|
||||
private createConfiguredProjectWithDelayLoad(configFileName: NormalizedPath, reason: string) {
|
||||
const project = this.createConfiguredProject(configFileName);
|
||||
project.pendingReload = ConfigFileProgramReloadLevel.Full;
|
||||
project.pendingReloadReason = reason;
|
||||
return project;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
private createAndLoadConfiguredProject(configFileName: NormalizedPath) {
|
||||
private createAndLoadConfiguredProject(configFileName: NormalizedPath, reason: string) {
|
||||
const project = this.createConfiguredProject(configFileName);
|
||||
this.loadConfiguredProject(project);
|
||||
this.loadConfiguredProject(project, reason);
|
||||
return project;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
private createLoadAndUpdateConfiguredProject(configFileName: NormalizedPath) {
|
||||
const project = this.createAndLoadConfiguredProject(configFileName);
|
||||
private createLoadAndUpdateConfiguredProject(configFileName: NormalizedPath, reason: string) {
|
||||
const project = this.createAndLoadConfiguredProject(configFileName, reason);
|
||||
project.updateGraph();
|
||||
return project;
|
||||
}
|
||||
@@ -1609,7 +1696,9 @@ namespace ts.server {
|
||||
* Read the config file of the project, and update the project root file names.
|
||||
*/
|
||||
/* @internal */
|
||||
private loadConfiguredProject(project: ConfiguredProject) {
|
||||
private loadConfiguredProject(project: ConfiguredProject, reason: string) {
|
||||
this.sendProjectLoadingStartEvent(project, reason);
|
||||
|
||||
// Read updated contents from disk
|
||||
const configFilename = normalizePath(project.getConfigFilePath());
|
||||
|
||||
@@ -1646,6 +1735,7 @@ namespace ts.server {
|
||||
};
|
||||
}
|
||||
project.configFileSpecs = parsedCommandLine.configFileSpecs;
|
||||
project.canConfigFileJsonReportNoInputFiles = canJsonReportNoInutFiles(parsedCommandLine.raw);
|
||||
project.setProjectErrors(configFileErrors);
|
||||
project.updateReferences(parsedCommandLine.projectReferences);
|
||||
const lastFileExceededProgramSize = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(project.canonicalConfigFilePath, compilerOptions, parsedCommandLine.fileNames, fileNamePropertyReader);
|
||||
@@ -1657,7 +1747,7 @@ namespace ts.server {
|
||||
project.enableLanguageService();
|
||||
project.watchWildcards(createMapFromTemplate(parsedCommandLine.wildcardDirectories!)); // TODO: GH#18217
|
||||
}
|
||||
project.enablePluginsWithOptions(compilerOptions);
|
||||
project.enablePluginsWithOptions(compilerOptions, this.currentPluginConfigOverrides);
|
||||
const filesToAdd = parsedCommandLine.fileNames.concat(project.getExternalFiles());
|
||||
this.updateRootAndOptionsOfNonInferredProject(project, filesToAdd, fileNamePropertyReader, compilerOptions, parsedCommandLine.typeAcquisition!, parsedCommandLine.compileOnSave!); // TODO: GH#18217
|
||||
}
|
||||
@@ -1738,7 +1828,7 @@ namespace ts.server {
|
||||
const configFileSpecs = project.configFileSpecs!; // TODO: GH#18217
|
||||
const configFileName = project.getConfigFilePath();
|
||||
const fileNamesResult = getFileNamesFromConfigSpecs(configFileSpecs, getDirectoryPath(configFileName), project.getCompilationSettings(), project.getCachedDirectoryStructureHost(), this.hostConfiguration.extraFileExtensions);
|
||||
project.updateErrorOnNoInputFiles(fileNamesResult.fileNames.length !== 0);
|
||||
project.updateErrorOnNoInputFiles(fileNamesResult);
|
||||
this.updateNonInferredProjectFiles(project, fileNamesResult.fileNames.concat(project.getExternalFiles()), fileNamePropertyReader);
|
||||
return project.updateGraph();
|
||||
}
|
||||
@@ -1747,7 +1837,7 @@ namespace ts.server {
|
||||
* Read the config file of the project again by clearing the cache and update the project graph
|
||||
*/
|
||||
/* @internal */
|
||||
reloadConfiguredProject(project: ConfiguredProject) {
|
||||
reloadConfiguredProject(project: ConfiguredProject, reason: string) {
|
||||
// At this point, there is no reason to not have configFile in the host
|
||||
const host = project.getCachedDirectoryStructureHost();
|
||||
|
||||
@@ -1757,7 +1847,7 @@ namespace ts.server {
|
||||
this.logger.info(`Reloading configured project ${configFileName}`);
|
||||
|
||||
// Load project from the disk
|
||||
this.loadConfiguredProject(project);
|
||||
this.loadConfiguredProject(project, reason);
|
||||
project.updateGraph();
|
||||
|
||||
this.sendConfigFileDiagEvent(project, configFileName);
|
||||
@@ -1847,7 +1937,7 @@ namespace ts.server {
|
||||
|
||||
private createInferredProject(currentDirectory: string | undefined, isSingleInferredProject?: boolean, projectRootPath?: NormalizedPath): InferredProject {
|
||||
const compilerOptions = projectRootPath && this.compilerOptionsForInferredProjectsPerProjectRoot.get(projectRootPath) || this.compilerOptionsForInferredProjects;
|
||||
const project = new InferredProject(this, this.documentRegistry, compilerOptions, projectRootPath, currentDirectory);
|
||||
const project = new InferredProject(this, this.documentRegistry, compilerOptions, projectRootPath, currentDirectory, this.currentPluginConfigOverrides);
|
||||
if (isSingleInferredProject) {
|
||||
this.inferredProjects.unshift(project);
|
||||
}
|
||||
@@ -1878,6 +1968,12 @@ namespace ts.server {
|
||||
return configProject && configProject.getCompilerOptions().configFile;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
logErrorForScriptInfoNotFound(fileName: string): void {
|
||||
const names = arrayFrom(this.filenameToScriptInfo.entries()).map(([path, scriptInfo]) => ({ path, fileName: scriptInfo.fileName }));
|
||||
this.logger.msg(`Could not find file ${JSON.stringify(fileName)}.\nAll files are: ${JSON.stringify(names)}`, Msg.Err);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the projects that contain script info through SymLink
|
||||
* Note that this does not return projects in info.containingProjects
|
||||
@@ -1923,18 +2019,99 @@ namespace ts.server {
|
||||
if (!info.isDynamicOrHasMixedContent() &&
|
||||
(!this.globalCacheLocationDirectoryPath ||
|
||||
!startsWith(info.path, this.globalCacheLocationDirectoryPath))) {
|
||||
const { fileName } = info;
|
||||
info.fileWatcher = this.watchFactory.watchFilePath(
|
||||
this.host,
|
||||
fileName,
|
||||
(fileName, eventKind, path) => this.onSourceFileChanged(fileName, eventKind, path),
|
||||
PollingInterval.Medium,
|
||||
info.path,
|
||||
WatchType.ClosedScriptInfo
|
||||
);
|
||||
const indexOfNodeModules = info.path.indexOf("/node_modules/");
|
||||
if (!this.host.getModifiedTime || indexOfNodeModules === -1) {
|
||||
info.fileWatcher = this.watchFactory.watchFilePath(
|
||||
this.host,
|
||||
info.fileName,
|
||||
(fileName, eventKind, path) => this.onSourceFileChanged(fileName, eventKind, path),
|
||||
PollingInterval.Medium,
|
||||
info.path,
|
||||
WatchType.ClosedScriptInfo
|
||||
);
|
||||
}
|
||||
else {
|
||||
info.mTime = this.getModifiedTime(info);
|
||||
info.fileWatcher = this.watchClosedScriptInfoInNodeModules(info.path.substr(0, indexOfNodeModules) as Path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private watchClosedScriptInfoInNodeModules(dir: Path): ScriptInfoInNodeModulesWatcher {
|
||||
// Watch only directory
|
||||
const existing = this.scriptInfoInNodeModulesWatchers.get(dir);
|
||||
if (existing) {
|
||||
existing.refCount++;
|
||||
return existing;
|
||||
}
|
||||
|
||||
const watchDir = dir + "/node_modules" as Path;
|
||||
const watcher = this.watchFactory.watchDirectory(
|
||||
this.host,
|
||||
watchDir,
|
||||
(fileOrDirectory) => {
|
||||
const fileOrDirectoryPath = this.toPath(fileOrDirectory);
|
||||
if (isPathInNodeModulesStartingWithDot(fileOrDirectoryPath)) return;
|
||||
|
||||
// Has extension
|
||||
Debug.assert(result.refCount > 0);
|
||||
if (watchDir === fileOrDirectoryPath) {
|
||||
this.refreshScriptInfosInDirectory(watchDir);
|
||||
}
|
||||
else {
|
||||
const info = this.getScriptInfoForPath(fileOrDirectoryPath);
|
||||
if (info) {
|
||||
if (isScriptInfoWatchedFromNodeModules(info)) {
|
||||
this.refreshScriptInfo(info);
|
||||
}
|
||||
}
|
||||
// Folder
|
||||
else if (!hasExtension(fileOrDirectoryPath)) {
|
||||
this.refreshScriptInfosInDirectory(fileOrDirectoryPath);
|
||||
}
|
||||
}
|
||||
},
|
||||
WatchDirectoryFlags.Recursive,
|
||||
WatchType.NodeModulesForClosedScriptInfo
|
||||
);
|
||||
const result: ScriptInfoInNodeModulesWatcher = {
|
||||
close: () => {
|
||||
if (result.refCount === 1) {
|
||||
watcher.close();
|
||||
this.scriptInfoInNodeModulesWatchers.delete(dir);
|
||||
}
|
||||
else {
|
||||
result.refCount--;
|
||||
}
|
||||
},
|
||||
refCount: 1
|
||||
};
|
||||
this.scriptInfoInNodeModulesWatchers.set(dir, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private getModifiedTime(info: ScriptInfo) {
|
||||
return (this.host.getModifiedTime!(info.path) || missingFileModifiedTime).getTime();
|
||||
}
|
||||
|
||||
private refreshScriptInfo(info: ScriptInfo) {
|
||||
const mTime = this.getModifiedTime(info);
|
||||
if (mTime !== info.mTime) {
|
||||
const eventKind = getFileWatcherEventKind(info.mTime!, mTime);
|
||||
info.mTime = mTime;
|
||||
this.onSourceFileChanged(info.fileName, eventKind, info.path);
|
||||
}
|
||||
}
|
||||
|
||||
private refreshScriptInfosInDirectory(dir: Path) {
|
||||
dir = dir + directorySeparator as Path;
|
||||
this.filenameToScriptInfo.forEach(info => {
|
||||
if (isScriptInfoWatchedFromNodeModules(info) && startsWith(info.path, dir)) {
|
||||
this.refreshScriptInfo(info);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private stopWatchingScriptInfo(info: ScriptInfo) {
|
||||
if (info.fileWatcher) {
|
||||
info.fileWatcher.close();
|
||||
@@ -1943,7 +2120,20 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private getOrCreateScriptInfoNotOpenedByClientForNormalizedPath(fileName: NormalizedPath, currentDirectory: string, scriptKind: ScriptKind | undefined, hasMixedContent: boolean | undefined, hostToQueryFileExistsOn: DirectoryStructureHost | undefined) {
|
||||
return this.getOrCreateScriptInfoWorker(fileName, currentDirectory, /*openedByClient*/ false, /*fileContent*/ undefined, scriptKind, hasMixedContent, hostToQueryFileExistsOn);
|
||||
if (isRootedDiskPath(fileName) || isDynamicFileName(fileName)) {
|
||||
return this.getOrCreateScriptInfoWorker(fileName, currentDirectory, /*openedByClient*/ false, /*fileContent*/ undefined, scriptKind, hasMixedContent, hostToQueryFileExistsOn);
|
||||
}
|
||||
|
||||
// This is non rooted path with different current directory than project service current directory
|
||||
// Only paths recognized are open relative file paths
|
||||
const info = this.openFilesWithNonRootedDiskPath.get(this.toCanonicalFileName(fileName));
|
||||
if (info) {
|
||||
return info;
|
||||
}
|
||||
|
||||
// This means triple slash references wont be resolved in dynamic and unsaved files
|
||||
// which is intentional since we dont know what it means to be relative to non disk files
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private getOrCreateScriptInfoOpenedByClientForNormalizedPath(fileName: NormalizedPath, currentDirectory: string, fileContent: string | undefined, scriptKind: ScriptKind | undefined, hasMixedContent: boolean | undefined) {
|
||||
@@ -1960,7 +2150,7 @@ namespace ts.server {
|
||||
let info = this.getScriptInfoForPath(path);
|
||||
if (!info) {
|
||||
const isDynamic = isDynamicFileName(fileName);
|
||||
Debug.assert(isRootedDiskPath(fileName) || isDynamic || openedByClient, "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })}\nScript info with non-dynamic relative file name can only be open script info`);
|
||||
Debug.assert(isRootedDiskPath(fileName) || isDynamic || openedByClient, "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })}\nScript info with non-dynamic relative file name can only be open script info or in context of host currentDirectory`);
|
||||
Debug.assert(!isRootedDiskPath(fileName) || this.currentDirectory === currentDirectory || !this.openFilesWithNonRootedDiskPath.has(this.toCanonicalFileName(fileName)), "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })}\nOpen script files with non rooted disk path opened with current directory context cannot have same canonical names`);
|
||||
Debug.assert(!isDynamic || this.currentDirectory === currentDirectory, "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })}\nDynamic files must always have current directory context since containing external project name will always match the script info name.`);
|
||||
// If the file is not opened by client and the file doesnot exist on the disk, return
|
||||
@@ -1973,7 +2163,7 @@ namespace ts.server {
|
||||
if (!openedByClient) {
|
||||
this.watchClosedScriptInfo(info);
|
||||
}
|
||||
else if (!isRootedDiskPath(fileName) && currentDirectory !== this.currentDirectory) {
|
||||
else if (!isRootedDiskPath(fileName) && !isDynamic) {
|
||||
// File that is opened by user but isn't rooted disk path
|
||||
this.openFilesWithNonRootedDiskPath.set(this.toCanonicalFileName(fileName), info);
|
||||
}
|
||||
@@ -2031,7 +2221,6 @@ namespace ts.server {
|
||||
if (project.hasExternalProjectRef() &&
|
||||
project.pendingReload === ConfigFileProgramReloadLevel.Full &&
|
||||
!this.pendingProjectUpdates.has(project.getProjectName())) {
|
||||
this.loadConfiguredProject(project);
|
||||
project.updateGraph();
|
||||
}
|
||||
});
|
||||
@@ -2063,7 +2252,7 @@ namespace ts.server {
|
||||
// as there is no need to load contents of the files from the disk
|
||||
|
||||
// Reload Projects
|
||||
this.reloadConfiguredProjectForFiles(this.openFiles, /*delayReload*/ false, returnTrue);
|
||||
this.reloadConfiguredProjectForFiles(this.openFiles, /*delayReload*/ false, returnTrue, "User requested reload projects");
|
||||
this.ensureProjectForOpenFiles();
|
||||
}
|
||||
|
||||
@@ -2074,7 +2263,8 @@ namespace ts.server {
|
||||
/*delayReload*/ true,
|
||||
ignoreIfNotRootOfInferredProject ?
|
||||
isRootOfInferredProject => isRootOfInferredProject : // Reload open files if they are root of inferred project
|
||||
returnTrue // Reload all the open files impacted by config file
|
||||
returnTrue, // Reload all the open files impacted by config file
|
||||
"Change in config file detected"
|
||||
);
|
||||
this.delayEnsureProjectForOpenFiles();
|
||||
}
|
||||
@@ -2086,7 +2276,7 @@ namespace ts.server {
|
||||
* If the there is no existing project it just opens the configured project for the config file
|
||||
* reloadForInfo provides a way to filter out files to reload configured project for
|
||||
*/
|
||||
private reloadConfiguredProjectForFiles<T>(openFiles: Map<T>, delayReload: boolean, shouldReloadProjectFor: (openFileValue: T) => boolean) {
|
||||
private reloadConfiguredProjectForFiles<T>(openFiles: Map<T>, delayReload: boolean, shouldReloadProjectFor: (openFileValue: T) => boolean, reason: string) {
|
||||
const updatedProjects = createMap<true>();
|
||||
// try to reload config file for all open files
|
||||
openFiles.forEach((openFileValue, path) => {
|
||||
@@ -2107,11 +2297,12 @@ namespace ts.server {
|
||||
if (!updatedProjects.has(configFileName)) {
|
||||
if (delayReload) {
|
||||
project.pendingReload = ConfigFileProgramReloadLevel.Full;
|
||||
project.pendingReloadReason = reason;
|
||||
this.delayUpdateProjectGraph(project);
|
||||
}
|
||||
else {
|
||||
// reload from the disk
|
||||
this.reloadConfiguredProject(project);
|
||||
this.reloadConfiguredProject(project, reason);
|
||||
}
|
||||
updatedProjects.set(configFileName, true);
|
||||
}
|
||||
@@ -2187,8 +2378,8 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getOriginalLocationEnsuringConfiguredProject(project: Project, location: sourcemaps.SourceMappableLocation): sourcemaps.SourceMappableLocation | undefined {
|
||||
const originalLocation = project.getSourceMapper().tryGetOriginalLocation(location);
|
||||
getOriginalLocationEnsuringConfiguredProject(project: Project, location: DocumentPosition): DocumentPosition | undefined {
|
||||
const originalLocation = project.getSourceMapper().tryGetSourcePosition(location);
|
||||
if (!originalLocation) return undefined;
|
||||
|
||||
const { fileName } = originalLocation;
|
||||
@@ -2198,7 +2389,8 @@ namespace ts.server {
|
||||
const configFileName = this.getConfigFileNameForFile(originalFileInfo);
|
||||
if (!configFileName) return undefined;
|
||||
|
||||
const configuredProject = this.findConfiguredProjectByProjectName(configFileName) || this.createAndLoadConfiguredProject(configFileName);
|
||||
const configuredProject = this.findConfiguredProjectByProjectName(configFileName) ||
|
||||
this.createAndLoadConfiguredProject(configFileName, `Creating project for original file: ${originalFileInfo.fileName} for location: ${location.fileName}`);
|
||||
updateProjectIfDirty(configuredProject);
|
||||
// Keep this configured project as referenced from project
|
||||
addOriginalConfiguredProject(configuredProject);
|
||||
@@ -2248,7 +2440,7 @@ namespace ts.server {
|
||||
if (configFileName) {
|
||||
project = this.findConfiguredProjectByProjectName(configFileName);
|
||||
if (!project) {
|
||||
project = this.createLoadAndUpdateConfiguredProject(configFileName);
|
||||
project = this.createLoadAndUpdateConfiguredProject(configFileName, `Creating possible configured project for ${fileName} to open`);
|
||||
// Send the event only if the project got created as part of this open request and info is part of the project
|
||||
if (info.isOrphan()) {
|
||||
// Since the file isnt part of configured project, do not send config file info
|
||||
@@ -2326,17 +2518,14 @@ namespace ts.server {
|
||||
}
|
||||
else {
|
||||
// If the configured project for project reference has more than zero references, keep it alive
|
||||
const resolvedProjectReferences = project.getResolvedProjectReferences();
|
||||
if (resolvedProjectReferences) {
|
||||
for (const ref of resolvedProjectReferences) {
|
||||
if (ref) {
|
||||
const refProject = this.configuredProjects.get(ref.sourceFile.path);
|
||||
if (refProject && refProject.hasOpenRef()) {
|
||||
toRemoveConfiguredProjects.delete(project.canonicalConfigFilePath);
|
||||
}
|
||||
project.forEachResolvedProjectReference(ref => {
|
||||
if (ref) {
|
||||
const refProject = this.configuredProjects.get(ref.sourceFile.path);
|
||||
if (refProject && refProject.hasOpenRef()) {
|
||||
toRemoveConfiguredProjects.delete(project.canonicalConfigFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2560,13 +2749,13 @@ namespace ts.server {
|
||||
if (fileExtensionIs(baseName, "js")) {
|
||||
const inferredTypingName = removeFileExtension(baseName);
|
||||
const cleanedTypingName = removeMinAndVersionNumbers(inferredTypingName);
|
||||
if (this.legacySafelist[cleanedTypingName]) {
|
||||
const typeName = this.legacySafelist.get(cleanedTypingName);
|
||||
if (typeName !== undefined) {
|
||||
this.logger.info(`Excluded '${normalizedNames[i]}' because it matched ${cleanedTypingName} from the legacy safelist`);
|
||||
excludedFiles.push(normalizedNames[i]);
|
||||
// *exclude* it from the project...
|
||||
exclude = true;
|
||||
// ... but *include* it in the list of types to acquire
|
||||
const typeName = this.legacySafelist[cleanedTypingName];
|
||||
// Same best-effort dedupe as above
|
||||
if (typeAcqInclude.indexOf(typeName) < 0) {
|
||||
typeAcqInclude.push(typeName);
|
||||
@@ -2689,8 +2878,8 @@ namespace ts.server {
|
||||
if (!project) {
|
||||
// errors are stored in the project, do not need to update the graph
|
||||
project = this.getHostPreferences().lazyConfiguredProjectsFromExternalProject ?
|
||||
this.createConfiguredProjectWithDelayLoad(tsconfigFile) :
|
||||
this.createLoadAndUpdateConfiguredProject(tsconfigFile);
|
||||
this.createConfiguredProjectWithDelayLoad(tsconfigFile, `Creating configured project in external project: ${proj.projectFileName}`) :
|
||||
this.createLoadAndUpdateConfiguredProject(tsconfigFile, `Creating configured project in external project: ${proj.projectFileName}`);
|
||||
}
|
||||
if (project && !contains(exisingConfigFiles, tsconfigFile)) {
|
||||
// keep project alive even if no documents are opened - its lifetime is bound to the lifetime of containing external project
|
||||
@@ -2717,6 +2906,16 @@ namespace ts.server {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
configurePlugin(args: protocol.ConfigurePluginRequestArguments) {
|
||||
// For any projects that already have the plugin loaded, configure the plugin
|
||||
this.forEachEnabledProject(project => project.onPluginConfigurationChanged(args.pluginName, args.configuration));
|
||||
|
||||
// Also save the current configuration to pass on to any projects that are yet to be loaded.
|
||||
// If a plugin is configured twice, only the latest configuration will be remembered.
|
||||
this.currentPluginConfigOverrides = this.currentPluginConfigOverrides || createMap();
|
||||
this.currentPluginConfigOverrides.set(args.pluginName, args.configuration);
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -2725,4 +2924,12 @@ namespace ts.server {
|
||||
export function isConfigFile(config: ScriptInfoOrConfig): config is TsConfigSourceFile {
|
||||
return (config as TsConfigSourceFile).kind !== undefined;
|
||||
}
|
||||
|
||||
function printProjectsWithCounter(projects: Project[], counter: number) {
|
||||
for (const project of projects) {
|
||||
project.print(counter);
|
||||
counter++;
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user