mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into tsconfig_canonicalpath
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:**
|
||||
|
||||
@@ -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.
|
||||
+3
-3
@@ -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>
|
||||
@@ -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).
|
||||
|
||||
@@ -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>
|
||||
@@ -861,6 +861,18 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";An_argument_for_0_was_not_provided_6210" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<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_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' or an enum type.]]></Val>
|
||||
@@ -1233,6 +1245,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 +1419,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`.]]></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_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`.]]></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_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`.]]></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 +2049,18 @@
|
||||
</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 +2319,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 +2415,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 +2493,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>
|
||||
@@ -2781,6 +2853,18 @@
|
||||
</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 +2913,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 +3303,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 +3339,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>
|
||||
@@ -3705,6 +3795,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>
|
||||
@@ -3909,9 +4005,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>
|
||||
@@ -5025,12 +5121,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 +5403,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>
|
||||
@@ -5589,6 +5685,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>
|
||||
@@ -6051,6 +6153,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>
|
||||
@@ -6207,6 +6315,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>
|
||||
@@ -6393,6 +6507,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 +6777,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 +6975,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}';\"",
|
||||
|
||||
@@ -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
+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
+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
+51
-6
@@ -827,15 +827,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 +854,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 +871,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 {
|
||||
/**
|
||||
@@ -1373,7 +1388,7 @@ declare namespace ts.server.protocol {
|
||||
* begin with prefix.
|
||||
*/
|
||||
interface CompletionsRequest extends FileLocationRequest {
|
||||
command: CommandTypes.Completions;
|
||||
command: CommandTypes.Completions | CommandTypes.CompletionInfo;
|
||||
arguments: CompletionsRequestArgs;
|
||||
}
|
||||
/**
|
||||
@@ -1885,6 +1900,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 +2264,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",
|
||||
|
||||
+5112
-3371
File diff suppressed because it is too large
Load Diff
+7546
-4530
File diff suppressed because it is too large
Load Diff
Vendored
+197
-280
@@ -14,7 +14,7 @@ and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
declare namespace ts {
|
||||
const versionMajorMinor = "3.1";
|
||||
const versionMajorMinor = "3.2";
|
||||
/** The version of the TypeScript compiler release */
|
||||
const version: string;
|
||||
}
|
||||
@@ -69,7 +69,8 @@ declare namespace ts {
|
||||
pos: number;
|
||||
end: number;
|
||||
}
|
||||
type JsDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.NoSubstitutionTemplateLiteral | SyntaxKind.Unknown;
|
||||
type JsDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.NoSubstitutionTemplateLiteral | SyntaxKind.Unknown | KeywordSyntaxKind;
|
||||
type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InKeyword | SyntaxKind.InferKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.OfKeyword;
|
||||
type JsxTokenSyntaxKind = SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken;
|
||||
enum SyntaxKind {
|
||||
Unknown = 0,
|
||||
@@ -536,6 +537,7 @@ declare namespace ts {
|
||||
name?: Identifier | StringLiteral | NumericLiteral;
|
||||
}
|
||||
interface ComputedPropertyName extends Node {
|
||||
parent: Declaration;
|
||||
kind: SyntaxKind.ComputedPropertyName;
|
||||
expression: Expression;
|
||||
}
|
||||
@@ -632,6 +634,7 @@ declare namespace ts {
|
||||
kind: SyntaxKind.ShorthandPropertyAssignment;
|
||||
name: Identifier;
|
||||
questionToken?: QuestionToken;
|
||||
exclamationToken?: ExclamationToken;
|
||||
equalsToken?: Token<SyntaxKind.EqualsToken>;
|
||||
objectAssignmentInitializer?: Expression;
|
||||
}
|
||||
@@ -668,6 +671,7 @@ declare namespace ts {
|
||||
_functionLikeDeclarationBrand: any;
|
||||
asteriskToken?: AsteriskToken;
|
||||
questionToken?: QuestionToken;
|
||||
exclamationToken?: ExclamationToken;
|
||||
body?: Block | Expression;
|
||||
}
|
||||
type FunctionLikeDeclaration = FunctionDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration | FunctionExpression | ArrowFunction;
|
||||
@@ -1079,7 +1083,7 @@ declare namespace ts {
|
||||
}
|
||||
interface ExpressionWithTypeArguments extends NodeWithTypeArguments {
|
||||
kind: SyntaxKind.ExpressionWithTypeArguments;
|
||||
parent: HeritageClause;
|
||||
parent: HeritageClause | JSDocAugmentsTag;
|
||||
expression: LeftHandSideExpression;
|
||||
}
|
||||
interface NewExpression extends PrimaryExpression, Declaration {
|
||||
@@ -1808,7 +1812,8 @@ declare namespace ts {
|
||||
getTypeChecker(): TypeChecker;
|
||||
isSourceFileFromExternalLibrary(file: SourceFile): boolean;
|
||||
isSourceFileDefaultLibrary(file: SourceFile): boolean;
|
||||
getProjectReferences(): (ResolvedProjectReference | undefined)[] | undefined;
|
||||
getProjectReferences(): ReadonlyArray<ProjectReference> | undefined;
|
||||
getResolvedProjectReferences(): (ResolvedProjectReference | undefined)[] | undefined;
|
||||
}
|
||||
interface ResolvedProjectReference {
|
||||
commandLine: ParsedCommandLine;
|
||||
@@ -2056,32 +2061,32 @@ declare namespace ts {
|
||||
ExportStar = 8388608,
|
||||
Optional = 16777216,
|
||||
Transient = 33554432,
|
||||
JSContainer = 67108864,
|
||||
Assignment = 67108864,
|
||||
ModuleExports = 134217728,
|
||||
Enum = 384,
|
||||
Variable = 3,
|
||||
Value = 67216319,
|
||||
Type = 67901928,
|
||||
Value = 67220415,
|
||||
Type = 67897832,
|
||||
Namespace = 1920,
|
||||
Module = 1536,
|
||||
Accessor = 98304,
|
||||
FunctionScopedVariableExcludes = 67216318,
|
||||
BlockScopedVariableExcludes = 67216319,
|
||||
ParameterExcludes = 67216319,
|
||||
FunctionScopedVariableExcludes = 67220414,
|
||||
BlockScopedVariableExcludes = 67220415,
|
||||
ParameterExcludes = 67220415,
|
||||
PropertyExcludes = 0,
|
||||
EnumMemberExcludes = 68008959,
|
||||
FunctionExcludes = 67215791,
|
||||
FunctionExcludes = 67219887,
|
||||
ClassExcludes = 68008383,
|
||||
InterfaceExcludes = 67901832,
|
||||
InterfaceExcludes = 67897736,
|
||||
RegularEnumExcludes = 68008191,
|
||||
ConstEnumExcludes = 68008831,
|
||||
ValueModuleExcludes = 67215503,
|
||||
ValueModuleExcludes = 110735,
|
||||
NamespaceModuleExcludes = 0,
|
||||
MethodExcludes = 67208127,
|
||||
GetAccessorExcludes = 67150783,
|
||||
SetAccessorExcludes = 67183551,
|
||||
TypeParameterExcludes = 67639784,
|
||||
TypeAliasExcludes = 67901928,
|
||||
MethodExcludes = 67212223,
|
||||
GetAccessorExcludes = 67154879,
|
||||
SetAccessorExcludes = 67187647,
|
||||
TypeParameterExcludes = 67635688,
|
||||
TypeAliasExcludes = 67897832,
|
||||
AliasExcludes = 2097152,
|
||||
ModuleMember = 2623475,
|
||||
ExportHasLocal = 944,
|
||||
@@ -2490,6 +2495,7 @@ declare namespace ts {
|
||||
sourceRoot?: string;
|
||||
strict?: boolean;
|
||||
strictFunctionTypes?: boolean;
|
||||
strictBindCallApply?: boolean;
|
||||
strictNullChecks?: boolean;
|
||||
strictPropertyInitialization?: boolean;
|
||||
stripInternal?: boolean;
|
||||
@@ -2581,7 +2587,6 @@ declare namespace ts {
|
||||
}
|
||||
interface ExpandResult {
|
||||
fileNames: string[];
|
||||
projectReferences: ReadonlyArray<ProjectReference> | undefined;
|
||||
wildcardDirectories: MapLike<WatchDirectoryFlags>;
|
||||
}
|
||||
interface CreateProgramOptions {
|
||||
@@ -2592,14 +2597,6 @@ declare namespace ts {
|
||||
oldProgram?: Program;
|
||||
configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>;
|
||||
}
|
||||
interface UpToDateHost {
|
||||
fileExists(fileName: string): boolean;
|
||||
getModifiedTime(fileName: string): Date | undefined;
|
||||
getUnchangedTime?(fileName: string): Date | undefined;
|
||||
getLastStatus?(fileName: string): UpToDateStatus | undefined;
|
||||
setLastStatus?(fileName: string, status: UpToDateStatus): void;
|
||||
parseConfigFile?(configFilePath: ResolvedConfigFileName): ParsedCommandLine | undefined;
|
||||
}
|
||||
interface ModuleResolutionHost {
|
||||
fileExists(fileName: string): boolean;
|
||||
readFile(fileName: string): string | undefined;
|
||||
@@ -2698,9 +2695,6 @@ declare namespace ts {
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
getEnvironmentVariable?(name: string): string | undefined;
|
||||
createHash?(data: string): string;
|
||||
getModifiedTime?(fileName: string): Date | undefined;
|
||||
setModifiedTime?(fileName: string, date: Date): void;
|
||||
deleteFile?(fileName: string): void;
|
||||
}
|
||||
interface SourceMapRange extends TextRange {
|
||||
source?: SourceMapSource;
|
||||
@@ -3001,6 +2995,16 @@ declare namespace ts {
|
||||
Parameters = 1296,
|
||||
IndexSignatureParameters = 4432
|
||||
}
|
||||
interface UserPreferences {
|
||||
readonly disableSuggestions?: boolean;
|
||||
readonly quotePreference?: "double" | "single";
|
||||
readonly includeCompletionsForModuleExports?: boolean;
|
||||
readonly includeCompletionsWithInsertText?: boolean;
|
||||
readonly importModuleSpecifierPreference?: "relative" | "non-relative";
|
||||
/** Determines whether we import `foo/index.ts` as "foo", "foo/index", or "foo/index.js" */
|
||||
readonly importModuleSpecifierEnding?: "minimal" | "index" | "js";
|
||||
readonly allowTextChangesInNewFiles?: boolean;
|
||||
}
|
||||
}
|
||||
declare function setTimeout(handler: (...args: any[]) => void, timeout: number): any;
|
||||
declare function clearTimeout(handle: any): void;
|
||||
@@ -3209,17 +3213,27 @@ declare namespace ts {
|
||||
/**
|
||||
* Gets the JSDoc parameter tags for the node if present.
|
||||
*
|
||||
* @remarks Returns any JSDoc param tag that matches the provided
|
||||
* @remarks Returns any JSDoc param tag whose name matches the provided
|
||||
* parameter, whether a param tag on a containing function
|
||||
* expression, or a param tag on a variable declaration whose
|
||||
* initializer is the containing function. The tags closest to the
|
||||
* node are returned first, so in the previous example, the param
|
||||
* tag on the containing function expression would be first.
|
||||
*
|
||||
* Does not return tags for binding patterns, because JSDoc matches
|
||||
* parameters by name and binding patterns do not have a name.
|
||||
* For binding patterns, parameter tags are matched by position.
|
||||
*/
|
||||
function getJSDocParameterTags(param: ParameterDeclaration): ReadonlyArray<JSDocParameterTag>;
|
||||
/**
|
||||
* Gets the JSDoc type parameter tags for the node if present.
|
||||
*
|
||||
* @remarks Returns any JSDoc template tag whose names match the provided
|
||||
* parameter, whether a template tag on a containing function
|
||||
* expression, or a template tag on a variable declaration whose
|
||||
* initializer is the containing function. The tags closest to the
|
||||
* node are returned first, so in the previous example, the template
|
||||
* tag on the containing function expression would be first.
|
||||
*/
|
||||
function getJSDocTypeParameterTags(param: TypeParameterDeclaration): ReadonlyArray<JSDocTemplateTag>;
|
||||
/**
|
||||
* Return true if the node has JSDoc parameter tags.
|
||||
*
|
||||
@@ -4171,14 +4185,15 @@ declare namespace ts {
|
||||
* @returns A 'Program' object.
|
||||
*/
|
||||
function createProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): Program;
|
||||
interface ResolveProjectReferencePathHost {
|
||||
/** @deprecated */ interface ResolveProjectReferencePathHost {
|
||||
fileExists(fileName: string): boolean;
|
||||
}
|
||||
/**
|
||||
* Returns the target config filename of a project reference.
|
||||
* Note: The file might not exist.
|
||||
*/
|
||||
function resolveProjectReferencePath(host: ResolveProjectReferencePathHost, ref: ProjectReference): ResolvedConfigFileName;
|
||||
function resolveProjectReferencePath(ref: ProjectReference): ResolvedConfigFileName;
|
||||
/** @deprecated */ function resolveProjectReferencePath(host: ResolveProjectReferencePathHost, ref: ProjectReference): ResolvedConfigFileName;
|
||||
}
|
||||
declare namespace ts {
|
||||
interface EmitOutput {
|
||||
@@ -4303,32 +4318,43 @@ declare namespace ts {
|
||||
* Create the builder to manage semantic diagnostics and cache them
|
||||
*/
|
||||
function createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): SemanticDiagnosticsBuilderProgram;
|
||||
function createSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): SemanticDiagnosticsBuilderProgram;
|
||||
function createSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>, projectReferences?: ReadonlyArray<ProjectReference>): SemanticDiagnosticsBuilderProgram;
|
||||
/**
|
||||
* Create the builder that can handle the changes in program and iterate through changed files
|
||||
* to emit the those files and manage semantic diagnostics cache as well
|
||||
*/
|
||||
function createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): EmitAndSemanticDiagnosticsBuilderProgram;
|
||||
function createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): EmitAndSemanticDiagnosticsBuilderProgram;
|
||||
function createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>, projectReferences?: ReadonlyArray<ProjectReference>): EmitAndSemanticDiagnosticsBuilderProgram;
|
||||
/**
|
||||
* Creates a builder thats just abstraction over program and can be used with watch
|
||||
*/
|
||||
function createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): BuilderProgram;
|
||||
function createAbstractBuilder(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): BuilderProgram;
|
||||
function createAbstractBuilder(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>, projectReferences?: ReadonlyArray<ProjectReference>): BuilderProgram;
|
||||
}
|
||||
declare namespace ts {
|
||||
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 */
|
||||
type CreateProgram<T extends BuilderProgram> = (rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: T, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>) => T;
|
||||
interface WatchCompilerHost<T extends BuilderProgram> {
|
||||
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 */
|
||||
interface WatchHost {
|
||||
/** If provided, called with Diagnostic message that informs about change in watch status */
|
||||
onWatchStatusChange?(diagnostic: Diagnostic, newLine: string, options: CompilerOptions): void;
|
||||
/** Used to watch changes in source files, missing files needed to update the program or config file */
|
||||
watchFile(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher;
|
||||
/** Used to watch resolved module's failed lookup locations, config file specs, type roots where auto type reference directives are added */
|
||||
watchDirectory(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
|
||||
/** If provided, will be used to set delayed compilation, so that multiple changes in short span are compiled together */
|
||||
setTimeout?(callback: (...args: any[]) => void, ms: number, ...args: any[]): any;
|
||||
/** If provided, will be used to reset existing delayed compilation */
|
||||
clearTimeout?(timeoutId: any): void;
|
||||
}
|
||||
interface WatchCompilerHost<T extends BuilderProgram> extends WatchHost {
|
||||
/**
|
||||
* Used to create the program when need for program creation or recreation detected
|
||||
*/
|
||||
createProgram: CreateProgram<T>;
|
||||
/** If provided, callback to invoke after every new program creation */
|
||||
afterProgramCreate?(program: T): void;
|
||||
/** If provided, called with Diagnostic message that informs about change in watch status */
|
||||
onWatchStatusChange?(diagnostic: Diagnostic, newLine: string, options: CompilerOptions): void;
|
||||
useCaseSensitiveFileNames(): boolean;
|
||||
getNewLine(): string;
|
||||
getCurrentDirectory(): string;
|
||||
@@ -4361,14 +4387,6 @@ declare namespace ts {
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[];
|
||||
/** If provided, used to resolve type reference directives, otherwise typescript's default resolution */
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
/** Used to watch changes in source files, missing files needed to update the program or config file */
|
||||
watchFile(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher;
|
||||
/** Used to watch resolved module's failed lookup locations, config file specs, type roots where auto type reference directives are added */
|
||||
watchDirectory(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
|
||||
/** If provided, will be used to set delayed compilation, so that multiple changes in short span are compiled together */
|
||||
setTimeout?(callback: (...args: any[]) => void, ms: number, ...args: any[]): any;
|
||||
/** If provided, will be used to reset existing delayed compilation */
|
||||
clearTimeout?(timeoutId: any): void;
|
||||
}
|
||||
/**
|
||||
* Host to create watch with root files and options
|
||||
@@ -4378,6 +4396,8 @@ declare namespace ts {
|
||||
rootFiles: string[];
|
||||
/** Compiler options */
|
||||
options: CompilerOptions;
|
||||
/** Project References */
|
||||
projectReferences?: ReadonlyArray<ProjectReference>;
|
||||
}
|
||||
/**
|
||||
* Host to create watch with config file
|
||||
@@ -4412,8 +4432,8 @@ declare namespace ts {
|
||||
/**
|
||||
* Create the watch compiler host for either configFile or fileNames and its options
|
||||
*/
|
||||
function createWatchCompilerHost<T extends BuilderProgram>(rootFiles: string[], options: CompilerOptions, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfFilesAndCompilerOptions<T>;
|
||||
function createWatchCompilerHost<T extends BuilderProgram>(configFileName: string, optionsToExtend: CompilerOptions | undefined, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfConfigFile<T>;
|
||||
function createWatchCompilerHost<T extends BuilderProgram>(rootFiles: string[], options: CompilerOptions, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter, projectReferences?: ReadonlyArray<ProjectReference>): WatchCompilerHostOfFilesAndCompilerOptions<T>;
|
||||
/**
|
||||
* Creates the watch from the host for root files and compiler options
|
||||
*/
|
||||
@@ -4423,184 +4443,11 @@ declare namespace ts {
|
||||
*/
|
||||
function createWatchProgram<T extends BuilderProgram>(host: WatchCompilerHostOfConfigFile<T>): WatchOfConfigFile<T>;
|
||||
}
|
||||
declare namespace ts {
|
||||
interface BuildHost {
|
||||
verbose(diag: DiagnosticMessage, ...args: string[]): void;
|
||||
error(diag: DiagnosticMessage, ...args: string[]): void;
|
||||
errorDiagnostic(diag: Diagnostic): void;
|
||||
message(diag: DiagnosticMessage, ...args: string[]): void;
|
||||
}
|
||||
/**
|
||||
* A BuildContext tracks what's going on during the course of a build.
|
||||
*
|
||||
* Callers may invoke any number of build requests within the same context;
|
||||
* until the context is reset, each project will only be built at most once.
|
||||
*
|
||||
* Example: In a standard setup where project B depends on project A, and both are out of date,
|
||||
* a failed build of A will result in A remaining out of date. When we try to build
|
||||
* B, we should immediately bail instead of recomputing A's up-to-date status again.
|
||||
*
|
||||
* This also matters for performing fast (i.e. fake) downstream builds of projects
|
||||
* when their upstream .d.ts files haven't changed content (but have newer timestamps)
|
||||
*/
|
||||
interface BuildContext {
|
||||
options: BuildOptions;
|
||||
/**
|
||||
* Map from output file name to its pre-build timestamp
|
||||
*/
|
||||
unchangedOutputs: FileMap<Date>;
|
||||
/**
|
||||
* Map from config file name to up-to-date status
|
||||
*/
|
||||
projectStatus: FileMap<UpToDateStatus>;
|
||||
invalidatedProjects: FileMap<true>;
|
||||
queuedProjects: FileMap<true>;
|
||||
missingRoots: Map<true>;
|
||||
}
|
||||
type Mapper = ReturnType<typeof createDependencyMapper>;
|
||||
interface DependencyGraph {
|
||||
buildQueue: ResolvedConfigFileName[];
|
||||
dependencyMap: Mapper;
|
||||
}
|
||||
interface BuildOptions {
|
||||
dry: boolean;
|
||||
force: boolean;
|
||||
verbose: boolean;
|
||||
}
|
||||
enum UpToDateStatusType {
|
||||
Unbuildable = 0,
|
||||
UpToDate = 1,
|
||||
/**
|
||||
* The project appears out of date because its upstream inputs are newer than its outputs,
|
||||
* but all of its outputs are actually newer than the previous identical outputs of its (.d.ts) inputs.
|
||||
* This means we can Pseudo-build (just touch timestamps), as if we had actually built this project.
|
||||
*/
|
||||
UpToDateWithUpstreamTypes = 2,
|
||||
OutputMissing = 3,
|
||||
OutOfDateWithSelf = 4,
|
||||
OutOfDateWithUpstream = 5,
|
||||
UpstreamOutOfDate = 6,
|
||||
UpstreamBlocked = 7,
|
||||
/**
|
||||
* Projects with no outputs (i.e. "solution" files)
|
||||
*/
|
||||
ContainerOnly = 8
|
||||
}
|
||||
type UpToDateStatus = Status.Unbuildable | Status.UpToDate | Status.OutputMissing | Status.OutOfDateWithSelf | Status.OutOfDateWithUpstream | Status.UpstreamOutOfDate | Status.UpstreamBlocked | Status.ContainerOnly;
|
||||
namespace Status {
|
||||
/**
|
||||
* The project can't be built at all in its current state. For example,
|
||||
* its config file cannot be parsed, or it has a syntax error or missing file
|
||||
*/
|
||||
interface Unbuildable {
|
||||
type: UpToDateStatusType.Unbuildable;
|
||||
reason: string;
|
||||
}
|
||||
/**
|
||||
* This project doesn't have any outputs, so "is it up to date" is a meaningless question.
|
||||
*/
|
||||
interface ContainerOnly {
|
||||
type: UpToDateStatusType.ContainerOnly;
|
||||
}
|
||||
/**
|
||||
* The project is up to date with respect to its inputs.
|
||||
* We track what the newest input file is.
|
||||
*/
|
||||
interface UpToDate {
|
||||
type: UpToDateStatusType.UpToDate | UpToDateStatusType.UpToDateWithUpstreamTypes;
|
||||
newestInputFileTime?: Date;
|
||||
newestInputFileName?: string;
|
||||
newestDeclarationFileContentChangedTime?: Date;
|
||||
newestOutputFileTime?: Date;
|
||||
newestOutputFileName?: string;
|
||||
oldestOutputFileName?: string;
|
||||
}
|
||||
/**
|
||||
* One or more of the outputs of the project does not exist.
|
||||
*/
|
||||
interface OutputMissing {
|
||||
type: UpToDateStatusType.OutputMissing;
|
||||
/**
|
||||
* The name of the first output file that didn't exist
|
||||
*/
|
||||
missingOutputFileName: string;
|
||||
}
|
||||
/**
|
||||
* One or more of the project's outputs is older than its newest input.
|
||||
*/
|
||||
interface OutOfDateWithSelf {
|
||||
type: UpToDateStatusType.OutOfDateWithSelf;
|
||||
outOfDateOutputFileName: string;
|
||||
newerInputFileName: string;
|
||||
}
|
||||
/**
|
||||
* This project depends on an out-of-date project, so shouldn't be built yet
|
||||
*/
|
||||
interface UpstreamOutOfDate {
|
||||
type: UpToDateStatusType.UpstreamOutOfDate;
|
||||
upstreamProjectName: string;
|
||||
}
|
||||
/**
|
||||
* This project depends an upstream project with build errors
|
||||
*/
|
||||
interface UpstreamBlocked {
|
||||
type: UpToDateStatusType.UpstreamBlocked;
|
||||
upstreamProjectName: string;
|
||||
}
|
||||
/**
|
||||
* One or more of the project's outputs is older than the newest output of
|
||||
* an upstream project.
|
||||
*/
|
||||
interface OutOfDateWithUpstream {
|
||||
type: UpToDateStatusType.OutOfDateWithUpstream;
|
||||
outOfDateOutputFileName: string;
|
||||
newerProjectName: string;
|
||||
}
|
||||
}
|
||||
interface FileMap<T> {
|
||||
setValue(fileName: string, value: T): void;
|
||||
getValue(fileName: string): T | never;
|
||||
getValueOrUndefined(fileName: string): T | undefined;
|
||||
hasKey(fileName: string): boolean;
|
||||
removeKey(fileName: string): void;
|
||||
getKeys(): string[];
|
||||
}
|
||||
function createDependencyMapper(): {
|
||||
addReference: (childConfigFileName: ResolvedConfigFileName, parentConfigFileName: ResolvedConfigFileName) => void;
|
||||
getReferencesTo: (parentConfigFileName: ResolvedConfigFileName) => ResolvedConfigFileName[];
|
||||
getReferencesOf: (childConfigFileName: ResolvedConfigFileName) => ResolvedConfigFileName[];
|
||||
getKeys: () => ReadonlyArray<ResolvedConfigFileName>;
|
||||
};
|
||||
function createBuildContext(options: BuildOptions): BuildContext;
|
||||
function performBuild(args: string[], compilerHost: CompilerHost, buildHost: BuildHost, system?: System): number | undefined;
|
||||
/**
|
||||
* A SolutionBuilder has an immutable set of rootNames that are the "entry point" projects, but
|
||||
* can dynamically add/remove other projects based on changes on the rootNames' references
|
||||
*/
|
||||
function createSolutionBuilder(compilerHost: CompilerHost, buildHost: BuildHost, rootNames: ReadonlyArray<string>, defaultOptions: BuildOptions, system?: System): {
|
||||
buildAllProjects: () => ExitStatus;
|
||||
getUpToDateStatus: (project: ParsedCommandLine | undefined) => UpToDateStatus;
|
||||
getUpToDateStatusOfFile: (configFileName: ResolvedConfigFileName) => UpToDateStatus;
|
||||
cleanAllProjects: () => ExitStatus.Success | ExitStatus.DiagnosticsPresent_OutputsSkipped;
|
||||
resetBuildContext: (opts?: BuildOptions) => void;
|
||||
getBuildGraph: (configFileNames: ReadonlyArray<string>) => DependencyGraph | undefined;
|
||||
invalidateProject: (configFileName: string) => void;
|
||||
buildInvalidatedProjects: () => void;
|
||||
buildDependentInvalidatedProjects: () => void;
|
||||
resolveProjectName: (name: string) => ResolvedConfigFileName | undefined;
|
||||
startWatching: () => void;
|
||||
};
|
||||
/**
|
||||
* Gets the UpToDateStatus for a project
|
||||
*/
|
||||
function getUpToDateStatus(host: UpToDateHost, project: ParsedCommandLine | undefined): UpToDateStatus;
|
||||
function getAllProjectOutputs(project: ParsedCommandLine): ReadonlyArray<string>;
|
||||
function formatUpToDateStatus<T>(configFileName: string, status: UpToDateStatus, relName: (fileName: string) => string, formatMessage: (message: DiagnosticMessage, ...args: string[]) => T): T | undefined;
|
||||
}
|
||||
declare namespace ts.server {
|
||||
type ActionSet = "action::set";
|
||||
type ActionInvalidate = "action::invalidate";
|
||||
type ActionPackageInstalled = "action::packageInstalled";
|
||||
type ActionValueInspected = "action::valueInspected";
|
||||
type EventTypesRegistry = "event::typesRegistry";
|
||||
type EventBeginInstallTypes = "event::beginInstallTypes";
|
||||
type EventEndInstallTypes = "event::endInstallTypes";
|
||||
@@ -4609,7 +4456,7 @@ declare namespace ts.server {
|
||||
" __sortedArrayBrand": any;
|
||||
}
|
||||
interface TypingInstallerResponse {
|
||||
readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | ActionPackageInstalled | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed;
|
||||
readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | ActionPackageInstalled | ActionValueInspected | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed;
|
||||
}
|
||||
interface TypingInstallerRequestWithProjectName {
|
||||
readonly projectName: string;
|
||||
@@ -4817,14 +4664,7 @@ declare namespace ts {
|
||||
getCustomTransformers?(): CustomTransformers | undefined;
|
||||
isKnownTypesPackageName?(name: string): boolean;
|
||||
installPackage?(options: InstallPackageOptions): Promise<ApplyCodeActionCommandResult>;
|
||||
}
|
||||
interface UserPreferences {
|
||||
readonly disableSuggestions?: boolean;
|
||||
readonly quotePreference?: "double" | "single";
|
||||
readonly includeCompletionsForModuleExports?: boolean;
|
||||
readonly includeCompletionsWithInsertText?: boolean;
|
||||
readonly importModuleSpecifierPreference?: "relative" | "non-relative";
|
||||
readonly allowTextChangesInNewFiles?: boolean;
|
||||
writeFile?(fileName: string, content: string): void;
|
||||
}
|
||||
interface LanguageService {
|
||||
cleanupSemanticCache(): void;
|
||||
@@ -4882,9 +4722,9 @@ declare namespace ts {
|
||||
toLineColumnOffset?(fileName: string, position: number): LineAndCharacter;
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray<number>, formatOptions: FormatCodeSettings, preferences: UserPreferences): ReadonlyArray<CodeFixAction>;
|
||||
getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: {}, formatOptions: FormatCodeSettings, preferences: UserPreferences): CombinedCodeActions;
|
||||
applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
|
||||
applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
applyCodeActionCommand(action: CodeActionCommand, formatSettings?: FormatCodeSettings): Promise<ApplyCodeActionCommandResult>;
|
||||
applyCodeActionCommand(action: CodeActionCommand[], formatSettings?: FormatCodeSettings): Promise<ApplyCodeActionCommandResult[]>;
|
||||
applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[], formatSettings?: FormatCodeSettings): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
/** @deprecated `fileName` will be ignored */
|
||||
applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
/** @deprecated `fileName` will be ignored */
|
||||
@@ -5046,9 +4886,16 @@ declare namespace ts {
|
||||
changes: ReadonlyArray<FileTextChanges>;
|
||||
commands?: ReadonlyArray<CodeActionCommand>;
|
||||
}
|
||||
type CodeActionCommand = InstallPackageAction;
|
||||
type CodeActionCommand = InstallPackageAction | GenerateTypesAction;
|
||||
interface InstallPackageAction {
|
||||
}
|
||||
interface GenerateTypesAction extends GenerateTypesOptions {
|
||||
}
|
||||
interface GenerateTypesOptions {
|
||||
readonly file: string;
|
||||
readonly fileToGenerateTypesFor: string;
|
||||
readonly outputFileName: string;
|
||||
}
|
||||
/**
|
||||
* A set of one or more available refactoring actions, grouped under a parent refactoring.
|
||||
*/
|
||||
@@ -5114,6 +4961,8 @@ declare namespace ts {
|
||||
originalFileName?: string;
|
||||
}
|
||||
interface RenameLocation extends DocumentSpan {
|
||||
readonly prefixText?: string;
|
||||
readonly suffixText?: string;
|
||||
}
|
||||
interface ReferenceEntry extends DocumentSpan {
|
||||
isWriteAccess: boolean;
|
||||
@@ -5266,15 +5115,24 @@ declare namespace ts {
|
||||
documentation?: SymbolDisplayPart[];
|
||||
tags?: JSDocTagInfo[];
|
||||
}
|
||||
interface RenameInfo {
|
||||
canRename: boolean;
|
||||
localizedErrorMessage?: string;
|
||||
type RenameInfo = RenameInfoSuccess | RenameInfoFailure;
|
||||
interface RenameInfoSuccess {
|
||||
canRename: true;
|
||||
/**
|
||||
* File or directory to rename.
|
||||
* If set, `getEditsForFileRename` should be called instead of `findRenameLocations`.
|
||||
*/
|
||||
fileToRename?: string;
|
||||
displayName: string;
|
||||
fullDisplayName: string;
|
||||
kind: ScriptElementKind;
|
||||
kindModifiers: string;
|
||||
triggerSpan: TextSpan;
|
||||
}
|
||||
interface RenameInfoFailure {
|
||||
canRename: false;
|
||||
localizedErrorMessage: string;
|
||||
}
|
||||
interface SignatureHelpParameter {
|
||||
name: string;
|
||||
documentation: SymbolDisplayPart[];
|
||||
@@ -5751,24 +5609,6 @@ declare namespace ts.server {
|
||||
remove(path: NormalizedPath): void;
|
||||
}
|
||||
function createNormalizedPathMap<T>(): NormalizedPathMap<T>;
|
||||
interface ProjectOptions {
|
||||
configHasExtendsProperty: boolean;
|
||||
/**
|
||||
* true if config file explicitly listed files
|
||||
*/
|
||||
configHasFilesProperty: boolean;
|
||||
configHasIncludeProperty: boolean;
|
||||
configHasExcludeProperty: boolean;
|
||||
projectReferences: ReadonlyArray<ProjectReference> | undefined;
|
||||
/**
|
||||
* these fields can be present in the project file
|
||||
*/
|
||||
files?: string[];
|
||||
wildcardDirectories?: Map<WatchDirectoryFlags>;
|
||||
compilerOptions?: CompilerOptions;
|
||||
typeAcquisition?: TypeAcquisition;
|
||||
compileOnSave?: boolean;
|
||||
}
|
||||
function isInferredProjectName(name: string): boolean;
|
||||
function makeInferredProjectName(counter: number): string;
|
||||
function createSortedArray<T>(): SortedArray<T>;
|
||||
@@ -6602,15 +6442,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.
|
||||
*/
|
||||
@@ -6627,6 +6469,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'.
|
||||
@@ -6635,7 +6486,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 {
|
||||
/**
|
||||
@@ -7148,7 +7003,7 @@ declare namespace ts.server.protocol {
|
||||
* begin with prefix.
|
||||
*/
|
||||
interface CompletionsRequest extends FileLocationRequest {
|
||||
command: CommandTypes.Completions;
|
||||
command: CommandTypes.Completions | CommandTypes.CompletionInfo;
|
||||
arguments: CompletionsRequestArgs;
|
||||
}
|
||||
/**
|
||||
@@ -7660,6 +7515,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;
|
||||
@@ -7995,6 +7879,7 @@ declare namespace ts.server.protocol {
|
||||
readonly includeCompletionsWithInsertText?: boolean;
|
||||
readonly importModuleSpecifierPreference?: "relative" | "non-relative";
|
||||
readonly allowTextChangesInNewFiles?: boolean;
|
||||
readonly lazyConfiguredProjectsFromExternalProject?: boolean;
|
||||
}
|
||||
interface CompilerOptions {
|
||||
allowJs?: boolean;
|
||||
@@ -8126,14 +8011,14 @@ declare namespace ts.server {
|
||||
getSnapshot(): IScriptSnapshot;
|
||||
private ensureRealPath;
|
||||
getFormatCodeSettings(): FormatCodeSettings | undefined;
|
||||
getPreferences(): UserPreferences | undefined;
|
||||
getPreferences(): protocol.UserPreferences | undefined;
|
||||
attachToProject(project: Project): boolean;
|
||||
isAttached(project: Project): boolean;
|
||||
detachFromProject(project: Project): void;
|
||||
detachAllProjects(): void;
|
||||
getDefaultProject(): Project;
|
||||
registerFileUpdate(): void;
|
||||
setOptions(formatSettings: FormatCodeSettings, preferences: UserPreferences | undefined): void;
|
||||
setOptions(formatSettings: FormatCodeSettings, preferences: protocol.UserPreferences | undefined): void;
|
||||
getLatestVersion(): string;
|
||||
saveTo(fileName: string): void;
|
||||
reloadFromFile(tempFileName?: NormalizedPath): boolean;
|
||||
@@ -8238,6 +8123,7 @@ declare namespace ts.server {
|
||||
* This property is different from projectStructureVersion since in most cases edits don't affect set of files in the project
|
||||
*/
|
||||
private projectStateVersion;
|
||||
protected isInitialLoadPending: () => boolean;
|
||||
private readonly cancellationToken;
|
||||
isNonTsProject(): boolean;
|
||||
isJsOnlyProject(): boolean;
|
||||
@@ -8261,6 +8147,7 @@ declare namespace ts.server {
|
||||
useCaseSensitiveFileNames(): boolean;
|
||||
readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];
|
||||
readFile(fileName: string): string | undefined;
|
||||
writeFile(fileName: string, content: string): void;
|
||||
fileExists(file: string): boolean;
|
||||
resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModuleFull[];
|
||||
getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations | undefined;
|
||||
@@ -8322,7 +8209,7 @@ declare namespace ts.server {
|
||||
filesToString(writeProjectFileNames: boolean): string;
|
||||
setCompilerOptions(compilerOptions: CompilerOptions): void;
|
||||
protected removeRoot(info: ScriptInfo): void;
|
||||
protected enableGlobalPlugins(): void;
|
||||
protected enableGlobalPlugins(options: CompilerOptions): void;
|
||||
protected enablePlugin(pluginConfigEntry: PluginImport, searchPaths: string[]): void;
|
||||
/** Starts a new check for diagnostics. Call this if some file has updated that would cause diagnostics to be changed. */
|
||||
refreshDiagnostics(): void;
|
||||
@@ -8351,14 +8238,14 @@ declare namespace ts.server {
|
||||
* Otherwise it will create an InferredProject.
|
||||
*/
|
||||
class ConfiguredProject extends Project {
|
||||
compileOnSaveEnabled: boolean;
|
||||
private projectReferences;
|
||||
private typeAcquisition;
|
||||
private directoriesWatchedForWildcards;
|
||||
readonly canonicalConfigFilePath: NormalizedPath;
|
||||
/** Ref count to the project when opened from external project */
|
||||
private externalProjectRefCount;
|
||||
private projectErrors;
|
||||
private projectReferences;
|
||||
protected isInitialLoadPending: () => boolean;
|
||||
/**
|
||||
* If the project has reload from disk pending, it reloads (and then updates graph as part of that) instead of just updating the graph
|
||||
* @returns: true if set of files in the project stays the same and false - otherwise.
|
||||
@@ -8391,6 +8278,7 @@ declare namespace ts.server {
|
||||
compileOnSaveEnabled: boolean;
|
||||
excludedFiles: ReadonlyArray<NormalizedPath>;
|
||||
private typeAcquisition;
|
||||
updateGraph(): boolean;
|
||||
getExcludedFiles(): ReadonlyArray<NormalizedPath>;
|
||||
getTypeAcquisition(): TypeAcquisition;
|
||||
setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void;
|
||||
@@ -8399,6 +8287,9 @@ declare namespace ts.server {
|
||||
declare namespace ts.server {
|
||||
const maxProgramSizeForNonTsFiles: number;
|
||||
const ProjectsUpdatedInBackgroundEvent = "projectsUpdatedInBackground";
|
||||
const ProjectLoadingStartEvent = "projectLoadingStart";
|
||||
const ProjectLoadingFinishEvent = "projectLoadingFinish";
|
||||
const SurveyReady = "surveyReady";
|
||||
const LargeFileReferencedEvent = "largeFileReferenced";
|
||||
const ConfigFileDiagEvent = "configFileDiag";
|
||||
const ProjectLanguageServiceStateEvent = "projectLanguageServiceState";
|
||||
@@ -8410,6 +8301,25 @@ declare namespace ts.server {
|
||||
openFiles: string[];
|
||||
};
|
||||
}
|
||||
interface ProjectLoadingStartEvent {
|
||||
eventName: typeof ProjectLoadingStartEvent;
|
||||
data: {
|
||||
project: Project;
|
||||
reason: string;
|
||||
};
|
||||
}
|
||||
interface ProjectLoadingFinishEvent {
|
||||
eventName: typeof ProjectLoadingFinishEvent;
|
||||
data: {
|
||||
project: Project;
|
||||
};
|
||||
}
|
||||
interface SurveyReady {
|
||||
eventName: typeof SurveyReady;
|
||||
data: {
|
||||
surveyId: string;
|
||||
};
|
||||
}
|
||||
interface LargeFileReferencedEvent {
|
||||
eventName: typeof LargeFileReferencedEvent;
|
||||
data: {
|
||||
@@ -8488,7 +8398,7 @@ declare namespace ts.server {
|
||||
interface OpenFileInfo {
|
||||
readonly checkJs: boolean;
|
||||
}
|
||||
type ProjectServiceEvent = LargeFileReferencedEvent | ProjectsUpdatedInBackgroundEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent | OpenFileInfoTelemetryEvent;
|
||||
type ProjectServiceEvent = LargeFileReferencedEvent | SurveyReady | ProjectsUpdatedInBackgroundEvent | ProjectLoadingStartEvent | ProjectLoadingFinishEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent | OpenFileInfoTelemetryEvent;
|
||||
type ProjectServiceEventHandler = (event: ProjectServiceEvent) => void;
|
||||
interface SafeList {
|
||||
[name: string]: {
|
||||
@@ -8509,7 +8419,7 @@ declare namespace ts.server {
|
||||
function convertScriptKindName(scriptKindName: protocol.ScriptKindName): ScriptKind.Unknown | ScriptKind.JS | ScriptKind.JSX | ScriptKind.TS | ScriptKind.TSX;
|
||||
interface HostConfiguration {
|
||||
formatCodeOptions: FormatCodeSettings;
|
||||
preferences: UserPreferences;
|
||||
preferences: protocol.UserPreferences;
|
||||
hostInfo: string;
|
||||
extraFileExtensions?: FileExtensionInfo[];
|
||||
}
|
||||
@@ -8538,6 +8448,7 @@ declare namespace ts.server {
|
||||
* Container of all known scripts
|
||||
*/
|
||||
private readonly filenameToScriptInfo;
|
||||
private readonly scriptInfoInNodeModulesWatchers;
|
||||
/**
|
||||
* Contains all the deleted script info's version information so that
|
||||
* it does not reset when creating script info again
|
||||
@@ -8586,7 +8497,7 @@ declare namespace ts.server {
|
||||
private readonly throttledOperations;
|
||||
private readonly hostConfiguration;
|
||||
private safelist;
|
||||
private legacySafelist;
|
||||
private readonly legacySafelist;
|
||||
private pendingProjectUpdates;
|
||||
readonly currentDirectory: NormalizedPath;
|
||||
readonly toCanonicalFileName: (f: string) => string;
|
||||
@@ -8607,6 +8518,8 @@ declare namespace ts.server {
|
||||
readonly syntaxOnly?: boolean;
|
||||
/** Tracks projects that we have already sent telemetry for. */
|
||||
private readonly seenProjects;
|
||||
/** Tracks projects that we have already sent survey events for. */
|
||||
private readonly seenSurveyProjects;
|
||||
constructor(opts: ProjectServiceOptions);
|
||||
toPath(fileName: string): Path;
|
||||
private loadTypesMap;
|
||||
@@ -8628,9 +8541,9 @@ declare namespace ts.server {
|
||||
*/
|
||||
private ensureProjectStructuresUptoDate;
|
||||
getFormatCodeOptions(file: NormalizedPath): FormatCodeSettings;
|
||||
getPreferences(file: NormalizedPath): UserPreferences;
|
||||
getPreferences(file: NormalizedPath): protocol.UserPreferences;
|
||||
getHostFormatCodeOptions(): FormatCodeSettings;
|
||||
getHostPreferences(): UserPreferences;
|
||||
getHostPreferences(): protocol.UserPreferences;
|
||||
private onSourceFileChanged;
|
||||
private handleDeletedFile;
|
||||
private onConfigChangedForConfiguredProject;
|
||||
@@ -8692,15 +8605,13 @@ declare namespace ts.server {
|
||||
private findConfiguredProjectByProjectName;
|
||||
private getConfiguredProjectByCanonicalConfigFilePath;
|
||||
private findExternalProjectByProjectName;
|
||||
private convertConfigFileContentToProjectOptions;
|
||||
/** Get a filename if the language service exceeds the maximum allowed program size; otherwise returns undefined. */
|
||||
private getFilenameForExceededTotalSizeLimitForNonTsFiles;
|
||||
private createExternalProject;
|
||||
private sendProjectTelemetry;
|
||||
private addFilesToNonInferredProjectAndUpdateGraph;
|
||||
private addFilesToNonInferredProject;
|
||||
private createConfiguredProject;
|
||||
private updateNonInferredProjectFiles;
|
||||
private updateNonInferredProject;
|
||||
private updateRootAndOptionsOfNonInferredProject;
|
||||
private sendConfigFileDiagEvent;
|
||||
private getOrCreateInferredProjectForProjectRootPathIfEnabled;
|
||||
private getOrCreateSingleInferredProjectIfEnabled;
|
||||
@@ -8708,6 +8619,10 @@ declare namespace ts.server {
|
||||
private createInferredProject;
|
||||
getScriptInfo(uncheckedFileName: string): ScriptInfo | undefined;
|
||||
private watchClosedScriptInfo;
|
||||
private watchClosedScriptInfoInNodeModules;
|
||||
private getModifiedTime;
|
||||
private refreshScriptInfo;
|
||||
private refreshScriptInfosInDirectory;
|
||||
private stopWatchingScriptInfo;
|
||||
private getOrCreateScriptInfoNotOpenedByClientForNormalizedPath;
|
||||
private getOrCreateScriptInfoOpenedByClientForNormalizedPath;
|
||||
@@ -8815,6 +8730,7 @@ declare namespace ts.server {
|
||||
globalPlugins?: ReadonlyArray<string>;
|
||||
pluginProbeLocations?: ReadonlyArray<string>;
|
||||
allowLocalPluginLoads?: boolean;
|
||||
typesMapLocation?: string;
|
||||
}
|
||||
class Session implements EventSender {
|
||||
private readonly gcTimer;
|
||||
@@ -8837,6 +8753,7 @@ declare namespace ts.server {
|
||||
private defaultEventHandler;
|
||||
private projectsUpdatedInBackgroundEvent;
|
||||
logError(err: Error, cmd: string): void;
|
||||
private logErrorWorker;
|
||||
send(msg: protocol.Message): void;
|
||||
event<T extends object>(body: T, eventName: string): void;
|
||||
/** @deprecated */
|
||||
@@ -8881,7 +8798,7 @@ declare namespace ts.server {
|
||||
private getProjects;
|
||||
private getDefaultProject;
|
||||
private getRenameLocations;
|
||||
private static mapRenameInfo;
|
||||
private mapRenameInfo;
|
||||
private toSpanGroups;
|
||||
private getReferences;
|
||||
/**
|
||||
|
||||
+7653
-4620
File diff suppressed because it is too large
Load Diff
Vendored
+99
-241
@@ -14,7 +14,7 @@ and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
declare namespace ts {
|
||||
const versionMajorMinor = "3.1";
|
||||
const versionMajorMinor = "3.2";
|
||||
/** The version of the TypeScript compiler release */
|
||||
const version: string;
|
||||
}
|
||||
@@ -69,7 +69,8 @@ declare namespace ts {
|
||||
pos: number;
|
||||
end: number;
|
||||
}
|
||||
type JsDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.NoSubstitutionTemplateLiteral | SyntaxKind.Unknown;
|
||||
type JsDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.NoSubstitutionTemplateLiteral | SyntaxKind.Unknown | KeywordSyntaxKind;
|
||||
type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InKeyword | SyntaxKind.InferKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.OfKeyword;
|
||||
type JsxTokenSyntaxKind = SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken;
|
||||
enum SyntaxKind {
|
||||
Unknown = 0,
|
||||
@@ -536,6 +537,7 @@ declare namespace ts {
|
||||
name?: Identifier | StringLiteral | NumericLiteral;
|
||||
}
|
||||
interface ComputedPropertyName extends Node {
|
||||
parent: Declaration;
|
||||
kind: SyntaxKind.ComputedPropertyName;
|
||||
expression: Expression;
|
||||
}
|
||||
@@ -632,6 +634,7 @@ declare namespace ts {
|
||||
kind: SyntaxKind.ShorthandPropertyAssignment;
|
||||
name: Identifier;
|
||||
questionToken?: QuestionToken;
|
||||
exclamationToken?: ExclamationToken;
|
||||
equalsToken?: Token<SyntaxKind.EqualsToken>;
|
||||
objectAssignmentInitializer?: Expression;
|
||||
}
|
||||
@@ -668,6 +671,7 @@ declare namespace ts {
|
||||
_functionLikeDeclarationBrand: any;
|
||||
asteriskToken?: AsteriskToken;
|
||||
questionToken?: QuestionToken;
|
||||
exclamationToken?: ExclamationToken;
|
||||
body?: Block | Expression;
|
||||
}
|
||||
type FunctionLikeDeclaration = FunctionDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration | FunctionExpression | ArrowFunction;
|
||||
@@ -1079,7 +1083,7 @@ declare namespace ts {
|
||||
}
|
||||
interface ExpressionWithTypeArguments extends NodeWithTypeArguments {
|
||||
kind: SyntaxKind.ExpressionWithTypeArguments;
|
||||
parent: HeritageClause;
|
||||
parent: HeritageClause | JSDocAugmentsTag;
|
||||
expression: LeftHandSideExpression;
|
||||
}
|
||||
interface NewExpression extends PrimaryExpression, Declaration {
|
||||
@@ -1808,7 +1812,8 @@ declare namespace ts {
|
||||
getTypeChecker(): TypeChecker;
|
||||
isSourceFileFromExternalLibrary(file: SourceFile): boolean;
|
||||
isSourceFileDefaultLibrary(file: SourceFile): boolean;
|
||||
getProjectReferences(): (ResolvedProjectReference | undefined)[] | undefined;
|
||||
getProjectReferences(): ReadonlyArray<ProjectReference> | undefined;
|
||||
getResolvedProjectReferences(): (ResolvedProjectReference | undefined)[] | undefined;
|
||||
}
|
||||
interface ResolvedProjectReference {
|
||||
commandLine: ParsedCommandLine;
|
||||
@@ -2056,32 +2061,32 @@ declare namespace ts {
|
||||
ExportStar = 8388608,
|
||||
Optional = 16777216,
|
||||
Transient = 33554432,
|
||||
JSContainer = 67108864,
|
||||
Assignment = 67108864,
|
||||
ModuleExports = 134217728,
|
||||
Enum = 384,
|
||||
Variable = 3,
|
||||
Value = 67216319,
|
||||
Type = 67901928,
|
||||
Value = 67220415,
|
||||
Type = 67897832,
|
||||
Namespace = 1920,
|
||||
Module = 1536,
|
||||
Accessor = 98304,
|
||||
FunctionScopedVariableExcludes = 67216318,
|
||||
BlockScopedVariableExcludes = 67216319,
|
||||
ParameterExcludes = 67216319,
|
||||
FunctionScopedVariableExcludes = 67220414,
|
||||
BlockScopedVariableExcludes = 67220415,
|
||||
ParameterExcludes = 67220415,
|
||||
PropertyExcludes = 0,
|
||||
EnumMemberExcludes = 68008959,
|
||||
FunctionExcludes = 67215791,
|
||||
FunctionExcludes = 67219887,
|
||||
ClassExcludes = 68008383,
|
||||
InterfaceExcludes = 67901832,
|
||||
InterfaceExcludes = 67897736,
|
||||
RegularEnumExcludes = 68008191,
|
||||
ConstEnumExcludes = 68008831,
|
||||
ValueModuleExcludes = 67215503,
|
||||
ValueModuleExcludes = 110735,
|
||||
NamespaceModuleExcludes = 0,
|
||||
MethodExcludes = 67208127,
|
||||
GetAccessorExcludes = 67150783,
|
||||
SetAccessorExcludes = 67183551,
|
||||
TypeParameterExcludes = 67639784,
|
||||
TypeAliasExcludes = 67901928,
|
||||
MethodExcludes = 67212223,
|
||||
GetAccessorExcludes = 67154879,
|
||||
SetAccessorExcludes = 67187647,
|
||||
TypeParameterExcludes = 67635688,
|
||||
TypeAliasExcludes = 67897832,
|
||||
AliasExcludes = 2097152,
|
||||
ModuleMember = 2623475,
|
||||
ExportHasLocal = 944,
|
||||
@@ -2490,6 +2495,7 @@ declare namespace ts {
|
||||
sourceRoot?: string;
|
||||
strict?: boolean;
|
||||
strictFunctionTypes?: boolean;
|
||||
strictBindCallApply?: boolean;
|
||||
strictNullChecks?: boolean;
|
||||
strictPropertyInitialization?: boolean;
|
||||
stripInternal?: boolean;
|
||||
@@ -2581,7 +2587,6 @@ declare namespace ts {
|
||||
}
|
||||
interface ExpandResult {
|
||||
fileNames: string[];
|
||||
projectReferences: ReadonlyArray<ProjectReference> | undefined;
|
||||
wildcardDirectories: MapLike<WatchDirectoryFlags>;
|
||||
}
|
||||
interface CreateProgramOptions {
|
||||
@@ -2592,14 +2597,6 @@ declare namespace ts {
|
||||
oldProgram?: Program;
|
||||
configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>;
|
||||
}
|
||||
interface UpToDateHost {
|
||||
fileExists(fileName: string): boolean;
|
||||
getModifiedTime(fileName: string): Date | undefined;
|
||||
getUnchangedTime?(fileName: string): Date | undefined;
|
||||
getLastStatus?(fileName: string): UpToDateStatus | undefined;
|
||||
setLastStatus?(fileName: string, status: UpToDateStatus): void;
|
||||
parseConfigFile?(configFilePath: ResolvedConfigFileName): ParsedCommandLine | undefined;
|
||||
}
|
||||
interface ModuleResolutionHost {
|
||||
fileExists(fileName: string): boolean;
|
||||
readFile(fileName: string): string | undefined;
|
||||
@@ -2698,9 +2695,6 @@ declare namespace ts {
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
getEnvironmentVariable?(name: string): string | undefined;
|
||||
createHash?(data: string): string;
|
||||
getModifiedTime?(fileName: string): Date | undefined;
|
||||
setModifiedTime?(fileName: string, date: Date): void;
|
||||
deleteFile?(fileName: string): void;
|
||||
}
|
||||
interface SourceMapRange extends TextRange {
|
||||
source?: SourceMapSource;
|
||||
@@ -3001,6 +2995,16 @@ declare namespace ts {
|
||||
Parameters = 1296,
|
||||
IndexSignatureParameters = 4432
|
||||
}
|
||||
interface UserPreferences {
|
||||
readonly disableSuggestions?: boolean;
|
||||
readonly quotePreference?: "double" | "single";
|
||||
readonly includeCompletionsForModuleExports?: boolean;
|
||||
readonly includeCompletionsWithInsertText?: boolean;
|
||||
readonly importModuleSpecifierPreference?: "relative" | "non-relative";
|
||||
/** Determines whether we import `foo/index.ts` as "foo", "foo/index", or "foo/index.js" */
|
||||
readonly importModuleSpecifierEnding?: "minimal" | "index" | "js";
|
||||
readonly allowTextChangesInNewFiles?: boolean;
|
||||
}
|
||||
}
|
||||
declare function setTimeout(handler: (...args: any[]) => void, timeout: number): any;
|
||||
declare function clearTimeout(handle: any): void;
|
||||
@@ -3209,17 +3213,27 @@ declare namespace ts {
|
||||
/**
|
||||
* Gets the JSDoc parameter tags for the node if present.
|
||||
*
|
||||
* @remarks Returns any JSDoc param tag that matches the provided
|
||||
* @remarks Returns any JSDoc param tag whose name matches the provided
|
||||
* parameter, whether a param tag on a containing function
|
||||
* expression, or a param tag on a variable declaration whose
|
||||
* initializer is the containing function. The tags closest to the
|
||||
* node are returned first, so in the previous example, the param
|
||||
* tag on the containing function expression would be first.
|
||||
*
|
||||
* Does not return tags for binding patterns, because JSDoc matches
|
||||
* parameters by name and binding patterns do not have a name.
|
||||
* For binding patterns, parameter tags are matched by position.
|
||||
*/
|
||||
function getJSDocParameterTags(param: ParameterDeclaration): ReadonlyArray<JSDocParameterTag>;
|
||||
/**
|
||||
* Gets the JSDoc type parameter tags for the node if present.
|
||||
*
|
||||
* @remarks Returns any JSDoc template tag whose names match the provided
|
||||
* parameter, whether a template tag on a containing function
|
||||
* expression, or a template tag on a variable declaration whose
|
||||
* initializer is the containing function. The tags closest to the
|
||||
* node are returned first, so in the previous example, the template
|
||||
* tag on the containing function expression would be first.
|
||||
*/
|
||||
function getJSDocTypeParameterTags(param: TypeParameterDeclaration): ReadonlyArray<JSDocTemplateTag>;
|
||||
/**
|
||||
* Return true if the node has JSDoc parameter tags.
|
||||
*
|
||||
@@ -4171,14 +4185,15 @@ declare namespace ts {
|
||||
* @returns A 'Program' object.
|
||||
*/
|
||||
function createProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): Program;
|
||||
interface ResolveProjectReferencePathHost {
|
||||
/** @deprecated */ interface ResolveProjectReferencePathHost {
|
||||
fileExists(fileName: string): boolean;
|
||||
}
|
||||
/**
|
||||
* Returns the target config filename of a project reference.
|
||||
* Note: The file might not exist.
|
||||
*/
|
||||
function resolveProjectReferencePath(host: ResolveProjectReferencePathHost, ref: ProjectReference): ResolvedConfigFileName;
|
||||
function resolveProjectReferencePath(ref: ProjectReference): ResolvedConfigFileName;
|
||||
/** @deprecated */ function resolveProjectReferencePath(host: ResolveProjectReferencePathHost, ref: ProjectReference): ResolvedConfigFileName;
|
||||
}
|
||||
declare namespace ts {
|
||||
interface EmitOutput {
|
||||
@@ -4303,32 +4318,43 @@ declare namespace ts {
|
||||
* Create the builder to manage semantic diagnostics and cache them
|
||||
*/
|
||||
function createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): SemanticDiagnosticsBuilderProgram;
|
||||
function createSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): SemanticDiagnosticsBuilderProgram;
|
||||
function createSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>, projectReferences?: ReadonlyArray<ProjectReference>): SemanticDiagnosticsBuilderProgram;
|
||||
/**
|
||||
* Create the builder that can handle the changes in program and iterate through changed files
|
||||
* to emit the those files and manage semantic diagnostics cache as well
|
||||
*/
|
||||
function createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): EmitAndSemanticDiagnosticsBuilderProgram;
|
||||
function createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): EmitAndSemanticDiagnosticsBuilderProgram;
|
||||
function createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>, projectReferences?: ReadonlyArray<ProjectReference>): EmitAndSemanticDiagnosticsBuilderProgram;
|
||||
/**
|
||||
* Creates a builder thats just abstraction over program and can be used with watch
|
||||
*/
|
||||
function createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): BuilderProgram;
|
||||
function createAbstractBuilder(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): BuilderProgram;
|
||||
function createAbstractBuilder(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>, projectReferences?: ReadonlyArray<ProjectReference>): BuilderProgram;
|
||||
}
|
||||
declare namespace ts {
|
||||
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 */
|
||||
type CreateProgram<T extends BuilderProgram> = (rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: T, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>) => T;
|
||||
interface WatchCompilerHost<T extends BuilderProgram> {
|
||||
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 */
|
||||
interface WatchHost {
|
||||
/** If provided, called with Diagnostic message that informs about change in watch status */
|
||||
onWatchStatusChange?(diagnostic: Diagnostic, newLine: string, options: CompilerOptions): void;
|
||||
/** Used to watch changes in source files, missing files needed to update the program or config file */
|
||||
watchFile(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher;
|
||||
/** Used to watch resolved module's failed lookup locations, config file specs, type roots where auto type reference directives are added */
|
||||
watchDirectory(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
|
||||
/** If provided, will be used to set delayed compilation, so that multiple changes in short span are compiled together */
|
||||
setTimeout?(callback: (...args: any[]) => void, ms: number, ...args: any[]): any;
|
||||
/** If provided, will be used to reset existing delayed compilation */
|
||||
clearTimeout?(timeoutId: any): void;
|
||||
}
|
||||
interface WatchCompilerHost<T extends BuilderProgram> extends WatchHost {
|
||||
/**
|
||||
* Used to create the program when need for program creation or recreation detected
|
||||
*/
|
||||
createProgram: CreateProgram<T>;
|
||||
/** If provided, callback to invoke after every new program creation */
|
||||
afterProgramCreate?(program: T): void;
|
||||
/** If provided, called with Diagnostic message that informs about change in watch status */
|
||||
onWatchStatusChange?(diagnostic: Diagnostic, newLine: string, options: CompilerOptions): void;
|
||||
useCaseSensitiveFileNames(): boolean;
|
||||
getNewLine(): string;
|
||||
getCurrentDirectory(): string;
|
||||
@@ -4361,14 +4387,6 @@ declare namespace ts {
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[];
|
||||
/** If provided, used to resolve type reference directives, otherwise typescript's default resolution */
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
/** Used to watch changes in source files, missing files needed to update the program or config file */
|
||||
watchFile(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher;
|
||||
/** Used to watch resolved module's failed lookup locations, config file specs, type roots where auto type reference directives are added */
|
||||
watchDirectory(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
|
||||
/** If provided, will be used to set delayed compilation, so that multiple changes in short span are compiled together */
|
||||
setTimeout?(callback: (...args: any[]) => void, ms: number, ...args: any[]): any;
|
||||
/** If provided, will be used to reset existing delayed compilation */
|
||||
clearTimeout?(timeoutId: any): void;
|
||||
}
|
||||
/**
|
||||
* Host to create watch with root files and options
|
||||
@@ -4378,6 +4396,8 @@ declare namespace ts {
|
||||
rootFiles: string[];
|
||||
/** Compiler options */
|
||||
options: CompilerOptions;
|
||||
/** Project References */
|
||||
projectReferences?: ReadonlyArray<ProjectReference>;
|
||||
}
|
||||
/**
|
||||
* Host to create watch with config file
|
||||
@@ -4412,8 +4432,8 @@ declare namespace ts {
|
||||
/**
|
||||
* Create the watch compiler host for either configFile or fileNames and its options
|
||||
*/
|
||||
function createWatchCompilerHost<T extends BuilderProgram>(rootFiles: string[], options: CompilerOptions, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfFilesAndCompilerOptions<T>;
|
||||
function createWatchCompilerHost<T extends BuilderProgram>(configFileName: string, optionsToExtend: CompilerOptions | undefined, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfConfigFile<T>;
|
||||
function createWatchCompilerHost<T extends BuilderProgram>(rootFiles: string[], options: CompilerOptions, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter, projectReferences?: ReadonlyArray<ProjectReference>): WatchCompilerHostOfFilesAndCompilerOptions<T>;
|
||||
/**
|
||||
* Creates the watch from the host for root files and compiler options
|
||||
*/
|
||||
@@ -4423,184 +4443,11 @@ declare namespace ts {
|
||||
*/
|
||||
function createWatchProgram<T extends BuilderProgram>(host: WatchCompilerHostOfConfigFile<T>): WatchOfConfigFile<T>;
|
||||
}
|
||||
declare namespace ts {
|
||||
interface BuildHost {
|
||||
verbose(diag: DiagnosticMessage, ...args: string[]): void;
|
||||
error(diag: DiagnosticMessage, ...args: string[]): void;
|
||||
errorDiagnostic(diag: Diagnostic): void;
|
||||
message(diag: DiagnosticMessage, ...args: string[]): void;
|
||||
}
|
||||
/**
|
||||
* A BuildContext tracks what's going on during the course of a build.
|
||||
*
|
||||
* Callers may invoke any number of build requests within the same context;
|
||||
* until the context is reset, each project will only be built at most once.
|
||||
*
|
||||
* Example: In a standard setup where project B depends on project A, and both are out of date,
|
||||
* a failed build of A will result in A remaining out of date. When we try to build
|
||||
* B, we should immediately bail instead of recomputing A's up-to-date status again.
|
||||
*
|
||||
* This also matters for performing fast (i.e. fake) downstream builds of projects
|
||||
* when their upstream .d.ts files haven't changed content (but have newer timestamps)
|
||||
*/
|
||||
interface BuildContext {
|
||||
options: BuildOptions;
|
||||
/**
|
||||
* Map from output file name to its pre-build timestamp
|
||||
*/
|
||||
unchangedOutputs: FileMap<Date>;
|
||||
/**
|
||||
* Map from config file name to up-to-date status
|
||||
*/
|
||||
projectStatus: FileMap<UpToDateStatus>;
|
||||
invalidatedProjects: FileMap<true>;
|
||||
queuedProjects: FileMap<true>;
|
||||
missingRoots: Map<true>;
|
||||
}
|
||||
type Mapper = ReturnType<typeof createDependencyMapper>;
|
||||
interface DependencyGraph {
|
||||
buildQueue: ResolvedConfigFileName[];
|
||||
dependencyMap: Mapper;
|
||||
}
|
||||
interface BuildOptions {
|
||||
dry: boolean;
|
||||
force: boolean;
|
||||
verbose: boolean;
|
||||
}
|
||||
enum UpToDateStatusType {
|
||||
Unbuildable = 0,
|
||||
UpToDate = 1,
|
||||
/**
|
||||
* The project appears out of date because its upstream inputs are newer than its outputs,
|
||||
* but all of its outputs are actually newer than the previous identical outputs of its (.d.ts) inputs.
|
||||
* This means we can Pseudo-build (just touch timestamps), as if we had actually built this project.
|
||||
*/
|
||||
UpToDateWithUpstreamTypes = 2,
|
||||
OutputMissing = 3,
|
||||
OutOfDateWithSelf = 4,
|
||||
OutOfDateWithUpstream = 5,
|
||||
UpstreamOutOfDate = 6,
|
||||
UpstreamBlocked = 7,
|
||||
/**
|
||||
* Projects with no outputs (i.e. "solution" files)
|
||||
*/
|
||||
ContainerOnly = 8
|
||||
}
|
||||
type UpToDateStatus = Status.Unbuildable | Status.UpToDate | Status.OutputMissing | Status.OutOfDateWithSelf | Status.OutOfDateWithUpstream | Status.UpstreamOutOfDate | Status.UpstreamBlocked | Status.ContainerOnly;
|
||||
namespace Status {
|
||||
/**
|
||||
* The project can't be built at all in its current state. For example,
|
||||
* its config file cannot be parsed, or it has a syntax error or missing file
|
||||
*/
|
||||
interface Unbuildable {
|
||||
type: UpToDateStatusType.Unbuildable;
|
||||
reason: string;
|
||||
}
|
||||
/**
|
||||
* This project doesn't have any outputs, so "is it up to date" is a meaningless question.
|
||||
*/
|
||||
interface ContainerOnly {
|
||||
type: UpToDateStatusType.ContainerOnly;
|
||||
}
|
||||
/**
|
||||
* The project is up to date with respect to its inputs.
|
||||
* We track what the newest input file is.
|
||||
*/
|
||||
interface UpToDate {
|
||||
type: UpToDateStatusType.UpToDate | UpToDateStatusType.UpToDateWithUpstreamTypes;
|
||||
newestInputFileTime?: Date;
|
||||
newestInputFileName?: string;
|
||||
newestDeclarationFileContentChangedTime?: Date;
|
||||
newestOutputFileTime?: Date;
|
||||
newestOutputFileName?: string;
|
||||
oldestOutputFileName?: string;
|
||||
}
|
||||
/**
|
||||
* One or more of the outputs of the project does not exist.
|
||||
*/
|
||||
interface OutputMissing {
|
||||
type: UpToDateStatusType.OutputMissing;
|
||||
/**
|
||||
* The name of the first output file that didn't exist
|
||||
*/
|
||||
missingOutputFileName: string;
|
||||
}
|
||||
/**
|
||||
* One or more of the project's outputs is older than its newest input.
|
||||
*/
|
||||
interface OutOfDateWithSelf {
|
||||
type: UpToDateStatusType.OutOfDateWithSelf;
|
||||
outOfDateOutputFileName: string;
|
||||
newerInputFileName: string;
|
||||
}
|
||||
/**
|
||||
* This project depends on an out-of-date project, so shouldn't be built yet
|
||||
*/
|
||||
interface UpstreamOutOfDate {
|
||||
type: UpToDateStatusType.UpstreamOutOfDate;
|
||||
upstreamProjectName: string;
|
||||
}
|
||||
/**
|
||||
* This project depends an upstream project with build errors
|
||||
*/
|
||||
interface UpstreamBlocked {
|
||||
type: UpToDateStatusType.UpstreamBlocked;
|
||||
upstreamProjectName: string;
|
||||
}
|
||||
/**
|
||||
* One or more of the project's outputs is older than the newest output of
|
||||
* an upstream project.
|
||||
*/
|
||||
interface OutOfDateWithUpstream {
|
||||
type: UpToDateStatusType.OutOfDateWithUpstream;
|
||||
outOfDateOutputFileName: string;
|
||||
newerProjectName: string;
|
||||
}
|
||||
}
|
||||
interface FileMap<T> {
|
||||
setValue(fileName: string, value: T): void;
|
||||
getValue(fileName: string): T | never;
|
||||
getValueOrUndefined(fileName: string): T | undefined;
|
||||
hasKey(fileName: string): boolean;
|
||||
removeKey(fileName: string): void;
|
||||
getKeys(): string[];
|
||||
}
|
||||
function createDependencyMapper(): {
|
||||
addReference: (childConfigFileName: ResolvedConfigFileName, parentConfigFileName: ResolvedConfigFileName) => void;
|
||||
getReferencesTo: (parentConfigFileName: ResolvedConfigFileName) => ResolvedConfigFileName[];
|
||||
getReferencesOf: (childConfigFileName: ResolvedConfigFileName) => ResolvedConfigFileName[];
|
||||
getKeys: () => ReadonlyArray<ResolvedConfigFileName>;
|
||||
};
|
||||
function createBuildContext(options: BuildOptions): BuildContext;
|
||||
function performBuild(args: string[], compilerHost: CompilerHost, buildHost: BuildHost, system?: System): number | undefined;
|
||||
/**
|
||||
* A SolutionBuilder has an immutable set of rootNames that are the "entry point" projects, but
|
||||
* can dynamically add/remove other projects based on changes on the rootNames' references
|
||||
*/
|
||||
function createSolutionBuilder(compilerHost: CompilerHost, buildHost: BuildHost, rootNames: ReadonlyArray<string>, defaultOptions: BuildOptions, system?: System): {
|
||||
buildAllProjects: () => ExitStatus;
|
||||
getUpToDateStatus: (project: ParsedCommandLine | undefined) => UpToDateStatus;
|
||||
getUpToDateStatusOfFile: (configFileName: ResolvedConfigFileName) => UpToDateStatus;
|
||||
cleanAllProjects: () => ExitStatus.Success | ExitStatus.DiagnosticsPresent_OutputsSkipped;
|
||||
resetBuildContext: (opts?: BuildOptions) => void;
|
||||
getBuildGraph: (configFileNames: ReadonlyArray<string>) => DependencyGraph | undefined;
|
||||
invalidateProject: (configFileName: string) => void;
|
||||
buildInvalidatedProjects: () => void;
|
||||
buildDependentInvalidatedProjects: () => void;
|
||||
resolveProjectName: (name: string) => ResolvedConfigFileName | undefined;
|
||||
startWatching: () => void;
|
||||
};
|
||||
/**
|
||||
* Gets the UpToDateStatus for a project
|
||||
*/
|
||||
function getUpToDateStatus(host: UpToDateHost, project: ParsedCommandLine | undefined): UpToDateStatus;
|
||||
function getAllProjectOutputs(project: ParsedCommandLine): ReadonlyArray<string>;
|
||||
function formatUpToDateStatus<T>(configFileName: string, status: UpToDateStatus, relName: (fileName: string) => string, formatMessage: (message: DiagnosticMessage, ...args: string[]) => T): T | undefined;
|
||||
}
|
||||
declare namespace ts.server {
|
||||
type ActionSet = "action::set";
|
||||
type ActionInvalidate = "action::invalidate";
|
||||
type ActionPackageInstalled = "action::packageInstalled";
|
||||
type ActionValueInspected = "action::valueInspected";
|
||||
type EventTypesRegistry = "event::typesRegistry";
|
||||
type EventBeginInstallTypes = "event::beginInstallTypes";
|
||||
type EventEndInstallTypes = "event::endInstallTypes";
|
||||
@@ -4609,7 +4456,7 @@ declare namespace ts.server {
|
||||
" __sortedArrayBrand": any;
|
||||
}
|
||||
interface TypingInstallerResponse {
|
||||
readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | ActionPackageInstalled | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed;
|
||||
readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | ActionPackageInstalled | ActionValueInspected | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed;
|
||||
}
|
||||
interface TypingInstallerRequestWithProjectName {
|
||||
readonly projectName: string;
|
||||
@@ -4817,14 +4664,7 @@ declare namespace ts {
|
||||
getCustomTransformers?(): CustomTransformers | undefined;
|
||||
isKnownTypesPackageName?(name: string): boolean;
|
||||
installPackage?(options: InstallPackageOptions): Promise<ApplyCodeActionCommandResult>;
|
||||
}
|
||||
interface UserPreferences {
|
||||
readonly disableSuggestions?: boolean;
|
||||
readonly quotePreference?: "double" | "single";
|
||||
readonly includeCompletionsForModuleExports?: boolean;
|
||||
readonly includeCompletionsWithInsertText?: boolean;
|
||||
readonly importModuleSpecifierPreference?: "relative" | "non-relative";
|
||||
readonly allowTextChangesInNewFiles?: boolean;
|
||||
writeFile?(fileName: string, content: string): void;
|
||||
}
|
||||
interface LanguageService {
|
||||
cleanupSemanticCache(): void;
|
||||
@@ -4882,9 +4722,9 @@ declare namespace ts {
|
||||
toLineColumnOffset?(fileName: string, position: number): LineAndCharacter;
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray<number>, formatOptions: FormatCodeSettings, preferences: UserPreferences): ReadonlyArray<CodeFixAction>;
|
||||
getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: {}, formatOptions: FormatCodeSettings, preferences: UserPreferences): CombinedCodeActions;
|
||||
applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
|
||||
applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
applyCodeActionCommand(action: CodeActionCommand, formatSettings?: FormatCodeSettings): Promise<ApplyCodeActionCommandResult>;
|
||||
applyCodeActionCommand(action: CodeActionCommand[], formatSettings?: FormatCodeSettings): Promise<ApplyCodeActionCommandResult[]>;
|
||||
applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[], formatSettings?: FormatCodeSettings): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
/** @deprecated `fileName` will be ignored */
|
||||
applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
/** @deprecated `fileName` will be ignored */
|
||||
@@ -5046,9 +4886,16 @@ declare namespace ts {
|
||||
changes: ReadonlyArray<FileTextChanges>;
|
||||
commands?: ReadonlyArray<CodeActionCommand>;
|
||||
}
|
||||
type CodeActionCommand = InstallPackageAction;
|
||||
type CodeActionCommand = InstallPackageAction | GenerateTypesAction;
|
||||
interface InstallPackageAction {
|
||||
}
|
||||
interface GenerateTypesAction extends GenerateTypesOptions {
|
||||
}
|
||||
interface GenerateTypesOptions {
|
||||
readonly file: string;
|
||||
readonly fileToGenerateTypesFor: string;
|
||||
readonly outputFileName: string;
|
||||
}
|
||||
/**
|
||||
* A set of one or more available refactoring actions, grouped under a parent refactoring.
|
||||
*/
|
||||
@@ -5114,6 +4961,8 @@ declare namespace ts {
|
||||
originalFileName?: string;
|
||||
}
|
||||
interface RenameLocation extends DocumentSpan {
|
||||
readonly prefixText?: string;
|
||||
readonly suffixText?: string;
|
||||
}
|
||||
interface ReferenceEntry extends DocumentSpan {
|
||||
isWriteAccess: boolean;
|
||||
@@ -5266,15 +5115,24 @@ declare namespace ts {
|
||||
documentation?: SymbolDisplayPart[];
|
||||
tags?: JSDocTagInfo[];
|
||||
}
|
||||
interface RenameInfo {
|
||||
canRename: boolean;
|
||||
localizedErrorMessage?: string;
|
||||
type RenameInfo = RenameInfoSuccess | RenameInfoFailure;
|
||||
interface RenameInfoSuccess {
|
||||
canRename: true;
|
||||
/**
|
||||
* File or directory to rename.
|
||||
* If set, `getEditsForFileRename` should be called instead of `findRenameLocations`.
|
||||
*/
|
||||
fileToRename?: string;
|
||||
displayName: string;
|
||||
fullDisplayName: string;
|
||||
kind: ScriptElementKind;
|
||||
kindModifiers: string;
|
||||
triggerSpan: TextSpan;
|
||||
}
|
||||
interface RenameInfoFailure {
|
||||
canRename: false;
|
||||
localizedErrorMessage: string;
|
||||
}
|
||||
interface SignatureHelpParameter {
|
||||
name: string;
|
||||
documentation: SymbolDisplayPart[];
|
||||
|
||||
+7223
-4440
File diff suppressed because it is too large
Load Diff
Vendored
+99
-241
@@ -14,7 +14,7 @@ and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
declare namespace ts {
|
||||
const versionMajorMinor = "3.1";
|
||||
const versionMajorMinor = "3.2";
|
||||
/** The version of the TypeScript compiler release */
|
||||
const version: string;
|
||||
}
|
||||
@@ -69,7 +69,8 @@ declare namespace ts {
|
||||
pos: number;
|
||||
end: number;
|
||||
}
|
||||
type JsDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.NoSubstitutionTemplateLiteral | SyntaxKind.Unknown;
|
||||
type JsDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.NoSubstitutionTemplateLiteral | SyntaxKind.Unknown | KeywordSyntaxKind;
|
||||
type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InKeyword | SyntaxKind.InferKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.OfKeyword;
|
||||
type JsxTokenSyntaxKind = SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken;
|
||||
enum SyntaxKind {
|
||||
Unknown = 0,
|
||||
@@ -536,6 +537,7 @@ declare namespace ts {
|
||||
name?: Identifier | StringLiteral | NumericLiteral;
|
||||
}
|
||||
interface ComputedPropertyName extends Node {
|
||||
parent: Declaration;
|
||||
kind: SyntaxKind.ComputedPropertyName;
|
||||
expression: Expression;
|
||||
}
|
||||
@@ -632,6 +634,7 @@ declare namespace ts {
|
||||
kind: SyntaxKind.ShorthandPropertyAssignment;
|
||||
name: Identifier;
|
||||
questionToken?: QuestionToken;
|
||||
exclamationToken?: ExclamationToken;
|
||||
equalsToken?: Token<SyntaxKind.EqualsToken>;
|
||||
objectAssignmentInitializer?: Expression;
|
||||
}
|
||||
@@ -668,6 +671,7 @@ declare namespace ts {
|
||||
_functionLikeDeclarationBrand: any;
|
||||
asteriskToken?: AsteriskToken;
|
||||
questionToken?: QuestionToken;
|
||||
exclamationToken?: ExclamationToken;
|
||||
body?: Block | Expression;
|
||||
}
|
||||
type FunctionLikeDeclaration = FunctionDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration | FunctionExpression | ArrowFunction;
|
||||
@@ -1079,7 +1083,7 @@ declare namespace ts {
|
||||
}
|
||||
interface ExpressionWithTypeArguments extends NodeWithTypeArguments {
|
||||
kind: SyntaxKind.ExpressionWithTypeArguments;
|
||||
parent: HeritageClause;
|
||||
parent: HeritageClause | JSDocAugmentsTag;
|
||||
expression: LeftHandSideExpression;
|
||||
}
|
||||
interface NewExpression extends PrimaryExpression, Declaration {
|
||||
@@ -1808,7 +1812,8 @@ declare namespace ts {
|
||||
getTypeChecker(): TypeChecker;
|
||||
isSourceFileFromExternalLibrary(file: SourceFile): boolean;
|
||||
isSourceFileDefaultLibrary(file: SourceFile): boolean;
|
||||
getProjectReferences(): (ResolvedProjectReference | undefined)[] | undefined;
|
||||
getProjectReferences(): ReadonlyArray<ProjectReference> | undefined;
|
||||
getResolvedProjectReferences(): (ResolvedProjectReference | undefined)[] | undefined;
|
||||
}
|
||||
interface ResolvedProjectReference {
|
||||
commandLine: ParsedCommandLine;
|
||||
@@ -2056,32 +2061,32 @@ declare namespace ts {
|
||||
ExportStar = 8388608,
|
||||
Optional = 16777216,
|
||||
Transient = 33554432,
|
||||
JSContainer = 67108864,
|
||||
Assignment = 67108864,
|
||||
ModuleExports = 134217728,
|
||||
Enum = 384,
|
||||
Variable = 3,
|
||||
Value = 67216319,
|
||||
Type = 67901928,
|
||||
Value = 67220415,
|
||||
Type = 67897832,
|
||||
Namespace = 1920,
|
||||
Module = 1536,
|
||||
Accessor = 98304,
|
||||
FunctionScopedVariableExcludes = 67216318,
|
||||
BlockScopedVariableExcludes = 67216319,
|
||||
ParameterExcludes = 67216319,
|
||||
FunctionScopedVariableExcludes = 67220414,
|
||||
BlockScopedVariableExcludes = 67220415,
|
||||
ParameterExcludes = 67220415,
|
||||
PropertyExcludes = 0,
|
||||
EnumMemberExcludes = 68008959,
|
||||
FunctionExcludes = 67215791,
|
||||
FunctionExcludes = 67219887,
|
||||
ClassExcludes = 68008383,
|
||||
InterfaceExcludes = 67901832,
|
||||
InterfaceExcludes = 67897736,
|
||||
RegularEnumExcludes = 68008191,
|
||||
ConstEnumExcludes = 68008831,
|
||||
ValueModuleExcludes = 67215503,
|
||||
ValueModuleExcludes = 110735,
|
||||
NamespaceModuleExcludes = 0,
|
||||
MethodExcludes = 67208127,
|
||||
GetAccessorExcludes = 67150783,
|
||||
SetAccessorExcludes = 67183551,
|
||||
TypeParameterExcludes = 67639784,
|
||||
TypeAliasExcludes = 67901928,
|
||||
MethodExcludes = 67212223,
|
||||
GetAccessorExcludes = 67154879,
|
||||
SetAccessorExcludes = 67187647,
|
||||
TypeParameterExcludes = 67635688,
|
||||
TypeAliasExcludes = 67897832,
|
||||
AliasExcludes = 2097152,
|
||||
ModuleMember = 2623475,
|
||||
ExportHasLocal = 944,
|
||||
@@ -2490,6 +2495,7 @@ declare namespace ts {
|
||||
sourceRoot?: string;
|
||||
strict?: boolean;
|
||||
strictFunctionTypes?: boolean;
|
||||
strictBindCallApply?: boolean;
|
||||
strictNullChecks?: boolean;
|
||||
strictPropertyInitialization?: boolean;
|
||||
stripInternal?: boolean;
|
||||
@@ -2581,7 +2587,6 @@ declare namespace ts {
|
||||
}
|
||||
interface ExpandResult {
|
||||
fileNames: string[];
|
||||
projectReferences: ReadonlyArray<ProjectReference> | undefined;
|
||||
wildcardDirectories: MapLike<WatchDirectoryFlags>;
|
||||
}
|
||||
interface CreateProgramOptions {
|
||||
@@ -2592,14 +2597,6 @@ declare namespace ts {
|
||||
oldProgram?: Program;
|
||||
configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>;
|
||||
}
|
||||
interface UpToDateHost {
|
||||
fileExists(fileName: string): boolean;
|
||||
getModifiedTime(fileName: string): Date | undefined;
|
||||
getUnchangedTime?(fileName: string): Date | undefined;
|
||||
getLastStatus?(fileName: string): UpToDateStatus | undefined;
|
||||
setLastStatus?(fileName: string, status: UpToDateStatus): void;
|
||||
parseConfigFile?(configFilePath: ResolvedConfigFileName): ParsedCommandLine | undefined;
|
||||
}
|
||||
interface ModuleResolutionHost {
|
||||
fileExists(fileName: string): boolean;
|
||||
readFile(fileName: string): string | undefined;
|
||||
@@ -2698,9 +2695,6 @@ declare namespace ts {
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
getEnvironmentVariable?(name: string): string | undefined;
|
||||
createHash?(data: string): string;
|
||||
getModifiedTime?(fileName: string): Date | undefined;
|
||||
setModifiedTime?(fileName: string, date: Date): void;
|
||||
deleteFile?(fileName: string): void;
|
||||
}
|
||||
interface SourceMapRange extends TextRange {
|
||||
source?: SourceMapSource;
|
||||
@@ -3001,6 +2995,16 @@ declare namespace ts {
|
||||
Parameters = 1296,
|
||||
IndexSignatureParameters = 4432
|
||||
}
|
||||
interface UserPreferences {
|
||||
readonly disableSuggestions?: boolean;
|
||||
readonly quotePreference?: "double" | "single";
|
||||
readonly includeCompletionsForModuleExports?: boolean;
|
||||
readonly includeCompletionsWithInsertText?: boolean;
|
||||
readonly importModuleSpecifierPreference?: "relative" | "non-relative";
|
||||
/** Determines whether we import `foo/index.ts` as "foo", "foo/index", or "foo/index.js" */
|
||||
readonly importModuleSpecifierEnding?: "minimal" | "index" | "js";
|
||||
readonly allowTextChangesInNewFiles?: boolean;
|
||||
}
|
||||
}
|
||||
declare function setTimeout(handler: (...args: any[]) => void, timeout: number): any;
|
||||
declare function clearTimeout(handle: any): void;
|
||||
@@ -3209,17 +3213,27 @@ declare namespace ts {
|
||||
/**
|
||||
* Gets the JSDoc parameter tags for the node if present.
|
||||
*
|
||||
* @remarks Returns any JSDoc param tag that matches the provided
|
||||
* @remarks Returns any JSDoc param tag whose name matches the provided
|
||||
* parameter, whether a param tag on a containing function
|
||||
* expression, or a param tag on a variable declaration whose
|
||||
* initializer is the containing function. The tags closest to the
|
||||
* node are returned first, so in the previous example, the param
|
||||
* tag on the containing function expression would be first.
|
||||
*
|
||||
* Does not return tags for binding patterns, because JSDoc matches
|
||||
* parameters by name and binding patterns do not have a name.
|
||||
* For binding patterns, parameter tags are matched by position.
|
||||
*/
|
||||
function getJSDocParameterTags(param: ParameterDeclaration): ReadonlyArray<JSDocParameterTag>;
|
||||
/**
|
||||
* Gets the JSDoc type parameter tags for the node if present.
|
||||
*
|
||||
* @remarks Returns any JSDoc template tag whose names match the provided
|
||||
* parameter, whether a template tag on a containing function
|
||||
* expression, or a template tag on a variable declaration whose
|
||||
* initializer is the containing function. The tags closest to the
|
||||
* node are returned first, so in the previous example, the template
|
||||
* tag on the containing function expression would be first.
|
||||
*/
|
||||
function getJSDocTypeParameterTags(param: TypeParameterDeclaration): ReadonlyArray<JSDocTemplateTag>;
|
||||
/**
|
||||
* Return true if the node has JSDoc parameter tags.
|
||||
*
|
||||
@@ -4171,14 +4185,15 @@ declare namespace ts {
|
||||
* @returns A 'Program' object.
|
||||
*/
|
||||
function createProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): Program;
|
||||
interface ResolveProjectReferencePathHost {
|
||||
/** @deprecated */ interface ResolveProjectReferencePathHost {
|
||||
fileExists(fileName: string): boolean;
|
||||
}
|
||||
/**
|
||||
* Returns the target config filename of a project reference.
|
||||
* Note: The file might not exist.
|
||||
*/
|
||||
function resolveProjectReferencePath(host: ResolveProjectReferencePathHost, ref: ProjectReference): ResolvedConfigFileName;
|
||||
function resolveProjectReferencePath(ref: ProjectReference): ResolvedConfigFileName;
|
||||
/** @deprecated */ function resolveProjectReferencePath(host: ResolveProjectReferencePathHost, ref: ProjectReference): ResolvedConfigFileName;
|
||||
}
|
||||
declare namespace ts {
|
||||
interface EmitOutput {
|
||||
@@ -4303,32 +4318,43 @@ declare namespace ts {
|
||||
* Create the builder to manage semantic diagnostics and cache them
|
||||
*/
|
||||
function createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): SemanticDiagnosticsBuilderProgram;
|
||||
function createSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): SemanticDiagnosticsBuilderProgram;
|
||||
function createSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>, projectReferences?: ReadonlyArray<ProjectReference>): SemanticDiagnosticsBuilderProgram;
|
||||
/**
|
||||
* Create the builder that can handle the changes in program and iterate through changed files
|
||||
* to emit the those files and manage semantic diagnostics cache as well
|
||||
*/
|
||||
function createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): EmitAndSemanticDiagnosticsBuilderProgram;
|
||||
function createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): EmitAndSemanticDiagnosticsBuilderProgram;
|
||||
function createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>, projectReferences?: ReadonlyArray<ProjectReference>): EmitAndSemanticDiagnosticsBuilderProgram;
|
||||
/**
|
||||
* Creates a builder thats just abstraction over program and can be used with watch
|
||||
*/
|
||||
function createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): BuilderProgram;
|
||||
function createAbstractBuilder(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): BuilderProgram;
|
||||
function createAbstractBuilder(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>, projectReferences?: ReadonlyArray<ProjectReference>): BuilderProgram;
|
||||
}
|
||||
declare namespace ts {
|
||||
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 */
|
||||
type CreateProgram<T extends BuilderProgram> = (rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: T, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>) => T;
|
||||
interface WatchCompilerHost<T extends BuilderProgram> {
|
||||
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 */
|
||||
interface WatchHost {
|
||||
/** If provided, called with Diagnostic message that informs about change in watch status */
|
||||
onWatchStatusChange?(diagnostic: Diagnostic, newLine: string, options: CompilerOptions): void;
|
||||
/** Used to watch changes in source files, missing files needed to update the program or config file */
|
||||
watchFile(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher;
|
||||
/** Used to watch resolved module's failed lookup locations, config file specs, type roots where auto type reference directives are added */
|
||||
watchDirectory(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
|
||||
/** If provided, will be used to set delayed compilation, so that multiple changes in short span are compiled together */
|
||||
setTimeout?(callback: (...args: any[]) => void, ms: number, ...args: any[]): any;
|
||||
/** If provided, will be used to reset existing delayed compilation */
|
||||
clearTimeout?(timeoutId: any): void;
|
||||
}
|
||||
interface WatchCompilerHost<T extends BuilderProgram> extends WatchHost {
|
||||
/**
|
||||
* Used to create the program when need for program creation or recreation detected
|
||||
*/
|
||||
createProgram: CreateProgram<T>;
|
||||
/** If provided, callback to invoke after every new program creation */
|
||||
afterProgramCreate?(program: T): void;
|
||||
/** If provided, called with Diagnostic message that informs about change in watch status */
|
||||
onWatchStatusChange?(diagnostic: Diagnostic, newLine: string, options: CompilerOptions): void;
|
||||
useCaseSensitiveFileNames(): boolean;
|
||||
getNewLine(): string;
|
||||
getCurrentDirectory(): string;
|
||||
@@ -4361,14 +4387,6 @@ declare namespace ts {
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[];
|
||||
/** If provided, used to resolve type reference directives, otherwise typescript's default resolution */
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
/** Used to watch changes in source files, missing files needed to update the program or config file */
|
||||
watchFile(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher;
|
||||
/** Used to watch resolved module's failed lookup locations, config file specs, type roots where auto type reference directives are added */
|
||||
watchDirectory(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
|
||||
/** If provided, will be used to set delayed compilation, so that multiple changes in short span are compiled together */
|
||||
setTimeout?(callback: (...args: any[]) => void, ms: number, ...args: any[]): any;
|
||||
/** If provided, will be used to reset existing delayed compilation */
|
||||
clearTimeout?(timeoutId: any): void;
|
||||
}
|
||||
/**
|
||||
* Host to create watch with root files and options
|
||||
@@ -4378,6 +4396,8 @@ declare namespace ts {
|
||||
rootFiles: string[];
|
||||
/** Compiler options */
|
||||
options: CompilerOptions;
|
||||
/** Project References */
|
||||
projectReferences?: ReadonlyArray<ProjectReference>;
|
||||
}
|
||||
/**
|
||||
* Host to create watch with config file
|
||||
@@ -4412,8 +4432,8 @@ declare namespace ts {
|
||||
/**
|
||||
* Create the watch compiler host for either configFile or fileNames and its options
|
||||
*/
|
||||
function createWatchCompilerHost<T extends BuilderProgram>(rootFiles: string[], options: CompilerOptions, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfFilesAndCompilerOptions<T>;
|
||||
function createWatchCompilerHost<T extends BuilderProgram>(configFileName: string, optionsToExtend: CompilerOptions | undefined, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfConfigFile<T>;
|
||||
function createWatchCompilerHost<T extends BuilderProgram>(rootFiles: string[], options: CompilerOptions, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter, projectReferences?: ReadonlyArray<ProjectReference>): WatchCompilerHostOfFilesAndCompilerOptions<T>;
|
||||
/**
|
||||
* Creates the watch from the host for root files and compiler options
|
||||
*/
|
||||
@@ -4423,184 +4443,11 @@ declare namespace ts {
|
||||
*/
|
||||
function createWatchProgram<T extends BuilderProgram>(host: WatchCompilerHostOfConfigFile<T>): WatchOfConfigFile<T>;
|
||||
}
|
||||
declare namespace ts {
|
||||
interface BuildHost {
|
||||
verbose(diag: DiagnosticMessage, ...args: string[]): void;
|
||||
error(diag: DiagnosticMessage, ...args: string[]): void;
|
||||
errorDiagnostic(diag: Diagnostic): void;
|
||||
message(diag: DiagnosticMessage, ...args: string[]): void;
|
||||
}
|
||||
/**
|
||||
* A BuildContext tracks what's going on during the course of a build.
|
||||
*
|
||||
* Callers may invoke any number of build requests within the same context;
|
||||
* until the context is reset, each project will only be built at most once.
|
||||
*
|
||||
* Example: In a standard setup where project B depends on project A, and both are out of date,
|
||||
* a failed build of A will result in A remaining out of date. When we try to build
|
||||
* B, we should immediately bail instead of recomputing A's up-to-date status again.
|
||||
*
|
||||
* This also matters for performing fast (i.e. fake) downstream builds of projects
|
||||
* when their upstream .d.ts files haven't changed content (but have newer timestamps)
|
||||
*/
|
||||
interface BuildContext {
|
||||
options: BuildOptions;
|
||||
/**
|
||||
* Map from output file name to its pre-build timestamp
|
||||
*/
|
||||
unchangedOutputs: FileMap<Date>;
|
||||
/**
|
||||
* Map from config file name to up-to-date status
|
||||
*/
|
||||
projectStatus: FileMap<UpToDateStatus>;
|
||||
invalidatedProjects: FileMap<true>;
|
||||
queuedProjects: FileMap<true>;
|
||||
missingRoots: Map<true>;
|
||||
}
|
||||
type Mapper = ReturnType<typeof createDependencyMapper>;
|
||||
interface DependencyGraph {
|
||||
buildQueue: ResolvedConfigFileName[];
|
||||
dependencyMap: Mapper;
|
||||
}
|
||||
interface BuildOptions {
|
||||
dry: boolean;
|
||||
force: boolean;
|
||||
verbose: boolean;
|
||||
}
|
||||
enum UpToDateStatusType {
|
||||
Unbuildable = 0,
|
||||
UpToDate = 1,
|
||||
/**
|
||||
* The project appears out of date because its upstream inputs are newer than its outputs,
|
||||
* but all of its outputs are actually newer than the previous identical outputs of its (.d.ts) inputs.
|
||||
* This means we can Pseudo-build (just touch timestamps), as if we had actually built this project.
|
||||
*/
|
||||
UpToDateWithUpstreamTypes = 2,
|
||||
OutputMissing = 3,
|
||||
OutOfDateWithSelf = 4,
|
||||
OutOfDateWithUpstream = 5,
|
||||
UpstreamOutOfDate = 6,
|
||||
UpstreamBlocked = 7,
|
||||
/**
|
||||
* Projects with no outputs (i.e. "solution" files)
|
||||
*/
|
||||
ContainerOnly = 8
|
||||
}
|
||||
type UpToDateStatus = Status.Unbuildable | Status.UpToDate | Status.OutputMissing | Status.OutOfDateWithSelf | Status.OutOfDateWithUpstream | Status.UpstreamOutOfDate | Status.UpstreamBlocked | Status.ContainerOnly;
|
||||
namespace Status {
|
||||
/**
|
||||
* The project can't be built at all in its current state. For example,
|
||||
* its config file cannot be parsed, or it has a syntax error or missing file
|
||||
*/
|
||||
interface Unbuildable {
|
||||
type: UpToDateStatusType.Unbuildable;
|
||||
reason: string;
|
||||
}
|
||||
/**
|
||||
* This project doesn't have any outputs, so "is it up to date" is a meaningless question.
|
||||
*/
|
||||
interface ContainerOnly {
|
||||
type: UpToDateStatusType.ContainerOnly;
|
||||
}
|
||||
/**
|
||||
* The project is up to date with respect to its inputs.
|
||||
* We track what the newest input file is.
|
||||
*/
|
||||
interface UpToDate {
|
||||
type: UpToDateStatusType.UpToDate | UpToDateStatusType.UpToDateWithUpstreamTypes;
|
||||
newestInputFileTime?: Date;
|
||||
newestInputFileName?: string;
|
||||
newestDeclarationFileContentChangedTime?: Date;
|
||||
newestOutputFileTime?: Date;
|
||||
newestOutputFileName?: string;
|
||||
oldestOutputFileName?: string;
|
||||
}
|
||||
/**
|
||||
* One or more of the outputs of the project does not exist.
|
||||
*/
|
||||
interface OutputMissing {
|
||||
type: UpToDateStatusType.OutputMissing;
|
||||
/**
|
||||
* The name of the first output file that didn't exist
|
||||
*/
|
||||
missingOutputFileName: string;
|
||||
}
|
||||
/**
|
||||
* One or more of the project's outputs is older than its newest input.
|
||||
*/
|
||||
interface OutOfDateWithSelf {
|
||||
type: UpToDateStatusType.OutOfDateWithSelf;
|
||||
outOfDateOutputFileName: string;
|
||||
newerInputFileName: string;
|
||||
}
|
||||
/**
|
||||
* This project depends on an out-of-date project, so shouldn't be built yet
|
||||
*/
|
||||
interface UpstreamOutOfDate {
|
||||
type: UpToDateStatusType.UpstreamOutOfDate;
|
||||
upstreamProjectName: string;
|
||||
}
|
||||
/**
|
||||
* This project depends an upstream project with build errors
|
||||
*/
|
||||
interface UpstreamBlocked {
|
||||
type: UpToDateStatusType.UpstreamBlocked;
|
||||
upstreamProjectName: string;
|
||||
}
|
||||
/**
|
||||
* One or more of the project's outputs is older than the newest output of
|
||||
* an upstream project.
|
||||
*/
|
||||
interface OutOfDateWithUpstream {
|
||||
type: UpToDateStatusType.OutOfDateWithUpstream;
|
||||
outOfDateOutputFileName: string;
|
||||
newerProjectName: string;
|
||||
}
|
||||
}
|
||||
interface FileMap<T> {
|
||||
setValue(fileName: string, value: T): void;
|
||||
getValue(fileName: string): T | never;
|
||||
getValueOrUndefined(fileName: string): T | undefined;
|
||||
hasKey(fileName: string): boolean;
|
||||
removeKey(fileName: string): void;
|
||||
getKeys(): string[];
|
||||
}
|
||||
function createDependencyMapper(): {
|
||||
addReference: (childConfigFileName: ResolvedConfigFileName, parentConfigFileName: ResolvedConfigFileName) => void;
|
||||
getReferencesTo: (parentConfigFileName: ResolvedConfigFileName) => ResolvedConfigFileName[];
|
||||
getReferencesOf: (childConfigFileName: ResolvedConfigFileName) => ResolvedConfigFileName[];
|
||||
getKeys: () => ReadonlyArray<ResolvedConfigFileName>;
|
||||
};
|
||||
function createBuildContext(options: BuildOptions): BuildContext;
|
||||
function performBuild(args: string[], compilerHost: CompilerHost, buildHost: BuildHost, system?: System): number | undefined;
|
||||
/**
|
||||
* A SolutionBuilder has an immutable set of rootNames that are the "entry point" projects, but
|
||||
* can dynamically add/remove other projects based on changes on the rootNames' references
|
||||
*/
|
||||
function createSolutionBuilder(compilerHost: CompilerHost, buildHost: BuildHost, rootNames: ReadonlyArray<string>, defaultOptions: BuildOptions, system?: System): {
|
||||
buildAllProjects: () => ExitStatus;
|
||||
getUpToDateStatus: (project: ParsedCommandLine | undefined) => UpToDateStatus;
|
||||
getUpToDateStatusOfFile: (configFileName: ResolvedConfigFileName) => UpToDateStatus;
|
||||
cleanAllProjects: () => ExitStatus.Success | ExitStatus.DiagnosticsPresent_OutputsSkipped;
|
||||
resetBuildContext: (opts?: BuildOptions) => void;
|
||||
getBuildGraph: (configFileNames: ReadonlyArray<string>) => DependencyGraph | undefined;
|
||||
invalidateProject: (configFileName: string) => void;
|
||||
buildInvalidatedProjects: () => void;
|
||||
buildDependentInvalidatedProjects: () => void;
|
||||
resolveProjectName: (name: string) => ResolvedConfigFileName | undefined;
|
||||
startWatching: () => void;
|
||||
};
|
||||
/**
|
||||
* Gets the UpToDateStatus for a project
|
||||
*/
|
||||
function getUpToDateStatus(host: UpToDateHost, project: ParsedCommandLine | undefined): UpToDateStatus;
|
||||
function getAllProjectOutputs(project: ParsedCommandLine): ReadonlyArray<string>;
|
||||
function formatUpToDateStatus<T>(configFileName: string, status: UpToDateStatus, relName: (fileName: string) => string, formatMessage: (message: DiagnosticMessage, ...args: string[]) => T): T | undefined;
|
||||
}
|
||||
declare namespace ts.server {
|
||||
type ActionSet = "action::set";
|
||||
type ActionInvalidate = "action::invalidate";
|
||||
type ActionPackageInstalled = "action::packageInstalled";
|
||||
type ActionValueInspected = "action::valueInspected";
|
||||
type EventTypesRegistry = "event::typesRegistry";
|
||||
type EventBeginInstallTypes = "event::beginInstallTypes";
|
||||
type EventEndInstallTypes = "event::endInstallTypes";
|
||||
@@ -4609,7 +4456,7 @@ declare namespace ts.server {
|
||||
" __sortedArrayBrand": any;
|
||||
}
|
||||
interface TypingInstallerResponse {
|
||||
readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | ActionPackageInstalled | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed;
|
||||
readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | ActionPackageInstalled | ActionValueInspected | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed;
|
||||
}
|
||||
interface TypingInstallerRequestWithProjectName {
|
||||
readonly projectName: string;
|
||||
@@ -4817,14 +4664,7 @@ declare namespace ts {
|
||||
getCustomTransformers?(): CustomTransformers | undefined;
|
||||
isKnownTypesPackageName?(name: string): boolean;
|
||||
installPackage?(options: InstallPackageOptions): Promise<ApplyCodeActionCommandResult>;
|
||||
}
|
||||
interface UserPreferences {
|
||||
readonly disableSuggestions?: boolean;
|
||||
readonly quotePreference?: "double" | "single";
|
||||
readonly includeCompletionsForModuleExports?: boolean;
|
||||
readonly includeCompletionsWithInsertText?: boolean;
|
||||
readonly importModuleSpecifierPreference?: "relative" | "non-relative";
|
||||
readonly allowTextChangesInNewFiles?: boolean;
|
||||
writeFile?(fileName: string, content: string): void;
|
||||
}
|
||||
interface LanguageService {
|
||||
cleanupSemanticCache(): void;
|
||||
@@ -4882,9 +4722,9 @@ declare namespace ts {
|
||||
toLineColumnOffset?(fileName: string, position: number): LineAndCharacter;
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray<number>, formatOptions: FormatCodeSettings, preferences: UserPreferences): ReadonlyArray<CodeFixAction>;
|
||||
getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: {}, formatOptions: FormatCodeSettings, preferences: UserPreferences): CombinedCodeActions;
|
||||
applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
|
||||
applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
applyCodeActionCommand(action: CodeActionCommand, formatSettings?: FormatCodeSettings): Promise<ApplyCodeActionCommandResult>;
|
||||
applyCodeActionCommand(action: CodeActionCommand[], formatSettings?: FormatCodeSettings): Promise<ApplyCodeActionCommandResult[]>;
|
||||
applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[], formatSettings?: FormatCodeSettings): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
/** @deprecated `fileName` will be ignored */
|
||||
applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
/** @deprecated `fileName` will be ignored */
|
||||
@@ -5046,9 +4886,16 @@ declare namespace ts {
|
||||
changes: ReadonlyArray<FileTextChanges>;
|
||||
commands?: ReadonlyArray<CodeActionCommand>;
|
||||
}
|
||||
type CodeActionCommand = InstallPackageAction;
|
||||
type CodeActionCommand = InstallPackageAction | GenerateTypesAction;
|
||||
interface InstallPackageAction {
|
||||
}
|
||||
interface GenerateTypesAction extends GenerateTypesOptions {
|
||||
}
|
||||
interface GenerateTypesOptions {
|
||||
readonly file: string;
|
||||
readonly fileToGenerateTypesFor: string;
|
||||
readonly outputFileName: string;
|
||||
}
|
||||
/**
|
||||
* A set of one or more available refactoring actions, grouped under a parent refactoring.
|
||||
*/
|
||||
@@ -5114,6 +4961,8 @@ declare namespace ts {
|
||||
originalFileName?: string;
|
||||
}
|
||||
interface RenameLocation extends DocumentSpan {
|
||||
readonly prefixText?: string;
|
||||
readonly suffixText?: string;
|
||||
}
|
||||
interface ReferenceEntry extends DocumentSpan {
|
||||
isWriteAccess: boolean;
|
||||
@@ -5266,15 +5115,24 @@ declare namespace ts {
|
||||
documentation?: SymbolDisplayPart[];
|
||||
tags?: JSDocTagInfo[];
|
||||
}
|
||||
interface RenameInfo {
|
||||
canRename: boolean;
|
||||
localizedErrorMessage?: string;
|
||||
type RenameInfo = RenameInfoSuccess | RenameInfoFailure;
|
||||
interface RenameInfoSuccess {
|
||||
canRename: true;
|
||||
/**
|
||||
* File or directory to rename.
|
||||
* If set, `getEditsForFileRename` should be called instead of `findRenameLocations`.
|
||||
*/
|
||||
fileToRename?: string;
|
||||
displayName: string;
|
||||
fullDisplayName: string;
|
||||
kind: ScriptElementKind;
|
||||
kindModifiers: string;
|
||||
triggerSpan: TextSpan;
|
||||
}
|
||||
interface RenameInfoFailure {
|
||||
canRename: false;
|
||||
localizedErrorMessage: string;
|
||||
}
|
||||
interface SignatureHelpParameter {
|
||||
name: string;
|
||||
documentation: SymbolDisplayPart[];
|
||||
|
||||
+7223
-4440
File diff suppressed because it is too large
Load Diff
+5812
-3851
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": "已生成声明文件的输出目录。",
|
||||
|
||||
+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",
|
||||
|
||||
+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;
|
||||
+98
-55
@@ -640,6 +640,7 @@ namespace ts {
|
||||
function bindChildrenWorker(node: Node): void {
|
||||
if (checkUnreachable(node)) {
|
||||
bindEachChild(node);
|
||||
bindJSDoc(node);
|
||||
return;
|
||||
}
|
||||
switch (node.kind) {
|
||||
@@ -1180,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];
|
||||
@@ -2112,7 +2112,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:
|
||||
@@ -2188,6 +2188,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);
|
||||
}
|
||||
@@ -2310,27 +2323,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) {
|
||||
@@ -2361,6 +2364,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
|
||||
@@ -2465,7 +2484,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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2486,6 +2510,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;
|
||||
@@ -2517,16 +2547,12 @@ 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;
|
||||
@@ -2538,6 +2564,10 @@ namespace ts {
|
||||
}
|
||||
});
|
||||
}
|
||||
return namespaceSymbol;
|
||||
}
|
||||
|
||||
function bindPotentiallyNewExpandoMemberToNamespace(declaration: PropertyAccessEntityNameExpression | CallExpression, namespaceSymbol: Symbol | undefined, isPrototypeProperty: boolean) {
|
||||
if (!namespaceSymbol || !isExpandoSymbol(namespaceSymbol)) {
|
||||
return;
|
||||
}
|
||||
@@ -2547,10 +2577,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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3010,7 +3049,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.
|
||||
@@ -3041,7 +3080,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;
|
||||
@@ -3084,18 +3123,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;
|
||||
}
|
||||
|
||||
@@ -3148,7 +3187,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;
|
||||
}
|
||||
@@ -3170,7 +3209,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;
|
||||
}
|
||||
@@ -3247,7 +3286,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// function declarations with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@@ -3271,7 +3310,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// function declarations with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@@ -3302,7 +3341,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// function declarations with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@@ -3317,7 +3356,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;
|
||||
@@ -3351,7 +3390,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// function declarations with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@@ -3393,7 +3432,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// function expressions with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@@ -3434,7 +3473,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// arrow functions with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (subtreeFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
@@ -3454,7 +3493,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;
|
||||
@@ -3470,7 +3511,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;
|
||||
@@ -3482,7 +3525,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;
|
||||
}
|
||||
|
||||
@@ -3731,11 +3774,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:
|
||||
@@ -3751,8 +3794,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;
|
||||
@@ -3765,13 +3808,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:
|
||||
@@ -3788,7 +3831,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;
|
||||
@@ -3799,7 +3842,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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
+1086
-973
File diff suppressed because it is too large
Load Diff
@@ -77,6 +77,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",
|
||||
@@ -96,13 +104,12 @@ namespace ts {
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Print_names_of_generated_files_part_of_the_compilation
|
||||
},
|
||||
|
||||
{
|
||||
name: "watch",
|
||||
shortName: "w",
|
||||
name: "traceResolution",
|
||||
type: "boolean",
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Command_line_Options,
|
||||
description: Diagnostics.Watch_input_files,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Enable_tracing_of_the_name_resolution_process
|
||||
},
|
||||
];
|
||||
|
||||
@@ -366,6 +373,14 @@ namespace ts {
|
||||
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",
|
||||
@@ -581,12 +596,6 @@ 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",
|
||||
@@ -1004,7 +1013,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++;
|
||||
@@ -1284,6 +1293,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));
|
||||
}
|
||||
|
||||
@@ -1520,7 +1532,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 {
|
||||
@@ -1653,7 +1670,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
else if (optionDefinition.type === "list") {
|
||||
return getCustomTypeMapOfCommandLineOption((<CommandLineOptionOfListType>optionDefinition).element);
|
||||
return getCustomTypeMapOfCommandLineOption(optionDefinition.element);
|
||||
}
|
||||
else {
|
||||
return (<CommandLineOptionOfCustomType>optionDefinition).type;
|
||||
@@ -1717,7 +1734,7 @@ namespace ts {
|
||||
case "object":
|
||||
return {};
|
||||
default:
|
||||
return (option as CommandLineOptionOfCustomType).type.keys().next().value;
|
||||
return option.type.keys().next().value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1886,7 +1903,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;
|
||||
@@ -1939,7 +1957,7 @@ 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));
|
||||
}
|
||||
|
||||
@@ -1974,13 +1992,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",
|
||||
@@ -1988,6 +2004,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;
|
||||
@@ -2030,7 +2067,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;
|
||||
@@ -2171,7 +2208,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getExtendedConfig(
|
||||
sourceFile: TsConfigSourceFile,
|
||||
sourceFile: TsConfigSourceFile | undefined,
|
||||
extendedConfigPath: string,
|
||||
host: ParseConfigHost,
|
||||
basePath: string,
|
||||
@@ -2180,7 +2217,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);
|
||||
@@ -2190,8 +2227,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)) {
|
||||
@@ -2304,7 +2341,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);
|
||||
}
|
||||
@@ -2475,11 +2512,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.
|
||||
@@ -2490,8 +2532,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.
|
||||
//
|
||||
@@ -2519,7 +2578,7 @@ namespace ts {
|
||||
const wildcardFiles = arrayFrom(wildcardFileMap.values());
|
||||
|
||||
return {
|
||||
fileNames: literalFiles.concat(wildcardFiles),
|
||||
fileNames: literalFiles.concat(wildcardFiles, arrayFrom(wildCardJsonFileMap.values())),
|
||||
wildcardDirectories,
|
||||
spec
|
||||
};
|
||||
@@ -2689,7 +2748,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) => {
|
||||
|
||||
@@ -220,7 +220,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.mark("beginEmitBodyWithDetachedCommetns");
|
||||
performance.mark("beginEmitBodyWithDetachedComments");
|
||||
}
|
||||
|
||||
if (!skipTrailingComments) {
|
||||
@@ -231,7 +231,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.measure("commentTime", "beginEmitBodyWithDetachedCommetns");
|
||||
performance.measure("commentTime", "beginEmitBodyWithDetachedComments");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-6
@@ -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`;
|
||||
}
|
||||
@@ -842,7 +842,7 @@ namespace ts {
|
||||
return deduplicateSorted(sort(array, comparer), equalityComparer || comparer);
|
||||
}
|
||||
|
||||
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 +852,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;
|
||||
}
|
||||
}
|
||||
@@ -1409,9 +1409,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 +1537,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 +1602,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) {
|
||||
@@ -2125,4 +2130,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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2112,6 +2112,14 @@
|
||||
"category": "Error",
|
||||
"code": 2585
|
||||
},
|
||||
"Enum type '{0}' circularly references itself.": {
|
||||
"category": "Error",
|
||||
"code": 2586
|
||||
},
|
||||
"JSDoc type '{0}' circularly references itself.": {
|
||||
"category": "Error",
|
||||
"code": 2587
|
||||
},
|
||||
"JSX element attributes type '{0}' may not be a union type.": {
|
||||
"category": "Error",
|
||||
"code": 2600
|
||||
@@ -2477,10 +2485,6 @@
|
||||
"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
|
||||
@@ -3755,6 +3759,14 @@
|
||||
"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
|
||||
},
|
||||
|
||||
"Projects to reference": {
|
||||
"category": "Message",
|
||||
@@ -3886,6 +3898,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",
|
||||
@@ -4145,6 +4161,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
|
||||
@@ -4659,5 +4679,13 @@
|
||||
"Convert all to async functions": {
|
||||
"category": "Message",
|
||||
"code": 95066
|
||||
},
|
||||
"Generate types for '{0}'": {
|
||||
"category": "Message",
|
||||
"code": 95067
|
||||
},
|
||||
"Generate types for all packages without types": {
|
||||
"category": "Message",
|
||||
"code": 95068
|
||||
}
|
||||
}
|
||||
|
||||
+29
-18
@@ -41,20 +41,25 @@ namespace ts {
|
||||
export function getOutputPathsFor(sourceFile: SourceFile | Bundle, host: EmitHost, forceDtsPaths: boolean): EmitFileNames {
|
||||
const options = host.getCompilerOptions();
|
||||
if (sourceFile.kind === SyntaxKind.Bundle) {
|
||||
const jsFilePath = options.outFile || options.out!;
|
||||
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
|
||||
const declarationFilePath = (forceDtsPaths || getEmitDeclarations(options)) ? removeFileExtension(jsFilePath) + Extension.Dts : undefined;
|
||||
const declarationMapPath = getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined;
|
||||
const outPath = options.outFile || options.out!;
|
||||
const jsFilePath = options.emitDeclarationOnly ? undefined : outPath;
|
||||
const sourceMapFilePath = jsFilePath && getSourceMapFilePath(jsFilePath, options);
|
||||
const declarationFilePath = (forceDtsPaths || getEmitDeclarations(options)) ? removeFileExtension(outPath) + Extension.Dts : undefined;
|
||||
const declarationMapPath = declarationFilePath && getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined;
|
||||
const bundleInfoPath = options.references && jsFilePath ? (removeFileExtension(jsFilePath) + infoExtension) : undefined;
|
||||
return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, bundleInfoPath };
|
||||
}
|
||||
else {
|
||||
const jsFilePath = getOwnEmitOutputFilePath(sourceFile.fileName, host, getOutputExtension(sourceFile, options));
|
||||
const sourceMapFilePath = isJsonSourceFile(sourceFile) ? undefined : getSourceMapFilePath(jsFilePath, options);
|
||||
const ownOutputFilePath = getOwnEmitOutputFilePath(sourceFile.fileName, host, getOutputExtension(sourceFile, options));
|
||||
// If json file emits to the same location skip writing it, if emitDeclarationOnly skip writing it
|
||||
const isJsonEmittedToSameLocation = isJsonSourceFile(sourceFile) &&
|
||||
comparePaths(sourceFile.fileName, ownOutputFilePath, host.getCurrentDirectory(), !host.useCaseSensitiveFileNames()) === Comparison.EqualTo;
|
||||
const jsFilePath = options.emitDeclarationOnly || isJsonEmittedToSameLocation ? undefined : ownOutputFilePath;
|
||||
const sourceMapFilePath = !jsFilePath || isJsonSourceFile(sourceFile) ? undefined : getSourceMapFilePath(jsFilePath, options);
|
||||
// For legacy reasons (ie, we have baselines capturing the behavior), js files don't report a .d.ts output path - this would only matter if `declaration` and `allowJs` were both on, which is currently an error
|
||||
const isJs = isSourceFileJS(sourceFile);
|
||||
const declarationFilePath = ((forceDtsPaths || getEmitDeclarations(options)) && !isJs) ? getDeclarationEmitOutputFilePath(sourceFile.fileName, host) : undefined;
|
||||
const declarationMapPath = getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined;
|
||||
const declarationMapPath = declarationFilePath && getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined;
|
||||
return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, bundleInfoPath: undefined };
|
||||
}
|
||||
}
|
||||
@@ -135,27 +140,33 @@ namespace ts {
|
||||
|
||||
if (!emitSkipped && emittedFilesList) {
|
||||
if (!emitOnlyDtsFiles) {
|
||||
emittedFilesList.push(jsFilePath);
|
||||
}
|
||||
if (sourceMapFilePath) {
|
||||
emittedFilesList.push(sourceMapFilePath);
|
||||
if (jsFilePath) {
|
||||
emittedFilesList.push(jsFilePath);
|
||||
}
|
||||
if (sourceMapFilePath) {
|
||||
emittedFilesList.push(sourceMapFilePath);
|
||||
}
|
||||
if (bundleInfoPath) {
|
||||
emittedFilesList.push(bundleInfoPath);
|
||||
}
|
||||
}
|
||||
if (declarationFilePath) {
|
||||
emittedFilesList.push(declarationFilePath);
|
||||
}
|
||||
if (bundleInfoPath) {
|
||||
emittedFilesList.push(bundleInfoPath);
|
||||
if (declarationMapPath) {
|
||||
emittedFilesList.push(declarationMapPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emitJsFileOrBundle(sourceFileOrBundle: SourceFile | Bundle, jsFilePath: string, sourceMapFilePath: string | undefined, bundleInfoPath: string | undefined) {
|
||||
// Make sure not to write js file and source map file if any of them cannot be written
|
||||
if (host.isEmitBlocked(jsFilePath) || compilerOptions.noEmit || compilerOptions.emitDeclarationOnly) {
|
||||
emitSkipped = true;
|
||||
function emitJsFileOrBundle(sourceFileOrBundle: SourceFile | Bundle, jsFilePath: string | undefined, sourceMapFilePath: string | undefined, bundleInfoPath: string | undefined) {
|
||||
if (emitOnlyDtsFiles || !jsFilePath) {
|
||||
return;
|
||||
}
|
||||
if (emitOnlyDtsFiles) {
|
||||
|
||||
// Make sure not to write js file and source map file if any of them cannot be written
|
||||
if ((jsFilePath && host.isEmitBlocked(jsFilePath)) || compilerOptions.noEmit) {
|
||||
emitSkipped = true;
|
||||
return;
|
||||
}
|
||||
// Transform the source files
|
||||
|
||||
@@ -235,7 +235,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
/* @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 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);
|
||||
return { kind: ValueKind.Object, name, members: flatMap(entries, ({ key, value }) => getValueInfo(key, value, recurser)) };
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -258,8 +258,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 +284,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 +298,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 +314,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 +341,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 +393,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 +414,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 +422,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 +432,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 +585,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 +621,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 +634,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -779,19 +840,28 @@ namespace ts {
|
||||
*/
|
||||
/* @internal */
|
||||
export function resolveJSModule(moduleName: string, initialDir: string, host: ModuleResolutionHost): string {
|
||||
const { resolvedModule, failedLookupLocations } =
|
||||
nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, /*jsOnly*/ true);
|
||||
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 {
|
||||
function tryResolveJSModuleWorker(moduleName: string, initialDir: string, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
|
||||
return nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, /*redirectedReference*/ undefined, /*jsOnly*/ true);
|
||||
}
|
||||
|
||||
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations {
|
||||
return nodeModuleNameResolverWorker(moduleName, getDirectoryPath(containingFile), compilerOptions, host, cache, redirectedReference, /*jsOnly*/ false);
|
||||
}
|
||||
|
||||
function nodeModuleNameResolverWorker(moduleName: string, containingDirectory: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined, jsOnly: boolean): ResolvedModuleWithFailedLookupLocations {
|
||||
const traceEnabled = isTraceEnabled(compilerOptions, host);
|
||||
|
||||
const failedLookupLocations: string[] = [];
|
||||
@@ -812,14 +882,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 +959,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`.
|
||||
@@ -1022,15 +1096,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;
|
||||
@@ -1090,22 +1155,12 @@ 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) {
|
||||
function loadNodeModuleFromDirectoryWorker(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState, jsonContent: PackageJsonPathFields | undefined, versionPaths: VersionPaths | undefined): PathAndExtension | undefined {
|
||||
const packageFile = jsonContent && (extensions !== Extensions.JavaScript && extensions !== Extensions.Json
|
||||
? readPackageJsonTypesFields(jsonContent, candidate, state) ||
|
||||
// When resolving typescript modules, try resolving using main field as well
|
||||
file = readPackageJsonMainField(jsonContent, candidate, state);
|
||||
if (!file) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
(extensions === Extensions.TypeScript ? readPackageJsonMainField(jsonContent, candidate, state) : undefined)
|
||||
: readPackageJsonMainField(jsonContent, candidate, state));
|
||||
|
||||
const loader: ResolutionKindSpecificLoader = (extensions, candidate, onlyRecordFailures, state) => {
|
||||
const fromFile = tryFile(candidate, onlyRecordFailures, state);
|
||||
@@ -1125,21 +1180,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, "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. */
|
||||
@@ -1171,17 +1231,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);
|
||||
@@ -1349,7 +1409,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 +1426,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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+34
-32
@@ -1482,7 +1482,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:
|
||||
@@ -6308,7 +6316,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 +6449,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 +6463,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;
|
||||
@@ -6517,7 +6520,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function skipWhitespaceOrAsterisk(next: () => void): void {
|
||||
function skipWhitespaceOrAsterisk(): void {
|
||||
if (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) {
|
||||
if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) {
|
||||
return; // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range
|
||||
@@ -6532,7 +6535,7 @@ namespace ts {
|
||||
else if (token() === SyntaxKind.AsteriskToken) {
|
||||
precedingLineBreak = false;
|
||||
}
|
||||
next();
|
||||
nextJSDocToken();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6542,9 +6545,8 @@ namespace ts {
|
||||
atToken.end = scanner.getTextPos();
|
||||
nextJSDocToken();
|
||||
|
||||
// Use 'nextToken' instead of 'nextJsDocToken' so we can parse a type like 'number' in `@enum number`
|
||||
const tagName = parseJSDocIdentifierName(/*message*/ undefined, nextToken);
|
||||
skipWhitespaceOrAsterisk(nextToken);
|
||||
const tagName = parseJSDocIdentifierName(/*message*/ undefined);
|
||||
skipWhitespaceOrAsterisk();
|
||||
|
||||
let tag: JSDocTag | undefined;
|
||||
switch (tagName.escapedText) {
|
||||
@@ -6688,7 +6690,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function tryParseTypeExpression(): JSDocTypeExpression | undefined {
|
||||
skipWhitespaceOrAsterisk(nextJSDocToken);
|
||||
skipWhitespaceOrAsterisk();
|
||||
return token() === SyntaxKind.OpenBraceToken ? parseJSDocTypeExpression() : undefined;
|
||||
}
|
||||
|
||||
@@ -6728,7 +6730,7 @@ namespace ts {
|
||||
function parseParameterOrPropertyTag(atToken: AtToken, tagName: Identifier, target: PropertyLikeParse, indent: number): JSDocParameterTag | JSDocPropertyTag {
|
||||
let typeExpression = tryParseTypeExpression();
|
||||
let isNameFirst = !typeExpression;
|
||||
skipWhitespaceOrAsterisk(nextJSDocToken);
|
||||
skipWhitespaceOrAsterisk();
|
||||
|
||||
const { name, isBracketed } = parseBracketNameInPropertyAndParamTag();
|
||||
skipWhitespace();
|
||||
@@ -6862,7 +6864,7 @@ namespace ts {
|
||||
|
||||
function parseTypedefTag(atToken: AtToken, tagName: Identifier, indent: number): JSDocTypedefTag {
|
||||
const typeExpression = tryParseTypeExpression();
|
||||
skipWhitespaceOrAsterisk(nextJSDocToken);
|
||||
skipWhitespaceOrAsterisk();
|
||||
|
||||
const typedefTag = <JSDocTypedefTag>createNode(SyntaxKind.JSDocTypedefTag, atToken.pos);
|
||||
typedefTag.atToken = atToken;
|
||||
@@ -7115,7 +7117,7 @@ namespace ts {
|
||||
return entity;
|
||||
}
|
||||
|
||||
function parseJSDocIdentifierName(message?: DiagnosticMessage, next: () => void = nextJSDocToken): Identifier {
|
||||
function parseJSDocIdentifierName(message?: DiagnosticMessage): Identifier {
|
||||
if (!tokenIsIdentifierOrKeyword(token())) {
|
||||
return createMissingNode<Identifier>(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ !message, message || Diagnostics.Identifier_expected);
|
||||
}
|
||||
@@ -7126,7 +7128,7 @@ namespace ts {
|
||||
result.escapedText = escapeLeadingUnderscores(scanner.getTokenText());
|
||||
finishNode(result, end);
|
||||
|
||||
next();
|
||||
nextJSDocToken();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -7725,7 +7727,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
|
||||
@@ -7780,7 +7782,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;
|
||||
@@ -7803,7 +7805,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": {
|
||||
@@ -7813,11 +7815,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;
|
||||
}
|
||||
@@ -7853,10 +7855,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;
|
||||
@@ -7883,10 +7885,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;
|
||||
}
|
||||
@@ -7905,9 +7907,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;
|
||||
@@ -7915,7 +7917,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;
|
||||
}
|
||||
|
||||
|
||||
+320
-165
@@ -207,7 +207,7 @@ namespace ts {
|
||||
...program.getSemanticDiagnostics(sourceFile, cancellationToken)
|
||||
];
|
||||
|
||||
if (program.getCompilerOptions().declaration) {
|
||||
if (getEmitDeclarations(program.getCompilerOptions())) {
|
||||
addRange(diagnostics, program.getDeclarationDiagnostics(sourceFile, cancellationToken));
|
||||
}
|
||||
|
||||
@@ -406,7 +406,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function loadWithLocalCache<T>(names: string[], containingFile: string, loader: (name: string, containingFile: string) => T): T[] {
|
||||
function loadWithLocalCache<T>(names: string[], containingFile: string, redirectedReference: ResolvedProjectReference | undefined, loader: (name: string, containingFile: string, redirectedReference: ResolvedProjectReference | undefined) => T): T[] {
|
||||
if (names.length === 0) {
|
||||
return [];
|
||||
}
|
||||
@@ -418,7 +418,7 @@ namespace ts {
|
||||
result = cache.get(name)!;
|
||||
}
|
||||
else {
|
||||
cache.set(name, result = loader(name, containingFile));
|
||||
cache.set(name, result = loader(name, containingFile, redirectedReference));
|
||||
}
|
||||
resolutions.push(result);
|
||||
}
|
||||
@@ -454,8 +454,10 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
let seenResolvedRefs: ResolvedProjectReference[] | undefined;
|
||||
|
||||
// If project references dont match
|
||||
if (!arrayIsEqualTo(program.getProjectReferences(), projectReferences)) {
|
||||
if (!arrayIsEqualTo(program.getProjectReferences(), projectReferences, projectReferenceUptoDate)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -483,10 +485,46 @@ namespace ts {
|
||||
|
||||
return true;
|
||||
|
||||
function sourceFileNotUptoDate(sourceFile: SourceFile): boolean {
|
||||
return sourceFile.version !== getSourceVersion(sourceFile.path) ||
|
||||
function sourceFileNotUptoDate(sourceFile: SourceFile) {
|
||||
return !sourceFileVersionUptoDate(sourceFile) ||
|
||||
hasInvalidatedResolution(sourceFile.path);
|
||||
}
|
||||
|
||||
function sourceFileVersionUptoDate(sourceFile: SourceFile) {
|
||||
return sourceFile.version === getSourceVersion(sourceFile.resolvedPath);
|
||||
}
|
||||
|
||||
function projectReferenceUptoDate(oldRef: ProjectReference, newRef: ProjectReference, index: number) {
|
||||
if (!projectReferenceIsEqualTo(oldRef, newRef)) {
|
||||
return false;
|
||||
}
|
||||
return resolvedProjectReferenceUptoDate(program!.getResolvedProjectReferences()![index], oldRef);
|
||||
}
|
||||
|
||||
function resolvedProjectReferenceUptoDate(oldResolvedRef: ResolvedProjectReference | undefined, oldRef: ProjectReference): boolean {
|
||||
if (oldResolvedRef) {
|
||||
if (contains(seenResolvedRefs, oldResolvedRef)) {
|
||||
// Assume true
|
||||
return true;
|
||||
}
|
||||
|
||||
// If sourceFile for the oldResolvedRef existed, check the version for uptodate
|
||||
if (!sourceFileVersionUptoDate(oldResolvedRef.sourceFile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add to seen before checking the referenced paths of this config file
|
||||
(seenResolvedRefs || (seenResolvedRefs = [])).push(oldResolvedRef);
|
||||
|
||||
// If child project references are upto date, this project reference is uptodate
|
||||
return !forEach(oldResolvedRef.references, (childResolvedRef, index) =>
|
||||
!resolvedProjectReferenceUptoDate(childResolvedRef, oldResolvedRef.commandLine.projectReferences![index]));
|
||||
}
|
||||
|
||||
// In old program, not able to resolve project reference path,
|
||||
// so if config file doesnt exist, it is uptodate.
|
||||
return !fileExists(resolveProjectReferencePath(oldRef));
|
||||
}
|
||||
}
|
||||
|
||||
export function getConfigFileParsingDiagnostics(configFileParseResult: ParsedCommandLine): ReadonlyArray<Diagnostic> {
|
||||
@@ -592,18 +630,17 @@ namespace ts {
|
||||
const programDiagnostics = createDiagnosticCollection();
|
||||
const currentDirectory = host.getCurrentDirectory();
|
||||
const supportedExtensions = getSupportedExtensions(options);
|
||||
const supportedExtensionsWithJsonIfResolveJsonModule = options.resolveJsonModule ? [...supportedExtensions, Extension.Json] : undefined;
|
||||
const supportedExtensionsWithJsonIfResolveJsonModule = getSuppoertedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions);
|
||||
|
||||
// Map storing if there is emit blocking diagnostics for given input
|
||||
const hasEmitBlockingDiagnostics = createMap<boolean>();
|
||||
let _compilerOptionsObjectLiteralSyntax: ObjectLiteralExpression | null | undefined;
|
||||
let _referencesArrayLiteralSyntax: ArrayLiteralExpression | null | undefined;
|
||||
|
||||
let moduleResolutionCache: ModuleResolutionCache | undefined;
|
||||
let resolveModuleNamesWorker: (moduleNames: string[], containingFile: string, reusedNames?: string[]) => ResolvedModuleFull[];
|
||||
let resolveModuleNamesWorker: (moduleNames: string[], containingFile: string, reusedNames?: string[], redirectedReference?: ResolvedProjectReference) => ResolvedModuleFull[];
|
||||
const hasInvalidatedResolution = host.hasInvalidatedResolution || returnFalse;
|
||||
if (host.resolveModuleNames) {
|
||||
resolveModuleNamesWorker = (moduleNames, containingFile, reusedNames) => host.resolveModuleNames!(Debug.assertEachDefined(moduleNames), containingFile, reusedNames).map(resolved => {
|
||||
resolveModuleNamesWorker = (moduleNames, containingFile, reusedNames, redirectedReference) => host.resolveModuleNames!(Debug.assertEachDefined(moduleNames), containingFile, reusedNames, redirectedReference).map(resolved => {
|
||||
// An older host may have omitted extension, in which case we should infer it from the file extension of resolvedFileName.
|
||||
if (!resolved || (resolved as ResolvedModuleFull).extension !== undefined) {
|
||||
return resolved as ResolvedModuleFull;
|
||||
@@ -615,17 +652,17 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
moduleResolutionCache = createModuleResolutionCache(currentDirectory, x => host.getCanonicalFileName(x));
|
||||
const loader = (moduleName: string, containingFile: string) => resolveModuleName(moduleName, containingFile, options, host, moduleResolutionCache).resolvedModule!; // TODO: GH#18217
|
||||
resolveModuleNamesWorker = (moduleNames, containingFile) => loadWithLocalCache<ResolvedModuleFull>(Debug.assertEachDefined(moduleNames), containingFile, loader);
|
||||
const loader = (moduleName: string, containingFile: string, redirectedReference: ResolvedProjectReference | undefined) => resolveModuleName(moduleName, containingFile, options, host, moduleResolutionCache, redirectedReference).resolvedModule!; // TODO: GH#18217
|
||||
resolveModuleNamesWorker = (moduleNames, containingFile, _reusedNames, redirectedReference) => loadWithLocalCache<ResolvedModuleFull>(Debug.assertEachDefined(moduleNames), containingFile, redirectedReference, loader);
|
||||
}
|
||||
|
||||
let resolveTypeReferenceDirectiveNamesWorker: (typeDirectiveNames: string[], containingFile: string) => ResolvedTypeReferenceDirective[];
|
||||
let resolveTypeReferenceDirectiveNamesWorker: (typeDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference) => ResolvedTypeReferenceDirective[];
|
||||
if (host.resolveTypeReferenceDirectives) {
|
||||
resolveTypeReferenceDirectiveNamesWorker = (typeDirectiveNames, containingFile) => host.resolveTypeReferenceDirectives!(Debug.assertEachDefined(typeDirectiveNames), containingFile);
|
||||
resolveTypeReferenceDirectiveNamesWorker = (typeDirectiveNames, containingFile, redirectedReference) => host.resolveTypeReferenceDirectives!(Debug.assertEachDefined(typeDirectiveNames), containingFile, redirectedReference);
|
||||
}
|
||||
else {
|
||||
const loader = (typesRef: string, containingFile: string) => resolveTypeReferenceDirective(typesRef, containingFile, options, host).resolvedTypeReferenceDirective!; // TODO: GH#18217
|
||||
resolveTypeReferenceDirectiveNamesWorker = (typeReferenceDirectiveNames, containingFile) => loadWithLocalCache<ResolvedTypeReferenceDirective>(Debug.assertEachDefined(typeReferenceDirectiveNames), containingFile, loader);
|
||||
const loader = (typesRef: string, containingFile: string, redirectedReference: ResolvedProjectReference | undefined) => resolveTypeReferenceDirective(typesRef, containingFile, options, host, redirectedReference).resolvedTypeReferenceDirective!; // TODO: GH#18217
|
||||
resolveTypeReferenceDirectiveNamesWorker = (typeReferenceDirectiveNames, containingFile, redirectedReference) => loadWithLocalCache<ResolvedTypeReferenceDirective>(Debug.assertEachDefined(typeReferenceDirectiveNames), containingFile, redirectedReference, loader);
|
||||
}
|
||||
|
||||
// Map from a stringified PackageId to the source file with that id.
|
||||
@@ -644,8 +681,8 @@ namespace ts {
|
||||
const filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? createMap<SourceFile>() : undefined;
|
||||
|
||||
// A parallel array to projectReferences storing the results of reading in the referenced tsconfig files
|
||||
let resolvedProjectReferences: (ResolvedProjectReference | undefined)[] | undefined = projectReferences ? [] : undefined;
|
||||
const projectReferenceRedirects: Map<string> = createMap();
|
||||
let resolvedProjectReferences: ReadonlyArray<ResolvedProjectReference | undefined> | undefined;
|
||||
let projectReferenceRedirects: Map<ResolvedProjectReference | false> | undefined;
|
||||
|
||||
const shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options);
|
||||
const structuralIsReused = tryReuseStructureFromOldProgram();
|
||||
@@ -654,15 +691,16 @@ namespace ts {
|
||||
processingOtherFiles = [];
|
||||
|
||||
if (projectReferences) {
|
||||
for (const ref of projectReferences) {
|
||||
const parsedRef = parseProjectReferenceConfigFile(ref);
|
||||
resolvedProjectReferences!.push(parsedRef);
|
||||
if (!resolvedProjectReferences) {
|
||||
resolvedProjectReferences = projectReferences.map(parseProjectReferenceConfigFile);
|
||||
}
|
||||
for (const parsedRef of resolvedProjectReferences) {
|
||||
if (parsedRef) {
|
||||
if (parsedRef.commandLine.options.outFile) {
|
||||
const dtsOutfile = changeExtension(parsedRef.commandLine.options.outFile, ".d.ts");
|
||||
const out = parsedRef.commandLine.options.outFile || parsedRef.commandLine.options.out;
|
||||
if (out) {
|
||||
const dtsOutfile = changeExtension(out, ".d.ts");
|
||||
processSourceFile(dtsOutfile, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, /*packageId*/ undefined);
|
||||
}
|
||||
addProjectReferenceRedirects(parsedRef.commandLine, projectReferenceRedirects);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -713,10 +751,18 @@ namespace ts {
|
||||
if (oldProgram && host.onReleaseOldSourceFile) {
|
||||
const oldSourceFiles = oldProgram.getSourceFiles();
|
||||
for (const oldSourceFile of oldSourceFiles) {
|
||||
if (!getSourceFile(oldSourceFile.path) || shouldCreateNewSourceFile) {
|
||||
host.onReleaseOldSourceFile(oldSourceFile, oldProgram.getCompilerOptions());
|
||||
const newFile = getSourceFileByPath(oldSourceFile.resolvedPath);
|
||||
if (shouldCreateNewSourceFile || !newFile ||
|
||||
// old file wasnt redirect but new file is
|
||||
(oldSourceFile.resolvedPath === oldSourceFile.path && newFile.resolvedPath !== oldSourceFile.path)) {
|
||||
host.onReleaseOldSourceFile(oldSourceFile, oldProgram.getCompilerOptions(), !!getSourceFileByPath(oldSourceFile.path));
|
||||
}
|
||||
}
|
||||
oldProgram.forEachResolvedProjectReference((resolvedProjectReference, resolvedProjectReferencePath) => {
|
||||
if (resolvedProjectReference && !getResolvedProjectReferenceByPath(resolvedProjectReferencePath)) {
|
||||
host.onReleaseOldSourceFile!(resolvedProjectReference.sourceFile, oldProgram!.getCompilerOptions(), /*hasSourceFileByPath*/ false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// unconditionally set oldProgram to undefined to prevent it from being captured in closure
|
||||
@@ -758,7 +804,11 @@ namespace ts {
|
||||
getConfigFileParsingDiagnostics,
|
||||
getResolvedModuleWithFailedLookupLocationsFromCache,
|
||||
getProjectReferences,
|
||||
getResolvedProjectReferences
|
||||
getResolvedProjectReferences,
|
||||
getProjectReferenceRedirect,
|
||||
getResolvedProjectReferenceToRedirect,
|
||||
getResolvedProjectReferenceByPath,
|
||||
forEachResolvedProjectReference
|
||||
};
|
||||
|
||||
verifyCompilerOptions();
|
||||
@@ -797,9 +847,9 @@ namespace ts {
|
||||
// If a rootDir is specified use it as the commonSourceDirectory
|
||||
commonSourceDirectory = getNormalizedAbsolutePath(options.rootDir, currentDirectory);
|
||||
}
|
||||
else if (options.composite) {
|
||||
else if (options.composite && options.configFilePath) {
|
||||
// Project compilations never infer their root from the input source paths
|
||||
commonSourceDirectory = getDirectoryPath(normalizeSlashes(options.configFilePath!)); // TODO: GH#18217
|
||||
commonSourceDirectory = getDirectoryPath(normalizeSlashes(options.configFilePath));
|
||||
checkSourceFilesBelongToPath(emittedFiles, commonSourceDirectory);
|
||||
}
|
||||
else {
|
||||
@@ -841,7 +891,7 @@ namespace ts {
|
||||
if (structuralIsReused === StructureIsReused.Not && !file.ambientModuleNames.length) {
|
||||
// If the old program state does not permit reusing resolutions and `file` does not contain locally defined ambient modules,
|
||||
// the best we can do is fallback to the default logic.
|
||||
return resolveModuleNamesWorker(moduleNames, containingFile);
|
||||
return resolveModuleNamesWorker(moduleNames, containingFile, /*reusedNames*/ undefined, getResolvedProjectReferenceToRedirect(file.originalFileName));
|
||||
}
|
||||
|
||||
const oldSourceFile = oldProgramState.program && oldProgramState.program.getSourceFile(containingFile);
|
||||
@@ -921,7 +971,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const resolutions = unknownModuleNames && unknownModuleNames.length
|
||||
? resolveModuleNamesWorker(unknownModuleNames, containingFile, reusedNames)
|
||||
? resolveModuleNamesWorker(unknownModuleNames, containingFile, reusedNames, getResolvedProjectReferenceToRedirect(file.originalFileName))
|
||||
: emptyArray;
|
||||
|
||||
// Combine results of resolutions and predicted results
|
||||
@@ -981,6 +1031,30 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function canReuseProjectReferences(): boolean {
|
||||
return !forEachProjectReference(
|
||||
oldProgram!.getProjectReferences(),
|
||||
oldProgram!.getResolvedProjectReferences(),
|
||||
(oldResolvedRef, index, parent) => {
|
||||
const newRef = (parent ? parent.commandLine.projectReferences : projectReferences)![index];
|
||||
const newResolvedRef = parseProjectReferenceConfigFile(newRef);
|
||||
if (oldResolvedRef) {
|
||||
// Resolved project reference has gone missing or changed
|
||||
return !newResolvedRef || newResolvedRef.sourceFile !== oldResolvedRef.sourceFile;
|
||||
}
|
||||
else {
|
||||
// A previously-unresolved reference may be resolved now
|
||||
return newResolvedRef !== undefined;
|
||||
}
|
||||
},
|
||||
(oldProjectReferences, parent) => {
|
||||
// If array of references is changed, we cant resue old program
|
||||
const newReferences = parent ? getResolvedProjectReferenceByPath(parent.sourceFile.path)!.commandLine.projectReferences : projectReferences;
|
||||
return !arrayIsEqualTo(oldProjectReferences, newReferences, projectReferenceIsEqualTo);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function tryReuseStructureFromOldProgram(): StructureIsReused {
|
||||
if (!oldProgram) {
|
||||
return StructureIsReused.Not;
|
||||
@@ -1006,43 +1080,15 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Check if any referenced project tsconfig files are different
|
||||
|
||||
// If array of references is changed, we cant resue old program
|
||||
const oldProjectReferences = oldProgram.getProjectReferences();
|
||||
if (!arrayIsEqualTo(oldProjectReferences!, projectReferences, projectReferenceIsEqualTo)) {
|
||||
if (!canReuseProjectReferences()) {
|
||||
return oldProgram.structureIsReused = StructureIsReused.Not;
|
||||
}
|
||||
|
||||
// Check the json files for the project references
|
||||
const oldRefs = oldProgram.getResolvedProjectReferences();
|
||||
if (projectReferences) {
|
||||
// Resolved project referenced should be array if projectReferences provided are array
|
||||
Debug.assert(!!oldRefs);
|
||||
for (let i = 0; i < projectReferences.length; i++) {
|
||||
const oldRef = oldRefs![i];
|
||||
const newRef = parseProjectReferenceConfigFile(projectReferences[i]);
|
||||
if (oldRef) {
|
||||
if (!newRef || newRef.sourceFile !== oldRef.sourceFile) {
|
||||
// Resolved project reference has gone missing or changed
|
||||
return oldProgram.structureIsReused = StructureIsReused.Not;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// A previously-unresolved reference may be resolved now
|
||||
if (newRef !== undefined) {
|
||||
return oldProgram.structureIsReused = StructureIsReused.Not;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Resolved project referenced should be undefined if projectReferences is undefined
|
||||
Debug.assert(!oldRefs);
|
||||
resolvedProjectReferences = projectReferences.map(parseProjectReferenceConfigFile);
|
||||
}
|
||||
|
||||
// check if program source files has changed in the way that can affect structure of the program
|
||||
const newSourceFiles: SourceFile[] = [];
|
||||
const filePaths: Path[] = [];
|
||||
const modifiedSourceFiles: { oldFile: SourceFile, newFile: SourceFile }[] = [];
|
||||
oldProgram.structureIsReused = StructureIsReused.Completely;
|
||||
|
||||
@@ -1059,7 +1105,7 @@ namespace ts {
|
||||
|
||||
for (const oldSourceFile of oldSourceFiles) {
|
||||
let newSourceFile = host.getSourceFileByPath
|
||||
? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.resolvedPath || oldSourceFile.path, options.target!, /*onError*/ undefined, shouldCreateNewSourceFile)
|
||||
? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.resolvedPath, options.target!, /*onError*/ undefined, shouldCreateNewSourceFile)
|
||||
: host.getSourceFile(oldSourceFile.fileName, options.target!, /*onError*/ undefined, shouldCreateNewSourceFile); // TODO: GH#18217
|
||||
|
||||
if (!newSourceFile) {
|
||||
@@ -1090,8 +1136,11 @@ namespace ts {
|
||||
fileChanged = newSourceFile !== oldSourceFile;
|
||||
}
|
||||
|
||||
// Since the project references havent changed, its right to set originalFileName and resolvedPath here
|
||||
newSourceFile.path = oldSourceFile.path;
|
||||
filePaths.push(newSourceFile.path);
|
||||
newSourceFile.originalFileName = oldSourceFile.originalFileName;
|
||||
newSourceFile.resolvedPath = oldSourceFile.resolvedPath;
|
||||
newSourceFile.fileName = oldSourceFile.fileName;
|
||||
|
||||
const packageName = oldProgram.sourceFileToPackageName.get(oldSourceFile.path);
|
||||
if (packageName !== undefined) {
|
||||
@@ -1167,7 +1216,7 @@ namespace ts {
|
||||
modifiedFilePaths = modifiedSourceFiles.map(f => f.newFile.path);
|
||||
// try to verify results of module resolution
|
||||
for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) {
|
||||
const newSourceFilePath = getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory);
|
||||
const newSourceFilePath = getNormalizedAbsolutePath(newSourceFile.originalFileName, currentDirectory);
|
||||
if (resolveModuleNamesWorker) {
|
||||
const moduleNames = getModuleNames(newSourceFile);
|
||||
const oldProgramState: OldProgramState = { program: oldProgram, oldSourceFile, modifiedFilePaths };
|
||||
@@ -1185,7 +1234,7 @@ namespace ts {
|
||||
if (resolveTypeReferenceDirectiveNamesWorker) {
|
||||
// We lower-case all type references because npm automatically lowercases all packages. See GH#9824.
|
||||
const typesReferenceDirectives = map(newSourceFile.typeReferenceDirectives, ref => ref.fileName.toLocaleLowerCase());
|
||||
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFilePath);
|
||||
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFilePath, getResolvedProjectReferenceToRedirect(newSourceFile.originalFileName));
|
||||
// ensure that types resolutions are still correct
|
||||
const resolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, resolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, typeDirectiveIsEqualTo);
|
||||
if (resolutionsChanged) {
|
||||
@@ -1209,11 +1258,12 @@ namespace ts {
|
||||
missingFilePaths = oldProgram.getMissingFilePaths();
|
||||
|
||||
// update fileName -> file mapping
|
||||
for (let i = 0; i < newSourceFiles.length; i++) {
|
||||
filesByName.set(filePaths[i], newSourceFiles[i]);
|
||||
for (const newSourceFile of newSourceFiles) {
|
||||
const filePath = newSourceFile.path;
|
||||
addFileToFilesByName(newSourceFile, filePath, newSourceFile.resolvedPath);
|
||||
// Set the file as found during node modules search if it was found that way in old progra,
|
||||
if (oldProgram.isSourceFileFromExternalLibrary(oldProgram.getSourceFileByPath(filePaths[i])!)) {
|
||||
sourceFilesFoundSearchingNodeModules.set(filePaths[i], true);
|
||||
if (oldProgram.isSourceFileFromExternalLibrary(oldProgram.getSourceFileByPath(filePath)!)) {
|
||||
sourceFilesFoundSearchingNodeModules.set(filePath, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1224,7 +1274,6 @@ namespace ts {
|
||||
fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile.newFile);
|
||||
}
|
||||
resolvedTypeReferenceDirectives = oldProgram.getResolvedTypeReferenceDirectives();
|
||||
resolvedProjectReferences = oldProgram.getResolvedProjectReferences();
|
||||
|
||||
sourceFileToPackageName = oldProgram.sourceFileToPackageName;
|
||||
redirectTargetsMap = oldProgram.redirectTargetsMap;
|
||||
@@ -1280,12 +1329,13 @@ namespace ts {
|
||||
const ref = projectReferences[i];
|
||||
const resolvedRefOpts = resolvedProjectReferences![i]!.commandLine;
|
||||
if (ref.prepend && resolvedRefOpts && resolvedRefOpts.options) {
|
||||
const out = resolvedRefOpts.options.outFile || resolvedRefOpts.options.out;
|
||||
// Upstream project didn't have outFile set -- skip (error will have been issued earlier)
|
||||
if (!resolvedRefOpts.options.outFile) continue;
|
||||
if (!out) continue;
|
||||
|
||||
const dtsFilename = changeExtension(resolvedRefOpts.options.outFile, ".d.ts");
|
||||
const js = host.readFile(resolvedRefOpts.options.outFile) || `/* Input file ${resolvedRefOpts.options.outFile} was missing */\r\n`;
|
||||
const jsMapPath = resolvedRefOpts.options.outFile + ".map"; // TODO: try to read sourceMappingUrl comment from the file
|
||||
const dtsFilename = changeExtension(out, ".d.ts");
|
||||
const js = host.readFile(out) || `/* Input file ${out} was missing */\r\n`;
|
||||
const jsMapPath = out + ".map"; // TODO: try to read sourceMappingUrl comment from the file
|
||||
const jsMap = host.readFile(jsMapPath);
|
||||
const dts = host.readFile(dtsFilename) || `/* Input file ${dtsFilename} was missing */\r\n`;
|
||||
const dtsMapPath = dtsFilename + ".map";
|
||||
@@ -1360,7 +1410,7 @@ namespace ts {
|
||||
...program.getSemanticDiagnostics(sourceFile, cancellationToken)
|
||||
];
|
||||
|
||||
if (diagnostics.length === 0 && program.getCompilerOptions().declaration) {
|
||||
if (diagnostics.length === 0 && getEmitDeclarations(program.getCompilerOptions())) {
|
||||
declarationDiagnostics = program.getDeclarationDiagnostics(/*sourceFile*/ undefined, cancellationToken);
|
||||
}
|
||||
|
||||
@@ -1778,11 +1828,22 @@ namespace ts {
|
||||
fileProcessingDiagnostics.getGlobalDiagnostics(),
|
||||
concatenate(
|
||||
programDiagnostics.getGlobalDiagnostics(),
|
||||
options.configFile ? programDiagnostics.getDiagnostics(options.configFile.fileName) : []
|
||||
getOptionsDiagnosticsOfConfigFile()
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
function getOptionsDiagnosticsOfConfigFile() {
|
||||
if (!options.configFile) { return emptyArray; }
|
||||
let diagnostics = programDiagnostics.getDiagnostics(options.configFile.fileName);
|
||||
forEachResolvedProjectReference(resolvedRef => {
|
||||
if (resolvedRef) {
|
||||
diagnostics = concatenate(diagnostics, programDiagnostics.getDiagnostics(resolvedRef.sourceFile.fileName));
|
||||
}
|
||||
});
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
function getGlobalDiagnostics(): Diagnostic[] {
|
||||
return sortAndDeduplicateDiagnostics(getDiagnosticsProducingTypeChecker().getGlobalDiagnostics().slice());
|
||||
}
|
||||
@@ -1933,7 +1994,7 @@ namespace ts {
|
||||
refFile?: SourceFile): SourceFile | undefined {
|
||||
|
||||
if (hasExtension(fileName)) {
|
||||
if (!options.allowNonTsExtensions && !forEach(supportedExtensionsWithJsonIfResolveJsonModule || supportedExtensions, extension => fileExtensionIs(host.getCanonicalFileName(fileName), extension))) {
|
||||
if (!options.allowNonTsExtensions && !forEach(supportedExtensionsWithJsonIfResolveJsonModule, extension => fileExtensionIs(host.getCanonicalFileName(fileName), extension))) {
|
||||
if (fail) fail(Diagnostics.File_0_has_unsupported_extension_The_only_supported_extensions_are_1, fileName, "'" + supportedExtensions.join("', '") + "'");
|
||||
return undefined;
|
||||
}
|
||||
@@ -1992,11 +2053,14 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function createRedirectSourceFile(redirectTarget: SourceFile, unredirected: SourceFile, fileName: string, path: Path): SourceFile {
|
||||
function createRedirectSourceFile(redirectTarget: SourceFile, unredirected: SourceFile, fileName: string, path: Path, resolvedPath: Path, originalFileName: string): SourceFile {
|
||||
const redirect: SourceFile = Object.create(redirectTarget);
|
||||
redirect.fileName = fileName;
|
||||
redirect.path = path;
|
||||
redirect.resolvedPath = resolvedPath;
|
||||
redirect.originalFileName = originalFileName;
|
||||
redirect.redirectInfo = { redirectTarget, unredirected };
|
||||
sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0);
|
||||
Object.defineProperties(redirect, {
|
||||
id: {
|
||||
get(this: SourceFile) { return this.redirectInfo!.redirectTarget.id; },
|
||||
@@ -2012,6 +2076,7 @@ namespace ts {
|
||||
|
||||
// Get source file from normalized fileName
|
||||
function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, ignoreNoDefaultLib: boolean, refFile: SourceFile, refPos: number, refEnd: number, packageId: PackageId | undefined): SourceFile | undefined {
|
||||
const originalFileName = fileName;
|
||||
if (filesByName.has(path)) {
|
||||
const file = filesByName.get(path);
|
||||
// try to check if we've already seen this file but with a different casing in path
|
||||
@@ -2053,7 +2118,7 @@ namespace ts {
|
||||
return file;
|
||||
}
|
||||
|
||||
let redirectedPath: string | undefined;
|
||||
let redirectedPath: Path | undefined;
|
||||
if (refFile) {
|
||||
const redirect = getProjectReferenceRedirect(fileName);
|
||||
if (redirect) {
|
||||
@@ -2085,9 +2150,9 @@ namespace ts {
|
||||
if (fileFromPackageId) {
|
||||
// Some other SourceFile already exists with this package name and version.
|
||||
// Instead of creating a duplicate, just redirect to the existing one.
|
||||
const dupFile = createRedirectSourceFile(fileFromPackageId, file!, fileName, path); // TODO: GH#18217
|
||||
const dupFile = createRedirectSourceFile(fileFromPackageId, file!, fileName, path, toPath(fileName), originalFileName); // TODO: GH#18217
|
||||
redirectTargetsMap.add(fileFromPackageId.path, fileName);
|
||||
filesByName.set(path, dupFile);
|
||||
addFileToFilesByName(dupFile, path, redirectedPath);
|
||||
sourceFileToPackageName.set(path, packageId.name);
|
||||
processingOtherFiles!.push(dupFile);
|
||||
return dupFile;
|
||||
@@ -2098,16 +2163,13 @@ namespace ts {
|
||||
sourceFileToPackageName.set(path, packageId.name);
|
||||
}
|
||||
}
|
||||
|
||||
filesByName.set(path, file);
|
||||
if (redirectedPath) {
|
||||
filesByName.set(redirectedPath, file);
|
||||
}
|
||||
addFileToFilesByName(file, path, redirectedPath);
|
||||
|
||||
if (file) {
|
||||
sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0);
|
||||
file.path = path;
|
||||
file.resolvedPath = toPath(fileName);
|
||||
file.originalFileName = originalFileName;
|
||||
|
||||
if (host.useCaseSensitiveFileNames()) {
|
||||
const pathLowerCase = path.toLowerCase();
|
||||
@@ -2144,26 +2206,112 @@ namespace ts {
|
||||
return file;
|
||||
}
|
||||
|
||||
function addFileToFilesByName(file: SourceFile | undefined, path: Path, redirectedPath: Path | undefined) {
|
||||
filesByName.set(path, file);
|
||||
if (redirectedPath) {
|
||||
filesByName.set(redirectedPath, file);
|
||||
}
|
||||
}
|
||||
|
||||
function getProjectReferenceRedirect(fileName: string): string | undefined {
|
||||
const path = toPath(fileName);
|
||||
// Ignore dts or any of the non ts files
|
||||
if (!resolvedProjectReferences || !resolvedProjectReferences.length || fileExtensionIs(fileName, Extension.Dts) || !fileExtensionIsOneOf(fileName, supportedTSExtensions)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// If this file is produced by a referenced project, we need to rewrite it to
|
||||
// look in the output folder of the referenced project rather than the input
|
||||
const normalized = getNormalizedAbsolutePath(fileName, path);
|
||||
let result: string | undefined;
|
||||
projectReferenceRedirects.forEach((v, k) => {
|
||||
if (result !== undefined) {
|
||||
const referencedProject = getResolvedProjectReferenceToRedirect(fileName);
|
||||
if (!referencedProject) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const out = referencedProject.commandLine.options.outFile || referencedProject.commandLine.options.out;
|
||||
return out ?
|
||||
changeExtension(out, Extension.Dts) :
|
||||
getOutputDeclarationFileName(fileName, referencedProject.commandLine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the referenced project if the file is input file from that reference project
|
||||
*/
|
||||
function getResolvedProjectReferenceToRedirect(fileName: string) {
|
||||
return forEachResolvedProjectReference((referencedProject, referenceProjectPath) => {
|
||||
// not input file from the referenced project, ignore
|
||||
if (!referencedProject ||
|
||||
toPath(options.configFilePath!) === referenceProjectPath ||
|
||||
!contains(referencedProject.commandLine.fileNames, fileName, isSameFile)) {
|
||||
return undefined;
|
||||
}
|
||||
if (normalized.indexOf(k) === 0) {
|
||||
result = changeExtension(fileName.replace(k, v), ".d.ts");
|
||||
}
|
||||
|
||||
return referencedProject;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
function forEachResolvedProjectReference<T>(
|
||||
cb: (resolvedProjectReference: ResolvedProjectReference | undefined, resolvedProjectReferencePath: Path) => T | undefined
|
||||
): T | undefined {
|
||||
return forEachProjectReference(projectReferences, resolvedProjectReferences, (resolvedRef, index, parent) => {
|
||||
const ref = (parent ? parent.commandLine.projectReferences : projectReferences)![index];
|
||||
const resolvedRefPath = toPath(resolveProjectReferencePath(ref));
|
||||
return cb(resolvedRef, resolvedRefPath);
|
||||
});
|
||||
}
|
||||
|
||||
function forEachProjectReference<T>(
|
||||
projectReferences: ReadonlyArray<ProjectReference> | undefined,
|
||||
resolvedProjectReferences: ReadonlyArray<ResolvedProjectReference | undefined> | undefined,
|
||||
cbResolvedRef: (resolvedRef: ResolvedProjectReference | undefined, index: number, parent: ResolvedProjectReference | undefined) => T | undefined,
|
||||
cbRef?: (projectReferences: ReadonlyArray<ProjectReference> | undefined, parent: ResolvedProjectReference | undefined) => T | undefined
|
||||
): T | undefined {
|
||||
let seenResolvedRefs: ResolvedProjectReference[] | undefined;
|
||||
|
||||
return worker(projectReferences, resolvedProjectReferences, /*parent*/ undefined, cbResolvedRef, cbRef);
|
||||
|
||||
function worker(
|
||||
projectReferences: ReadonlyArray<ProjectReference> | undefined,
|
||||
resolvedProjectReferences: ReadonlyArray<ResolvedProjectReference | undefined> | undefined,
|
||||
parent: ResolvedProjectReference | undefined,
|
||||
cbResolvedRef: (resolvedRef: ResolvedProjectReference | undefined, index: number, parent: ResolvedProjectReference | undefined) => T | undefined,
|
||||
cbRef?: (projectReferences: ReadonlyArray<ProjectReference> | undefined, parent: ResolvedProjectReference | undefined) => T | undefined,
|
||||
): T | undefined {
|
||||
|
||||
// Visit project references first
|
||||
if (cbRef) {
|
||||
const result = cbRef(projectReferences, parent);
|
||||
if (result) { return result; }
|
||||
}
|
||||
|
||||
return forEach(resolvedProjectReferences, (resolvedRef, index) => {
|
||||
if (contains(seenResolvedRefs, resolvedRef)) {
|
||||
// ignore recursives
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const result = cbResolvedRef(resolvedRef, index, parent);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!resolvedRef) return undefined;
|
||||
|
||||
(seenResolvedRefs || (seenResolvedRefs = [])).push(resolvedRef);
|
||||
return worker(resolvedRef.commandLine.projectReferences, resolvedRef.references, resolvedRef, cbResolvedRef, cbRef);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getResolvedProjectReferenceByPath(projectReferencePath: Path): ResolvedProjectReference | undefined {
|
||||
if (!projectReferenceRedirects) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return projectReferenceRedirects.get(projectReferencePath) || undefined;
|
||||
}
|
||||
|
||||
function processReferencedFiles(file: SourceFile, isDefaultLib: boolean) {
|
||||
forEach(file.referencedFiles, ref => {
|
||||
const referencedFileName = resolveTripleslashReference(ref.fileName, file.fileName);
|
||||
const referencedFileName = resolveTripleslashReference(ref.fileName, file.originalFileName);
|
||||
processSourceFile(referencedFileName, isDefaultLib, /*ignoreNoDefaultLib*/ false, /*packageId*/ undefined, file, ref.pos, ref.end);
|
||||
});
|
||||
}
|
||||
@@ -2175,7 +2323,7 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
|
||||
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeDirectives, file.fileName);
|
||||
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeDirectives, file.originalFileName, getResolvedProjectReferenceToRedirect(file.originalFileName));
|
||||
|
||||
for (let i = 0; i < typeDirectives.length; i++) {
|
||||
const ref = file.typeReferenceDirectives[i];
|
||||
@@ -2197,6 +2345,8 @@ namespace ts {
|
||||
}
|
||||
let saveResolution = true;
|
||||
if (resolvedTypeReferenceDirective) {
|
||||
if (resolvedTypeReferenceDirective.isExternalLibraryImport) currentNodeModulesDepth++;
|
||||
|
||||
if (resolvedTypeReferenceDirective.primary) {
|
||||
// resolved from the primary path
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName!, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile, refPos, refEnd); // TODO: GH#18217
|
||||
@@ -2225,6 +2375,8 @@ namespace ts {
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName!, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile, refPos, refEnd);
|
||||
}
|
||||
}
|
||||
|
||||
if (resolvedTypeReferenceDirective.isExternalLibraryImport) currentNodeModulesDepth--;
|
||||
}
|
||||
else {
|
||||
fileProcessingDiagnostics.add(createDiagnostic(refFile!, refPos!, refEnd!, Diagnostics.Cannot_find_type_definition_file_for_0, typeReferenceDirective)); // TODO: GH#18217
|
||||
@@ -2271,7 +2423,7 @@ namespace ts {
|
||||
// Because global augmentation doesn't have string literal name, we can check for global augmentation as such.
|
||||
const moduleNames = getModuleNames(file);
|
||||
const oldProgramState: OldProgramState = { program: oldProgram, oldSourceFile: oldProgram && oldProgram.getSourceFile(file.fileName), modifiedFilePaths };
|
||||
const resolutions = resolveModuleNamesReusingOldState(moduleNames, getNormalizedAbsolutePath(file.fileName, currentDirectory), file, oldProgramState);
|
||||
const resolutions = resolveModuleNamesReusingOldState(moduleNames, getNormalizedAbsolutePath(file.originalFileName, currentDirectory), file, oldProgramState);
|
||||
Debug.assert(resolutions.length === moduleNames.length);
|
||||
for (let i = 0; i < moduleNames.length; i++) {
|
||||
const resolution = resolutions[i];
|
||||
@@ -2348,29 +2500,37 @@ namespace ts {
|
||||
return allFilesBelongToPath;
|
||||
}
|
||||
|
||||
function parseProjectReferenceConfigFile(ref: ProjectReference): { commandLine: ParsedCommandLine, sourceFile: SourceFile } | undefined {
|
||||
function parseProjectReferenceConfigFile(ref: ProjectReference): ResolvedProjectReference | undefined {
|
||||
if (!projectReferenceRedirects) {
|
||||
projectReferenceRedirects = createMap<ResolvedProjectReference | false>();
|
||||
}
|
||||
|
||||
// The actual filename (i.e. add "/tsconfig.json" if necessary)
|
||||
const refPath = resolveProjectReferencePath(ref);
|
||||
const sourceFilePath = toPath(refPath);
|
||||
const fromCache = projectReferenceRedirects.get(sourceFilePath);
|
||||
if (fromCache !== undefined) {
|
||||
return fromCache || undefined;
|
||||
}
|
||||
|
||||
// An absolute path pointing to the containing directory of the config file
|
||||
const basePath = getNormalizedAbsolutePath(getDirectoryPath(refPath), host.getCurrentDirectory());
|
||||
const sourceFile = host.getSourceFile(refPath, ScriptTarget.JSON) as JsonSourceFile | undefined;
|
||||
addFileToFilesByName(sourceFile, sourceFilePath, /*redirectedPath*/ undefined);
|
||||
if (sourceFile === undefined) {
|
||||
projectReferenceRedirects.set(sourceFilePath, false);
|
||||
return undefined;
|
||||
}
|
||||
sourceFile.path = toPath(refPath);
|
||||
sourceFile.path = sourceFilePath;
|
||||
sourceFile.resolvedPath = sourceFilePath;
|
||||
sourceFile.originalFileName = refPath;
|
||||
const commandLine = parseJsonSourceFileConfigFileContent(sourceFile, configParsingHost, basePath, /*existingOptions*/ undefined, refPath);
|
||||
return { commandLine, sourceFile };
|
||||
}
|
||||
|
||||
function addProjectReferenceRedirects(referencedProject: ParsedCommandLine, target: Map<string>) {
|
||||
const rootDir = normalizePath(referencedProject.options.rootDir || getDirectoryPath(referencedProject.options.configFilePath!)); // TODO: GH#18217
|
||||
target.set(rootDir, getDeclarationOutputDirectory(referencedProject));
|
||||
}
|
||||
|
||||
function getDeclarationOutputDirectory(proj: ParsedCommandLine) {
|
||||
return proj.options.declarationDir ||
|
||||
proj.options.outDir ||
|
||||
getDirectoryPath(proj.options.configFilePath!); // TODO: GH#18217
|
||||
const resolvedRef: ResolvedProjectReference = { commandLine, sourceFile };
|
||||
projectReferenceRedirects.set(sourceFilePath, resolvedRef);
|
||||
if (commandLine.projectReferences) {
|
||||
resolvedRef.references = commandLine.projectReferences.map(parseProjectReferenceConfigFile);
|
||||
}
|
||||
return resolvedRef;
|
||||
}
|
||||
|
||||
function verifyCompilerOptions() {
|
||||
@@ -2379,8 +2539,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (options.isolatedModules) {
|
||||
if (options.declaration) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "declaration", "isolatedModules");
|
||||
if (getEmitDeclarations(options)) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, getEmitDeclarationOptionName(options), "isolatedModules");
|
||||
}
|
||||
|
||||
if (options.noEmitOnError) {
|
||||
@@ -2415,29 +2575,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (projectReferences) {
|
||||
for (let i = 0; i < projectReferences.length; i++) {
|
||||
const ref = projectReferences[i];
|
||||
const resolvedRefOpts = resolvedProjectReferences![i] && resolvedProjectReferences![i]!.commandLine.options;
|
||||
if (resolvedRefOpts === undefined) {
|
||||
createDiagnosticForReference(i, Diagnostics.File_0_does_not_exist, ref.path);
|
||||
continue;
|
||||
}
|
||||
if (!resolvedRefOpts.composite) {
|
||||
createDiagnosticForReference(i, Diagnostics.Referenced_project_0_must_have_setting_composite_Colon_true, ref.path);
|
||||
}
|
||||
if (ref.prepend) {
|
||||
if (resolvedRefOpts.outFile) {
|
||||
if (!host.fileExists(resolvedRefOpts.outFile)) {
|
||||
createDiagnosticForReference(i, Diagnostics.Output_file_0_from_project_1_does_not_exist, resolvedRefOpts.outFile, ref.path);
|
||||
}
|
||||
}
|
||||
else {
|
||||
createDiagnosticForReference(i, Diagnostics.Cannot_prepend_project_0_because_it_does_not_have_outFile_set, ref.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
verifyProjectReferences();
|
||||
|
||||
// List of collected files is complete; validate exhautiveness if this is a project with a file list
|
||||
if (options.composite) {
|
||||
@@ -2503,8 +2641,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (options.declarationDir) {
|
||||
if (!options.declaration) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "declarationDir", "declaration");
|
||||
if (!getEmitDeclarations(options)) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "declarationDir", "declaration", "composite");
|
||||
}
|
||||
if (options.out || options.outFile) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "declarationDir", options.out ? "out" : "outFile");
|
||||
@@ -2512,7 +2650,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (options.declarationMap && !getEmitDeclarations(options)) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "declarationMap", "declaration");
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "declarationMap", "declaration", "composite");
|
||||
}
|
||||
|
||||
if (options.lib && options.noLib) {
|
||||
@@ -2545,7 +2683,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Cannot specify module gen that isn't amd or system with --out
|
||||
if (outFile) {
|
||||
if (outFile && !options.emitDeclarationOnly) {
|
||||
if (options.module && !(options.module === ModuleKind.AMD || options.module === ModuleKind.System)) {
|
||||
createDiagnosticForOptionName(Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile", "module");
|
||||
}
|
||||
@@ -2580,8 +2718,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.noEmit && options.allowJs && options.declaration) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration");
|
||||
if (!options.noEmit && options.allowJs && getEmitDeclarations(options)) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", getEmitDeclarationOptionName(options));
|
||||
}
|
||||
|
||||
if (options.checkJs && !options.allowJs) {
|
||||
@@ -2589,8 +2727,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (options.emitDeclarationOnly) {
|
||||
if (!options.declaration) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDeclarationOnly", "declaration");
|
||||
if (!getEmitDeclarations(options)) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "emitDeclarationOnly", "declaration", "composite");
|
||||
}
|
||||
|
||||
if (options.noEmit) {
|
||||
@@ -2655,6 +2793,32 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function verifyProjectReferences() {
|
||||
forEachProjectReference(projectReferences, resolvedProjectReferences, (resolvedRef, index, parent) => {
|
||||
const ref = (parent ? parent.commandLine.projectReferences : projectReferences)![index];
|
||||
const parentFile = parent && parent.sourceFile as JsonSourceFile;
|
||||
if (!resolvedRef) {
|
||||
createDiagnosticForReference(parentFile, index, Diagnostics.File_0_not_found, ref.path);
|
||||
return;
|
||||
}
|
||||
const options = resolvedRef.commandLine.options;
|
||||
if (!options.composite) {
|
||||
createDiagnosticForReference(parentFile, index, Diagnostics.Referenced_project_0_must_have_setting_composite_Colon_true, ref.path);
|
||||
}
|
||||
if (ref.prepend) {
|
||||
const out = options.outFile || options.out;
|
||||
if (out) {
|
||||
if (!host.fileExists(out)) {
|
||||
createDiagnosticForReference(parentFile, index, Diagnostics.Output_file_0_from_project_1_does_not_exist, out, ref.path);
|
||||
}
|
||||
}
|
||||
else {
|
||||
createDiagnosticForReference(parentFile, index, Diagnostics.Cannot_prepend_project_0_because_it_does_not_have_outFile_set, ref.path);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function createDiagnosticForOptionPathKeyValue(key: string, valueIndex: number, message: DiagnosticMessage, arg0: string | number, arg1: string | number, arg2?: string | number) {
|
||||
let needCompilerDiagnostic = true;
|
||||
const pathsSyntax = getOptionPathsSyntax();
|
||||
@@ -2711,10 +2875,11 @@ namespace ts {
|
||||
createDiagnosticForOption(/*onKey*/ false, option1, /*option2*/ undefined, message, arg0);
|
||||
}
|
||||
|
||||
function createDiagnosticForReference(index: number, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number) {
|
||||
const referencesSyntax = getProjectReferencesSyntax();
|
||||
function createDiagnosticForReference(sourceFile: JsonSourceFile | undefined, index: number, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number) {
|
||||
const referencesSyntax = firstDefined(getTsConfigPropArray(sourceFile || options.configFile, "references"),
|
||||
property => isArrayLiteralExpression(property.initializer) ? property.initializer : undefined);
|
||||
if (referencesSyntax && referencesSyntax.elements.length > index) {
|
||||
programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile!, referencesSyntax.elements[index], message, arg0, arg1));
|
||||
programDiagnostics.add(createDiagnosticForNodeInSourceFile(sourceFile || options.configFile!, referencesSyntax.elements[index], message, arg0, arg1));
|
||||
}
|
||||
else {
|
||||
programDiagnostics.add(createCompilerDiagnostic(message, arg0, arg1));
|
||||
@@ -2731,22 +2896,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getProjectReferencesSyntax(): ArrayLiteralExpression | null {
|
||||
if (_referencesArrayLiteralSyntax === undefined) {
|
||||
_referencesArrayLiteralSyntax = null; // tslint:disable-line:no-null-keyword
|
||||
if (options.configFile) {
|
||||
const jsonObjectLiteral = getTsConfigObjectLiteralExpression(options.configFile)!; // TODO: GH#18217
|
||||
for (const prop of getPropertyAssignment(jsonObjectLiteral, "references")) {
|
||||
if (isArrayLiteralExpression(prop.initializer)) {
|
||||
_referencesArrayLiteralSyntax = prop.initializer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return _referencesArrayLiteralSyntax;
|
||||
}
|
||||
|
||||
function getCompilerOptionsObjectLiteralSyntax() {
|
||||
if (_compilerOptionsObjectLiteralSyntax === undefined) {
|
||||
_compilerOptionsObjectLiteralSyntax = null; // tslint:disable-line:no-null-keyword
|
||||
@@ -2821,7 +2970,10 @@ namespace ts {
|
||||
export function parseConfigHostFromCompilerHost(host: CompilerHost): ParseConfigFileHost {
|
||||
return {
|
||||
fileExists: f => host.fileExists(f),
|
||||
readDirectory: (root, extensions, includes, depth?) => host.readDirectory ? host.readDirectory(root, extensions, includes, depth) : [],
|
||||
readDirectory(root, extensions, excludes, includes, depth) {
|
||||
Debug.assertDefined(host.readDirectory, "'CompilerHost.readDirectory' must be implemented to correctly process 'projectReferences'");
|
||||
return host.readDirectory!(root, extensions, excludes, includes, depth);
|
||||
},
|
||||
readFile: f => host.readFile(f),
|
||||
useCaseSensitiveFileNames: host.useCaseSensitiveFileNames(),
|
||||
getCurrentDirectory: () => host.getCurrentDirectory(),
|
||||
@@ -2845,6 +2997,9 @@ namespace ts {
|
||||
return resolveConfigFileProjectName(passedInRef.path);
|
||||
}
|
||||
|
||||
function getEmitDeclarationOptionName(options: CompilerOptions) {
|
||||
return options.declaration ? "declaration" : "composite";
|
||||
}
|
||||
/* @internal */
|
||||
/**
|
||||
* Returns a DiagnosticMessage if we won't include a resolved module due to its extension.
|
||||
|
||||
@@ -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[];
|
||||
getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): CachedResolvedModuleWithFailedLookupLocations | undefined;
|
||||
resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): ResolvedTypeReferenceDirective[];
|
||||
|
||||
invalidateResolutionOfFile(filePath: Path): void;
|
||||
removeResolutionsOfFile(filePath: Path): void;
|
||||
removeResolutionsFromProjectReferenceRedirects(filePath: Path): void;
|
||||
setFilesWithInvalidatedNonRelativeUnresolvedImports(filesWithUnresolvedImports: Map<ReadonlyArray<string>>): void;
|
||||
createHasInvalidatedResolution(forceAllFilesAsInvalidated?: boolean): HasInvalidatedResolution;
|
||||
|
||||
@@ -90,17 +91,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 +129,7 @@ namespace ts {
|
||||
resolveModuleNames,
|
||||
getResolvedModuleWithFailedLookupLocationsFromCache,
|
||||
resolveTypeReferenceDirectives,
|
||||
removeResolutionsFromProjectReferenceRedirects,
|
||||
removeResolutionsOfFile,
|
||||
invalidateResolutionOfFile,
|
||||
setFilesWithInvalidatedNonRelativeUnresolvedImports,
|
||||
@@ -199,7 +201,7 @@ namespace ts {
|
||||
|
||||
function clearPerDirectoryResolutions() {
|
||||
perDirectoryResolvedModuleNames.clear();
|
||||
nonRelaticeModuleNameCache.clear();
|
||||
nonRelativeModuleNameCache.clear();
|
||||
perDirectoryResolvedTypeReferenceDirectives.clear();
|
||||
nonRelativeExternalModuleResolutions.forEach(watchFailedLookupLocationOfNonRelativeModuleResolutions);
|
||||
nonRelativeExternalModuleResolutions.clear();
|
||||
@@ -217,8 +219,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;
|
||||
@@ -242,9 +244,10 @@ namespace ts {
|
||||
function resolveNamesWithLocalCache<T extends ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName>(
|
||||
names: 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[] {
|
||||
@@ -252,6 +255,7 @@ namespace ts {
|
||||
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();
|
||||
@@ -260,12 +264,20 @@ namespace ts {
|
||||
const resolvedModules: R[] = [];
|
||||
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))) {
|
||||
const existingResolution = resolution;
|
||||
@@ -274,7 +286,7 @@ namespace ts {
|
||||
resolution = resolutionInDirectory;
|
||||
}
|
||||
else {
|
||||
resolution = loader(name, containingFile, compilerOptions, resolutionHost);
|
||||
resolution = loader(name, containingFile, compilerOptions, resolutionHost, redirectedReference);
|
||||
perDirectoryResolution.set(name, resolution);
|
||||
}
|
||||
resolutionsInFile.set(name, resolution);
|
||||
@@ -323,18 +335,18 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[] {
|
||||
function resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): ResolvedTypeReferenceDirective[] {
|
||||
return resolveNamesWithLocalCache<CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations, ResolvedTypeReferenceDirective>(
|
||||
typeDirectiveNames, containingFile,
|
||||
typeDirectiveNames, containingFile, redirectedReference,
|
||||
resolvedTypeReferenceDirectives, perDirectoryResolvedTypeReferenceDirectives,
|
||||
resolveTypeReferenceDirective, getResolvedTypeReferenceDirective,
|
||||
/*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[] {
|
||||
return resolveNamesWithLocalCache<CachedResolvedModuleWithFailedLookupLocations, ResolvedModuleFull>(
|
||||
moduleNames, containingFile,
|
||||
moduleNames, containingFile, redirectedReference,
|
||||
resolvedModuleNames, perDirectoryResolvedModuleNames,
|
||||
resolveModuleName, getResolvedModule,
|
||||
reusedNames, logChangesWhenResolvingModule
|
||||
@@ -398,7 +410,8 @@ namespace ts {
|
||||
|
||||
function getDirectoryToWatchFailedLookupLocation(failedLookupLocation: string, failedLookupLocationPath: Path): DirectoryOfFailedLookupWatch {
|
||||
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) {
|
||||
@@ -419,7 +432,7 @@ namespace ts {
|
||||
|
||||
function getDirectoryToWatchFromFailedLookupLocationDirectory(dir: string, dirPath: Path) {
|
||||
// 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);
|
||||
}
|
||||
@@ -593,6 +606,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);
|
||||
|
||||
+86
-80
@@ -60,81 +60,87 @@ 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,
|
||||
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,
|
||||
@@ -1288,15 +1294,15 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2016,7 +2022,7 @@ namespace ts {
|
||||
pos++;
|
||||
}
|
||||
tokenValue = text.substring(tokenPos, pos);
|
||||
return token = SyntaxKind.Identifier;
|
||||
return token = getIdentifierToken();
|
||||
}
|
||||
else {
|
||||
return token = SyntaxKind.Unknown;
|
||||
|
||||
+4
-22
@@ -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 */
|
||||
@@ -796,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);
|
||||
@@ -847,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", "");
|
||||
|
||||
@@ -275,7 +275,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) {
|
||||
|
||||
@@ -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.
|
||||
|
||||
+13
-13
@@ -248,7 +248,7 @@ namespace ts {
|
||||
return getOrCreateValueFromConfigFileMap<Map<T>>(configFileMap, resolved, createMap);
|
||||
}
|
||||
|
||||
function getOutputDeclarationFileName(inputFileName: string, configFile: ParsedCommandLine) {
|
||||
export function getOutputDeclarationFileName(inputFileName: string, configFile: ParsedCommandLine) {
|
||||
const relativePath = getRelativePathFromDirectory(rootDirOfOptions(configFile.options, configFile.options.configFilePath!), inputFileName, /*ignoreCase*/ true);
|
||||
const outputPath = resolvePath(configFile.options.declarationDir || configFile.options.outDir || getDirectoryPath(configFile.options.configFilePath!), relativePath);
|
||||
return changeExtension(outputPath, Extension.Dts);
|
||||
@@ -285,16 +285,17 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getOutFileOutputs(project: ParsedCommandLine): ReadonlyArray<string> {
|
||||
if (!project.options.outFile) {
|
||||
const out = project.options.outFile || project.options.out;
|
||||
if (!out) {
|
||||
return Debug.fail("outFile must be set");
|
||||
}
|
||||
const outputs: string[] = [];
|
||||
outputs.push(project.options.outFile);
|
||||
outputs.push(out);
|
||||
if (project.options.sourceMap) {
|
||||
outputs.push(`${project.options.outFile}.map`);
|
||||
outputs.push(`${out}.map`);
|
||||
}
|
||||
if (getEmitDeclarations(project.options)) {
|
||||
const dts = changeExtension(project.options.outFile, Extension.Dts);
|
||||
const dts = changeExtension(out, Extension.Dts);
|
||||
outputs.push(dts);
|
||||
if (project.options.declarationMap) {
|
||||
outputs.push(`${dts}.map`);
|
||||
@@ -862,7 +863,7 @@ namespace ts {
|
||||
if (buildProject) {
|
||||
buildSingleInvalidatedProject(buildProject.project, buildProject.reloadLevel);
|
||||
if (hasPendingInvalidatedProjects()) {
|
||||
if (!timerToBuildInvalidatedProject) {
|
||||
if (options.watch && !timerToBuildInvalidatedProject) {
|
||||
scheduleBuildInvalidatedProject();
|
||||
}
|
||||
}
|
||||
@@ -901,12 +902,7 @@ namespace ts {
|
||||
else if (reloadLevel === ConfigFileProgramReloadLevel.Partial) {
|
||||
// Update file names
|
||||
const result = getFileNamesFromConfigSpecs(proj.configFileSpecs!, getDirectoryPath(resolved), proj.options, parseConfigFileHost);
|
||||
if (result.fileNames.length !== 0) {
|
||||
filterMutate(proj.errors, error => !isErrorNoInputFiles(error));
|
||||
}
|
||||
else if (!proj.configFileSpecs!.filesSpecs && !some(proj.errors, isErrorNoInputFiles)) {
|
||||
proj.errors.push(getErrorForNoInputFiles(proj.configFileSpecs!, resolved));
|
||||
}
|
||||
updateErrorForNoInputFiles(result, resolved, proj.configFileSpecs!, proj.errors, canJsonReportNoInutFiles(proj.raw));
|
||||
proj.fileNames = result.fileNames;
|
||||
watchInputFiles(resolved, proj);
|
||||
}
|
||||
@@ -1001,6 +997,7 @@ namespace ts {
|
||||
return resultFlags;
|
||||
}
|
||||
if (configFile.fileNames.length === 0) {
|
||||
reportAndStoreErrors(proj, configFile.errors);
|
||||
// Nothing to build - must be a solution file, basically
|
||||
return BuildResultFlags.None;
|
||||
}
|
||||
@@ -1069,6 +1066,9 @@ namespace ts {
|
||||
type: UpToDateStatusType.UpToDate,
|
||||
newestDeclarationFileContentChangedTime: anyDtsChanged ? maximumDate : newestDeclarationFileContentChangedTime
|
||||
};
|
||||
if (options.watch) {
|
||||
diagnostics.removeKey(proj);
|
||||
}
|
||||
projectStatus.setValue(proj, status);
|
||||
return resultFlags;
|
||||
|
||||
@@ -1248,7 +1248,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getAllProjectOutputs(project: ParsedCommandLine): ReadonlyArray<string> {
|
||||
if (project.options.outFile) {
|
||||
if (project.options.outFile || project.options.out) {
|
||||
return getOutFileOutputs(project);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
"resolutionCache.ts",
|
||||
"moduleSpecifiers.ts",
|
||||
"watch.ts",
|
||||
"tsbuild.ts"
|
||||
"tsbuild.ts",
|
||||
"inspectValue.ts",
|
||||
]
|
||||
}
|
||||
|
||||
+173
-61
@@ -24,7 +24,84 @@ namespace ts {
|
||||
| SyntaxKind.DotToken
|
||||
| SyntaxKind.Identifier
|
||||
| SyntaxKind.NoSubstitutionTemplateLiteral
|
||||
| SyntaxKind.Unknown;
|
||||
| SyntaxKind.Unknown
|
||||
| KeywordSyntaxKind;
|
||||
|
||||
export type KeywordSyntaxKind =
|
||||
| SyntaxKind.AbstractKeyword
|
||||
| SyntaxKind.AnyKeyword
|
||||
| SyntaxKind.AsKeyword
|
||||
| SyntaxKind.BooleanKeyword
|
||||
| SyntaxKind.BreakKeyword
|
||||
| SyntaxKind.CaseKeyword
|
||||
| SyntaxKind.CatchKeyword
|
||||
| SyntaxKind.ClassKeyword
|
||||
| SyntaxKind.ContinueKeyword
|
||||
| SyntaxKind.ConstKeyword
|
||||
| SyntaxKind.ConstructorKeyword
|
||||
| SyntaxKind.DebuggerKeyword
|
||||
| SyntaxKind.DeclareKeyword
|
||||
| SyntaxKind.DefaultKeyword
|
||||
| SyntaxKind.DeleteKeyword
|
||||
| SyntaxKind.DoKeyword
|
||||
| SyntaxKind.ElseKeyword
|
||||
| SyntaxKind.EnumKeyword
|
||||
| SyntaxKind.ExportKeyword
|
||||
| SyntaxKind.ExtendsKeyword
|
||||
| SyntaxKind.FalseKeyword
|
||||
| SyntaxKind.FinallyKeyword
|
||||
| SyntaxKind.ForKeyword
|
||||
| SyntaxKind.FromKeyword
|
||||
| SyntaxKind.FunctionKeyword
|
||||
| SyntaxKind.GetKeyword
|
||||
| SyntaxKind.IfKeyword
|
||||
| SyntaxKind.ImplementsKeyword
|
||||
| SyntaxKind.ImportKeyword
|
||||
| SyntaxKind.InKeyword
|
||||
| SyntaxKind.InferKeyword
|
||||
| SyntaxKind.InstanceOfKeyword
|
||||
| SyntaxKind.InterfaceKeyword
|
||||
| SyntaxKind.IsKeyword
|
||||
| SyntaxKind.KeyOfKeyword
|
||||
| SyntaxKind.LetKeyword
|
||||
| SyntaxKind.ModuleKeyword
|
||||
| SyntaxKind.NamespaceKeyword
|
||||
| SyntaxKind.NeverKeyword
|
||||
| SyntaxKind.NewKeyword
|
||||
| SyntaxKind.NullKeyword
|
||||
| SyntaxKind.NumberKeyword
|
||||
| SyntaxKind.ObjectKeyword
|
||||
| SyntaxKind.PackageKeyword
|
||||
| SyntaxKind.PrivateKeyword
|
||||
| SyntaxKind.ProtectedKeyword
|
||||
| SyntaxKind.PublicKeyword
|
||||
| SyntaxKind.ReadonlyKeyword
|
||||
| SyntaxKind.RequireKeyword
|
||||
| SyntaxKind.GlobalKeyword
|
||||
| SyntaxKind.ReturnKeyword
|
||||
| SyntaxKind.SetKeyword
|
||||
| SyntaxKind.StaticKeyword
|
||||
| SyntaxKind.StringKeyword
|
||||
| SyntaxKind.SuperKeyword
|
||||
| SyntaxKind.SwitchKeyword
|
||||
| SyntaxKind.SymbolKeyword
|
||||
| SyntaxKind.ThisKeyword
|
||||
| SyntaxKind.ThrowKeyword
|
||||
| SyntaxKind.TrueKeyword
|
||||
| SyntaxKind.TryKeyword
|
||||
| SyntaxKind.TypeKeyword
|
||||
| SyntaxKind.TypeOfKeyword
|
||||
| SyntaxKind.UndefinedKeyword
|
||||
| SyntaxKind.UniqueKeyword
|
||||
| SyntaxKind.UnknownKeyword
|
||||
| SyntaxKind.VarKeyword
|
||||
| SyntaxKind.VoidKeyword
|
||||
| SyntaxKind.WhileKeyword
|
||||
| SyntaxKind.WithKeyword
|
||||
| SyntaxKind.YieldKeyword
|
||||
| SyntaxKind.AsyncKeyword
|
||||
| SyntaxKind.AwaitKeyword
|
||||
| SyntaxKind.OfKeyword;
|
||||
|
||||
export type JsxTokenSyntaxKind =
|
||||
| SyntaxKind.LessThanSlashToken
|
||||
@@ -713,7 +790,7 @@ namespace ts {
|
||||
|
||||
export type PropertyName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName;
|
||||
|
||||
export type DeclarationName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | BindingPattern;
|
||||
export type DeclarationName = Identifier | StringLiteralLike | NumericLiteral | ComputedPropertyName | BindingPattern;
|
||||
|
||||
export interface Declaration extends Node {
|
||||
_declarationBrand: any;
|
||||
@@ -1697,6 +1774,9 @@ namespace ts {
|
||||
arguments: NodeArray<Expression>;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export type BindableObjectDefinePropertyCall = CallExpression & { arguments: { 0: EntityNameExpression, 1: StringLiteralLike | NumericLiteral, 2: ObjectLiteralExpression } };
|
||||
|
||||
// see: https://tc39.github.io/ecma262/#prod-SuperCall
|
||||
export interface SuperCall extends CallExpression {
|
||||
expression: SuperExpression;
|
||||
@@ -1708,7 +1788,7 @@ namespace ts {
|
||||
|
||||
export interface ExpressionWithTypeArguments extends NodeWithTypeArguments {
|
||||
kind: SyntaxKind.ExpressionWithTypeArguments;
|
||||
parent: HeritageClause;
|
||||
parent: HeritageClause | JSDocAugmentsTag;
|
||||
expression: LeftHandSideExpression;
|
||||
}
|
||||
|
||||
@@ -2551,7 +2631,18 @@ namespace ts {
|
||||
fileName: string;
|
||||
/* @internal */ path: Path;
|
||||
text: string;
|
||||
/** Resolved path can be different from path property,
|
||||
* when file is included through project reference is mapped to its output instead of source
|
||||
* in that case resolvedPath = path to output file
|
||||
* path = input file's path
|
||||
*/
|
||||
/* @internal */ resolvedPath: Path;
|
||||
/** Original file name that can be different from fileName,
|
||||
* when file is included through project reference is mapped to its output instead of source
|
||||
* in that case originalFileName = name of input file
|
||||
* fileName = output file's name
|
||||
*/
|
||||
/* @internal */ originalFileName: string;
|
||||
|
||||
/**
|
||||
* If two source files are for the same version of the same package, one will redirect to the other.
|
||||
@@ -2818,7 +2909,11 @@ namespace ts {
|
||||
/* @internal */ getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations | undefined;
|
||||
|
||||
getProjectReferences(): ReadonlyArray<ProjectReference> | undefined;
|
||||
getResolvedProjectReferences(): (ResolvedProjectReference | undefined)[] | undefined;
|
||||
getResolvedProjectReferences(): ReadonlyArray<ResolvedProjectReference | undefined> | undefined;
|
||||
/*@internal*/ getProjectReferenceRedirect(fileName: string): string | undefined;
|
||||
/*@internal*/ getResolvedProjectReferenceToRedirect(fileName: string): ResolvedProjectReference | undefined;
|
||||
/*@internal*/ forEachResolvedProjectReference<T>(cb: (resolvedProjectReference: ResolvedProjectReference | undefined, resolvedProjectReferencePath: Path) => T | undefined): T | undefined;
|
||||
/*@internal*/ getResolvedProjectReferenceByPath(projectReferencePath: Path): ResolvedProjectReference | undefined;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -2827,6 +2922,7 @@ namespace ts {
|
||||
export interface ResolvedProjectReference {
|
||||
commandLine: ParsedCommandLine;
|
||||
sourceFile: SourceFile;
|
||||
references?: ReadonlyArray<ResolvedProjectReference | undefined>;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -2896,7 +2992,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface TypeCheckerHost {
|
||||
export interface TypeCheckerHost extends ModuleSpecifierResolutionHost {
|
||||
getCompilerOptions(): CompilerOptions;
|
||||
|
||||
getSourceFiles(): ReadonlyArray<SourceFile>;
|
||||
@@ -3014,8 +3110,6 @@ namespace ts {
|
||||
getExportsOfModule(moduleSymbol: Symbol): Symbol[];
|
||||
/** Unlike `getExportsOfModule`, this includes properties of an `export =` value. */
|
||||
/* @internal */ getExportsAndPropertiesOfModule(moduleSymbol: Symbol): Symbol[];
|
||||
|
||||
getAllAttributesTypeFromJsxOpeningLikeElement(elementNode: JsxOpeningLikeElement): Type | undefined;
|
||||
getJsxIntrinsicTagNamesAt(location: Node): Symbol[];
|
||||
isOptionalParameter(node: ParameterDeclaration): boolean;
|
||||
getAmbientModules(): Symbol[];
|
||||
@@ -3082,7 +3176,7 @@ namespace ts {
|
||||
* True if `contextualType` should not be considered for completions because
|
||||
* e.g. it specifies `kind: "a"` and obj has `kind: "b"`.
|
||||
*/
|
||||
/* @internal */ isTypeInvalidDueToUnionDiscriminant(contextualType: Type, obj: ObjectLiteralExpression): boolean;
|
||||
/* @internal */ isTypeInvalidDueToUnionDiscriminant(contextualType: Type, obj: ObjectLiteralExpression | JsxAttributes): boolean;
|
||||
/**
|
||||
* For a union, will include a property if it's defined in *any* of the member types.
|
||||
* So for `{ a } | { b }`, this will include both `a` and `b`.
|
||||
@@ -3171,6 +3265,8 @@ namespace ts {
|
||||
InTypeAlias = 1 << 23, // Writing type in type alias declaration
|
||||
InInitialEntityName = 1 << 24, // Set when writing the LHS of an entity name or entity name expression
|
||||
InReverseMappedType = 1 << 25,
|
||||
|
||||
/* @internal */ DoNotIncludeSymbolChain = 1 << 26, // Skip looking up and printing an accessible symbol chain
|
||||
}
|
||||
|
||||
// Ensure the shared flags between this and `NodeBuilderFlags` stay in alignment
|
||||
@@ -3233,6 +3329,9 @@ namespace ts {
|
||||
|
||||
// Prefer aliases which are not directly visible
|
||||
UseAliasDefinedOutsideCurrentScope = 0x00000008,
|
||||
|
||||
// Skip building an accessible symbol chain
|
||||
/* @internal */ DoNotIncludeSymbolChain = 0x00000010,
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -3408,6 +3507,7 @@ namespace ts {
|
||||
getJsxFactoryEntity(location?: Node): EntityName | undefined;
|
||||
getAllAccessorDeclarations(declaration: AccessorDeclaration): AllAccessorDeclarations;
|
||||
getSymbolOfExternalModuleSpecifier(node: StringLiteralLike): Symbol | undefined;
|
||||
isBindingCapturedByNode(node: Node, decl: VariableDeclaration | BindingElement): boolean;
|
||||
}
|
||||
|
||||
export const enum SymbolFlags {
|
||||
@@ -3523,6 +3623,7 @@ namespace ts {
|
||||
type?: Type; // Type of value symbol
|
||||
uniqueESSymbolType?: Type; // UniqueESSymbol type for a symbol
|
||||
declaredType?: Type; // Type of class, interface, enum, type alias, or type parameter
|
||||
resolvedJSDocType?: Type; // Resolved type of a JSDoc type reference
|
||||
typeParameters?: TypeParameter[]; // Type parameters of type alias (undefined if non-generic)
|
||||
outerTypeParameters?: TypeParameter[]; // Outer type parameters of anonymous object type
|
||||
inferredClassType?: Type; // Type of an inferred ES5 class
|
||||
@@ -3656,22 +3757,23 @@ namespace ts {
|
||||
EnumValuesComputed = 0x00004000, // Values for enum members have been computed, and any errors have been reported for them.
|
||||
LexicalModuleMergesWithClass = 0x00008000, // Instantiated lexical module declaration is merged with a previous class declaration.
|
||||
LoopWithCapturedBlockScopedBinding = 0x00010000, // Loop that contains block scoped variable captured in closure
|
||||
CapturedBlockScopedBinding = 0x00020000, // Block-scoped binding that is captured in some function
|
||||
BlockScopedBindingInLoop = 0x00040000, // Block-scoped binding with declaration nested inside iteration statement
|
||||
ClassWithBodyScopedClassBinding = 0x00080000, // Decorated class that contains a binding to itself inside of the class body.
|
||||
BodyScopedClassBinding = 0x00100000, // Binding to a decorated class inside of the class's body.
|
||||
NeedsLoopOutParameter = 0x00200000, // Block scoped binding whose value should be explicitly copied outside of the converted loop
|
||||
AssignmentsMarked = 0x00400000, // Parameter assignments have been marked
|
||||
ClassWithConstructorReference = 0x00800000, // Class that contains a binding to its constructor inside of the class body.
|
||||
ConstructorReferenceInClass = 0x01000000, // Binding to a class constructor inside of the class's body.
|
||||
ContainsCapturedBlockScopeBinding = 0x00020000, // Part of a loop that contains block scoped variable captured in closure
|
||||
CapturedBlockScopedBinding = 0x00040000, // Block-scoped binding that is captured in some function
|
||||
BlockScopedBindingInLoop = 0x00080000, // Block-scoped binding with declaration nested inside iteration statement
|
||||
ClassWithBodyScopedClassBinding = 0x00100000, // Decorated class that contains a binding to itself inside of the class body.
|
||||
BodyScopedClassBinding = 0x00200000, // Binding to a decorated class inside of the class's body.
|
||||
NeedsLoopOutParameter = 0x00400000, // Block scoped binding whose value should be explicitly copied outside of the converted loop
|
||||
AssignmentsMarked = 0x00800000, // Parameter assignments have been marked
|
||||
ClassWithConstructorReference = 0x01000000, // Class that contains a binding to its constructor inside of the class body.
|
||||
ConstructorReferenceInClass = 0x02000000, // Binding to a class constructor inside of the class's body.
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface NodeLinks {
|
||||
flags: NodeCheckFlags; // Set of flags specific to Node
|
||||
resolvedType?: Type; // Cached type of type node
|
||||
resolvedEnumType?: Type; // Cached constraint type from enum jsdoc tag
|
||||
resolvedSignature?: Signature; // Cached signature of signature node or call expression
|
||||
resolvedSignatures?: Map<Signature[]>; // Cached signatures of jsx node
|
||||
resolvedSymbol?: Symbol; // Cached name resolution result
|
||||
resolvedIndexInfo?: IndexInfo; // Cached indexing info resolution result
|
||||
maybeTypePredicate?: boolean; // Cached check whether call expression might reference a type predicate
|
||||
@@ -3687,6 +3789,8 @@ namespace ts {
|
||||
switchTypes?: Type[]; // Cached array of switch case expression types
|
||||
jsxNamespace?: Symbol | false; // Resolved jsx namespace symbol for this node
|
||||
contextFreeType?: Type; // Cached context-free type used by the first pass of inference; used when a function's return is partially contextually sensitive
|
||||
deferredNodes?: Map<Node>; // Set of nodes whose checking has been deferred
|
||||
capturedBlockScopeBindings?: Symbol[]; // Block-scoped bindings captured beneath this part of an IterationStatement
|
||||
}
|
||||
|
||||
export const enum TypeFlags {
|
||||
@@ -3974,6 +4078,7 @@ namespace ts {
|
||||
templateType?: Type;
|
||||
modifiersType?: Type;
|
||||
resolvedApparentType?: Type;
|
||||
instantiating?: boolean;
|
||||
}
|
||||
|
||||
export interface EvolvingArrayType extends ObjectType {
|
||||
@@ -4245,6 +4350,15 @@ namespace ts {
|
||||
Property,
|
||||
// F.prototype = { ... }
|
||||
Prototype,
|
||||
// Object.defineProperty(x, 'name', { value: any, writable?: boolean (false by default) });
|
||||
// Object.defineProperty(x, 'name', { get: Function, set: Function });
|
||||
// Object.defineProperty(x, 'name', { get: Function });
|
||||
// Object.defineProperty(x, 'name', { set: Function });
|
||||
ObjectDefinePropertyValue,
|
||||
// Object.defineProperty(exports || module.exports, 'name', ...);
|
||||
ObjectDefinePropertyExports,
|
||||
// Object.defineProperty(Foo.prototype, 'name', ...);
|
||||
ObjectDefinePrototypeProperty,
|
||||
}
|
||||
|
||||
/** @deprecated Use FileExtensionInfo instead. */
|
||||
@@ -4414,6 +4528,7 @@ namespace ts {
|
||||
sourceRoot?: string;
|
||||
strict?: boolean;
|
||||
strictFunctionTypes?: boolean; // Always combine with strict property
|
||||
strictBindCallApply?: boolean; // Always combine with strict property
|
||||
strictNullChecks?: boolean; // Always combine with strict property
|
||||
strictPropertyInitialization?: boolean; // Always combine with strict property
|
||||
stripInternal?: boolean;
|
||||
@@ -4827,6 +4942,8 @@ namespace ts {
|
||||
// The location of the .d.ts file we located, or undefined if resolution failed
|
||||
resolvedFileName: string | undefined;
|
||||
packageId?: PackageId;
|
||||
/** True if `resolvedFileName` comes from `node_modules`. */
|
||||
isExternalLibraryImport?: boolean;
|
||||
}
|
||||
|
||||
export interface ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
|
||||
@@ -4858,13 +4975,13 @@ namespace ts {
|
||||
* If resolveModuleNames is implemented then implementation for members from ModuleResolutionHost can be just
|
||||
* 'throw new Error("NotImplemented")'
|
||||
*/
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): (ResolvedModule | undefined)[];
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[], redirectedReference?: ResolvedProjectReference): (ResolvedModule | undefined)[];
|
||||
/**
|
||||
* This method is a companion for 'resolveModuleNames' and is used to resolve 'types' references to actual type declaration files
|
||||
*/
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): ResolvedTypeReferenceDirective[];
|
||||
getEnvironmentVariable?(name: string): string | undefined;
|
||||
/* @internal */ onReleaseOldSourceFile?(oldSourceFile: SourceFile, oldOptions: CompilerOptions): void;
|
||||
/* @internal */ onReleaseOldSourceFile?(oldSourceFile: SourceFile, oldOptions: CompilerOptions, hasSourceFileByPath: boolean): void;
|
||||
/* @internal */ hasInvalidatedResolution?: HasInvalidatedResolution;
|
||||
/* @internal */ hasChangedAutomaticTypeDirectiveNames?: boolean;
|
||||
createHash?(data: string): string;
|
||||
@@ -4891,25 +5008,21 @@ namespace ts {
|
||||
|
||||
// Markers
|
||||
// - Flags used to indicate that a subtree contains a specific transformation.
|
||||
ContainsDecorators = 1 << 12,
|
||||
ContainsPropertyInitializer = 1 << 13,
|
||||
ContainsLexicalThis = 1 << 14,
|
||||
ContainsCapturedLexicalThis = 1 << 15,
|
||||
ContainsLexicalThisInComputedPropertyName = 1 << 16,
|
||||
ContainsDefaultValueAssignments = 1 << 17,
|
||||
ContainsParameterPropertyAssignments = 1 << 18,
|
||||
ContainsSpread = 1 << 19,
|
||||
ContainsObjectSpread = 1 << 20,
|
||||
ContainsRest = ContainsSpread,
|
||||
ContainsObjectRest = ContainsObjectSpread,
|
||||
ContainsComputedPropertyName = 1 << 21,
|
||||
ContainsBlockScopedBinding = 1 << 22,
|
||||
ContainsBindingPattern = 1 << 23,
|
||||
ContainsYield = 1 << 24,
|
||||
ContainsHoistedDeclarationOrCompletion = 1 << 25,
|
||||
ContainsDynamicImport = 1 << 26,
|
||||
Super = 1 << 27,
|
||||
ContainsSuper = 1 << 28,
|
||||
ContainsTypeScriptClassSyntax = 1 << 12, // Decorators, Property Initializers, Parameter Property Initializers
|
||||
ContainsLexicalThis = 1 << 13,
|
||||
ContainsCapturedLexicalThis = 1 << 14,
|
||||
ContainsLexicalThisInComputedPropertyName = 1 << 15,
|
||||
ContainsDefaultValueAssignments = 1 << 16,
|
||||
ContainsRestOrSpread = 1 << 17,
|
||||
ContainsObjectRestOrSpread = 1 << 18,
|
||||
ContainsComputedPropertyName = 1 << 19,
|
||||
ContainsBlockScopedBinding = 1 << 20,
|
||||
ContainsBindingPattern = 1 << 21,
|
||||
ContainsYield = 1 << 22,
|
||||
ContainsHoistedDeclarationOrCompletion = 1 << 23,
|
||||
ContainsDynamicImport = 1 << 24,
|
||||
Super = 1 << 25,
|
||||
ContainsSuper = 1 << 26,
|
||||
|
||||
// Please leave this as 1 << 29.
|
||||
// It is the maximum bit we can set before we outgrow the size of a v8 small integer (SMI) on an x86 system.
|
||||
@@ -4933,23 +5046,22 @@ namespace ts {
|
||||
OuterExpressionExcludes = TypeScript | ES2015 | DestructuringAssignment | Generator | HasComputedFlags,
|
||||
PropertyAccessExcludes = OuterExpressionExcludes | Super,
|
||||
NodeExcludes = PropertyAccessExcludes | ContainsSuper,
|
||||
ArrowFunctionExcludes = NodeExcludes | ContainsDecorators | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRest,
|
||||
FunctionExcludes = NodeExcludes | ContainsDecorators | ContainsDefaultValueAssignments | ContainsCapturedLexicalThis | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRest,
|
||||
ConstructorExcludes = NodeExcludes | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRest,
|
||||
MethodOrAccessorExcludes = NodeExcludes | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRest,
|
||||
ClassExcludes = NodeExcludes | ContainsDecorators | ContainsPropertyInitializer | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsComputedPropertyName | ContainsParameterPropertyAssignments | ContainsLexicalThisInComputedPropertyName,
|
||||
ModuleExcludes = NodeExcludes | ContainsDecorators | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsHoistedDeclarationOrCompletion,
|
||||
ArrowFunctionExcludes = NodeExcludes | ContainsTypeScriptClassSyntax | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRestOrSpread,
|
||||
FunctionExcludes = NodeExcludes | ContainsTypeScriptClassSyntax | ContainsDefaultValueAssignments | ContainsCapturedLexicalThis | ContainsLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRestOrSpread,
|
||||
ConstructorExcludes = NodeExcludes | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRestOrSpread,
|
||||
MethodOrAccessorExcludes = NodeExcludes | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRestOrSpread,
|
||||
ClassExcludes = NodeExcludes | ContainsTypeScriptClassSyntax | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsComputedPropertyName | ContainsLexicalThisInComputedPropertyName,
|
||||
ModuleExcludes = NodeExcludes | ContainsTypeScriptClassSyntax | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsHoistedDeclarationOrCompletion,
|
||||
TypeExcludes = ~ContainsTypeScript,
|
||||
ObjectLiteralExcludes = NodeExcludes | ContainsDecorators | ContainsComputedPropertyName | ContainsLexicalThisInComputedPropertyName | ContainsObjectSpread,
|
||||
ArrayLiteralOrCallOrNewExcludes = NodeExcludes | ContainsSpread,
|
||||
VariableDeclarationListExcludes = NodeExcludes | ContainsBindingPattern | ContainsObjectRest,
|
||||
ObjectLiteralExcludes = NodeExcludes | ContainsTypeScriptClassSyntax | ContainsComputedPropertyName | ContainsLexicalThisInComputedPropertyName | ContainsObjectRestOrSpread,
|
||||
ArrayLiteralOrCallOrNewExcludes = NodeExcludes | ContainsRestOrSpread,
|
||||
VariableDeclarationListExcludes = NodeExcludes | ContainsBindingPattern | ContainsObjectRestOrSpread,
|
||||
ParameterExcludes = NodeExcludes,
|
||||
CatchClauseExcludes = NodeExcludes | ContainsObjectRest,
|
||||
BindingPatternExcludes = NodeExcludes | ContainsRest,
|
||||
CatchClauseExcludes = NodeExcludes | ContainsObjectRestOrSpread,
|
||||
BindingPatternExcludes = NodeExcludes | ContainsRestOrSpread,
|
||||
|
||||
// Masks
|
||||
// - Additional bitmasks
|
||||
TypeScriptClassSyntaxMask = ContainsParameterPropertyAssignments | ContainsPropertyInitializer | ContainsDecorators,
|
||||
ES2015FunctionSyntaxMask = ContainsCapturedLexicalThis | ContainsDefaultValueAssignments,
|
||||
}
|
||||
|
||||
@@ -5365,7 +5477,7 @@ namespace ts {
|
||||
reportInaccessibleThisError?(): void;
|
||||
reportPrivateInBaseOfClassExpression?(propertyName: string): void;
|
||||
reportInaccessibleUniqueSymbolError?(): void;
|
||||
moduleResolverHost?: EmitHost;
|
||||
moduleResolverHost?: ModuleSpecifierResolutionHost & { getSourceFiles(): ReadonlyArray<SourceFile>, getCommonSourceDirectory(): string };
|
||||
trackReferencedAmbientModule?(decl: ModuleDeclaration, symbol: Symbol): void;
|
||||
trackExternalModuleSymbolOfImportTypeNode?(symbol: Symbol): void;
|
||||
}
|
||||
@@ -5599,15 +5711,15 @@ namespace ts {
|
||||
type ConcretePragmaSpecs = typeof commentPragmas;
|
||||
|
||||
/* @internal */
|
||||
export type PragmaPsuedoMap = {[K in keyof ConcretePragmaSpecs]?: {arguments: PragmaArgumentType<ConcretePragmaSpecs[K]>, range: CommentRange}};
|
||||
export type PragmaPseudoMap = {[K in keyof ConcretePragmaSpecs]?: {arguments: PragmaArgumentType<ConcretePragmaSpecs[K]>, range: CommentRange}};
|
||||
|
||||
/* @internal */
|
||||
export type PragmaPsuedoMapEntry = {[K in keyof PragmaPsuedoMap]: {name: K, args: PragmaPsuedoMap[K]}}[keyof PragmaPsuedoMap];
|
||||
export type PragmaPseudoMapEntry = {[K in keyof PragmaPseudoMap]: {name: K, args: PragmaPseudoMap[K]}}[keyof PragmaPseudoMap];
|
||||
|
||||
/* @internal */
|
||||
export interface ReadonlyPragmaMap extends ReadonlyMap<PragmaPsuedoMap[keyof PragmaPsuedoMap] | PragmaPsuedoMap[keyof PragmaPsuedoMap][]> {
|
||||
get<TKey extends keyof PragmaPsuedoMap>(key: TKey): PragmaPsuedoMap[TKey] | PragmaPsuedoMap[TKey][];
|
||||
forEach(action: <TKey extends keyof PragmaPsuedoMap>(value: PragmaPsuedoMap[TKey] | PragmaPsuedoMap[TKey][], key: TKey) => void): void;
|
||||
export interface ReadonlyPragmaMap extends ReadonlyMap<PragmaPseudoMap[keyof PragmaPseudoMap] | PragmaPseudoMap[keyof PragmaPseudoMap][]> {
|
||||
get<TKey extends keyof PragmaPseudoMap>(key: TKey): PragmaPseudoMap[TKey] | PragmaPseudoMap[TKey][];
|
||||
forEach(action: <TKey extends keyof PragmaPseudoMap>(value: PragmaPseudoMap[TKey] | PragmaPseudoMap[TKey][], key: TKey) => void): void;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5616,10 +5728,10 @@ namespace ts {
|
||||
* in multiple places
|
||||
*/
|
||||
/* @internal */
|
||||
export interface PragmaMap extends Map<PragmaPsuedoMap[keyof PragmaPsuedoMap] | PragmaPsuedoMap[keyof PragmaPsuedoMap][]>, ReadonlyPragmaMap {
|
||||
set<TKey extends keyof PragmaPsuedoMap>(key: TKey, value: PragmaPsuedoMap[TKey] | PragmaPsuedoMap[TKey][]): this;
|
||||
get<TKey extends keyof PragmaPsuedoMap>(key: TKey): PragmaPsuedoMap[TKey] | PragmaPsuedoMap[TKey][];
|
||||
forEach(action: <TKey extends keyof PragmaPsuedoMap>(value: PragmaPsuedoMap[TKey] | PragmaPsuedoMap[TKey][], key: TKey) => void): void;
|
||||
export interface PragmaMap extends Map<PragmaPseudoMap[keyof PragmaPseudoMap] | PragmaPseudoMap[keyof PragmaPseudoMap][]>, ReadonlyPragmaMap {
|
||||
set<TKey extends keyof PragmaPseudoMap>(key: TKey, value: PragmaPseudoMap[TKey] | PragmaPseudoMap[TKey][]): this;
|
||||
get<TKey extends keyof PragmaPseudoMap>(key: TKey): PragmaPseudoMap[TKey] | PragmaPseudoMap[TKey][];
|
||||
forEach(action: <TKey extends keyof PragmaPseudoMap>(value: PragmaPseudoMap[TKey] | PragmaPseudoMap[TKey][], key: TKey) => void): void;
|
||||
}
|
||||
|
||||
export interface UserPreferences {
|
||||
|
||||
+80
-29
@@ -765,12 +765,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!
|
||||
@@ -978,6 +979,7 @@ namespace ts {
|
||||
case SyntaxKind.StringKeyword:
|
||||
case SyntaxKind.BooleanKeyword:
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
case SyntaxKind.ObjectKeyword:
|
||||
case SyntaxKind.UndefinedKeyword:
|
||||
case SyntaxKind.NeverKeyword:
|
||||
return true;
|
||||
@@ -1769,7 +1771,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 */
|
||||
@@ -1904,12 +1906,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;
|
||||
@@ -1926,7 +1951,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;
|
||||
}
|
||||
@@ -3244,7 +3269,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export interface EmitFileNames {
|
||||
jsFilePath: string;
|
||||
jsFilePath: string | undefined;
|
||||
sourceMapFilePath: string | undefined;
|
||||
declarationFilePath: string | undefined;
|
||||
declarationMapPath: string | undefined;
|
||||
@@ -3265,7 +3290,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));
|
||||
@@ -3734,11 +3759,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>;
|
||||
@@ -3765,15 +3799,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);
|
||||
}
|
||||
@@ -4976,14 +5001,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;
|
||||
}
|
||||
@@ -7077,16 +7107,15 @@ 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];
|
||||
@@ -7738,7 +7767,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"): string[] | undefined {
|
||||
if (specs === undefined || specs.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -8003,11 +8032,13 @@ namespace ts {
|
||||
* List of supported extensions in order of file resolution precedence.
|
||||
*/
|
||||
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 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, extraFileExtensions?: ReadonlyArray<FileExtensionInfo>): ReadonlyArray<string> {
|
||||
const needJsExtensions = options && options.allowJs;
|
||||
@@ -8024,6 +8055,13 @@ namespace ts {
|
||||
return deduplicate<string>(extensions, equateStringsCaseSensitive, compareStringsCaseSensitive);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -8043,7 +8081,8 @@ namespace ts {
|
||||
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;
|
||||
}
|
||||
@@ -8370,4 +8409,16 @@ namespace ts {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+20
-19
@@ -338,9 +338,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[];
|
||||
/** 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[];
|
||||
}
|
||||
|
||||
/** Internal interface used to wire emit through same host */
|
||||
@@ -469,7 +469,8 @@ namespace ts {
|
||||
const { configFileName, optionsToExtend: optionsToExtendForConfigFile = {}, createProgram } = 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);
|
||||
@@ -546,7 +547,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 ?
|
||||
@@ -556,11 +558,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();
|
||||
@@ -762,8 +764,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
|
||||
@@ -777,8 +779,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -828,12 +832,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;
|
||||
@@ -866,7 +865,8 @@ namespace ts {
|
||||
compilerOptions = configFileParseResult.options;
|
||||
configFileSpecs = configFileParseResult.configFileSpecs!; // TODO: GH#18217
|
||||
projectReferences = configFileParseResult.projectReferences;
|
||||
configFileParsingDiagnostics = getConfigFileParsingDiagnostics(configFileParseResult);
|
||||
configFileParsingDiagnostics = getConfigFileParsingDiagnostics(configFileParseResult).slice();
|
||||
canConfigFileJsonReportNoInputFiles = canJsonReportNoInutFiles(configFileParseResult.raw);
|
||||
hasChangedConfigFileParsingErrors = true;
|
||||
}
|
||||
|
||||
@@ -877,6 +877,7 @@ namespace ts {
|
||||
if (eventKind === FileWatcherEventKind.Deleted && sourceFilesCache.get(path)) {
|
||||
resolutionCache.invalidateResolutionOfFile(path);
|
||||
}
|
||||
resolutionCache.removeResolutionsFromProjectReferenceRedirects(path);
|
||||
nextSourceFileVersion(path);
|
||||
|
||||
// Update the program
|
||||
|
||||
+35
-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);
|
||||
}
|
||||
|
||||
|
||||
+64
-31
@@ -1181,12 +1181,7 @@ namespace FourSlash {
|
||||
}));
|
||||
|
||||
for (const start of toArray<string | Range>(starts)) {
|
||||
if (typeof start === "string") {
|
||||
this.goToMarker(start);
|
||||
}
|
||||
else {
|
||||
this.goToRangeStart(start);
|
||||
}
|
||||
this.goToMarkerOrRange(start);
|
||||
const fullActual = ts.map<ts.ReferencedSymbol, ReferenceGroupJson>(this.findReferencesAtCaret(), ({ definition, references }, i) => {
|
||||
const text = definition.displayParts.map(d => d.text).join("");
|
||||
return {
|
||||
@@ -1203,15 +1198,7 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
public verifyNoReferences(markerNameOrRange?: string | Range) {
|
||||
if (markerNameOrRange) {
|
||||
if (ts.isString(markerNameOrRange)) {
|
||||
this.goToMarker(markerNameOrRange);
|
||||
}
|
||||
else {
|
||||
this.goToRangeStart(markerNameOrRange);
|
||||
}
|
||||
}
|
||||
|
||||
if (markerNameOrRange) this.goToMarkerOrRange(markerNameOrRange);
|
||||
const refs = this.getReferencesAtCaret();
|
||||
if (refs && refs.length) {
|
||||
this.raiseError(`Expected getReferences to fail, but saw references: ${stringify(refs)}`);
|
||||
@@ -1328,8 +1315,10 @@ Actual: ${stringify(fullActual)}`);
|
||||
})));
|
||||
}
|
||||
|
||||
public verifyQuickInfoAt(markerName: string, expectedText: string, expectedDocumentation?: string) {
|
||||
this.goToMarker(markerName);
|
||||
public verifyQuickInfoAt(markerName: string | Range, expectedText: string, expectedDocumentation?: string) {
|
||||
if (typeof markerName === "string") this.goToMarker(markerName);
|
||||
else this.goToRangeStart(markerName);
|
||||
|
||||
this.verifyQuickInfoString(expectedText, expectedDocumentation);
|
||||
}
|
||||
|
||||
@@ -1395,7 +1384,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
}
|
||||
|
||||
public verifyRenameLocations(startRanges: ArrayOrSingle<Range>, options: ReadonlyArray<Range> | { findInStrings?: boolean, findInComments?: boolean, ranges: ReadonlyArray<Range> }) {
|
||||
public verifyRenameLocations(startRanges: ArrayOrSingle<Range>, options: FourSlashInterface.RenameLocationsOptions) {
|
||||
const { findInStrings = false, findInComments = false, ranges = this.getRanges() } = ts.isArray(options) ? { findInStrings: false, findInComments: false, ranges: options } : options;
|
||||
|
||||
for (const startRange of toArray(startRanges)) {
|
||||
@@ -1412,7 +1401,10 @@ Actual: ${stringify(fullActual)}`);
|
||||
|
||||
const sort = (locations: ReadonlyArray<ts.RenameLocation> | undefined) =>
|
||||
locations && ts.sort(locations, (r1, r2) => ts.compareStringsCaseSensitive(r1.fileName, r2.fileName) || r1.textSpan.start - r2.textSpan.start);
|
||||
assert.deepEqual(sort(references), sort(ranges.map((r): ts.RenameLocation => ({ fileName: r.fileName, textSpan: ts.createTextSpanFromRange(r) }))));
|
||||
assert.deepEqual(sort(references), sort(ranges.map((rangeOrOptions): ts.RenameLocation => {
|
||||
const { range, ...prefixSuffixText } = "range" in rangeOrOptions ? rangeOrOptions : { range: rangeOrOptions };
|
||||
return { fileName: range.fileName, textSpan: ts.createTextSpanFromRange(range), ...prefixSuffixText };
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1534,7 +1526,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
public verifyRenameInfoSucceeded(displayName: string | undefined, fullDisplayName: string | undefined, kind: string | undefined, kindModifiers: string | undefined, fileToRename: string | undefined, expectedRange: Range | undefined): void {
|
||||
const renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition);
|
||||
if (!renameInfo.canRename) {
|
||||
this.raiseError("Rename did not succeed");
|
||||
throw this.raiseError("Rename did not succeed");
|
||||
}
|
||||
|
||||
this.validate("displayName", displayName, renameInfo.displayName);
|
||||
@@ -1560,9 +1552,8 @@ Actual: ${stringify(fullActual)}`);
|
||||
public verifyRenameInfoFailed(message?: string) {
|
||||
const renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition);
|
||||
if (renameInfo.canRename) {
|
||||
this.raiseError("Rename was expected to fail");
|
||||
throw this.raiseError("Rename was expected to fail");
|
||||
}
|
||||
|
||||
this.validate("error", message, renameInfo.localizedErrorMessage);
|
||||
}
|
||||
|
||||
@@ -2049,6 +2040,14 @@ Actual: ${stringify(fullActual)}`);
|
||||
this.goToPosition(len);
|
||||
}
|
||||
|
||||
private goToMarkerOrRange(markerOrRange: string | Range) {
|
||||
if (typeof markerOrRange === "string") {
|
||||
this.goToMarker(markerOrRange);
|
||||
} else {
|
||||
this.goToRangeStart(markerOrRange);
|
||||
}
|
||||
}
|
||||
|
||||
public goToRangeStart({ fileName, pos }: Range) {
|
||||
this.openFile(fileName);
|
||||
this.goToPosition(pos);
|
||||
@@ -2502,9 +2501,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
|
||||
const { changes, commands } = this.languageService.getCombinedCodeFix({ type: "file", fileName: this.activeFile.fileName }, fixId, this.formatCodeSettings, ts.emptyOptions);
|
||||
assert.deepEqual<ReadonlyArray<{}> | undefined>(commands, expectedCommands);
|
||||
assert(changes.every(c => c.fileName === this.activeFile.fileName), "TODO: support testing codefixes that touch multiple files");
|
||||
this.applyChanges(changes);
|
||||
this.verifyCurrentFileContent(newFileContent);
|
||||
this.verifyNewContent({ newFileContent }, changes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2516,10 +2513,10 @@ Actual: ${stringify(fullActual)}`);
|
||||
* @param expectedContents The contents of the file after the fixes are applied.
|
||||
* @param fileName The file to check. If not supplied, the current open file is used.
|
||||
*/
|
||||
public verifyFileAfterCodeFix(expectedContents: string, fileName?: string) {
|
||||
public verifyFileAfterCodeFix(expectedContents: string, fileName?: string, index?: number) {
|
||||
fileName = fileName ? fileName : this.activeFile.fileName;
|
||||
|
||||
this.applyCodeActions(this.getCodeFixes(fileName));
|
||||
this.applyCodeActions(this.getCodeFixes(fileName), index);
|
||||
|
||||
const actualContents: string = this.getFileContent(fileName);
|
||||
if (this.removeWhitespace(actualContents) !== this.removeWhitespace(expectedContents)) {
|
||||
@@ -3389,6 +3386,19 @@ Actual: ${stringify(fullActual)}`);
|
||||
private getApplicableRefactorsWorker(positionOrRange: number | ts.TextRange, fileName: string, preferences = ts.emptyOptions): ReadonlyArray<ts.ApplicableRefactorInfo> {
|
||||
return this.languageService.getApplicableRefactors(fileName, positionOrRange, preferences) || ts.emptyArray;
|
||||
}
|
||||
|
||||
public generateTypes(examples: ReadonlyArray<FourSlashInterface.GenerateTypesOptions>): void {
|
||||
for (const { name = "example", value, output, outputBaseline } of examples) {
|
||||
const actual = ts.generateTypesForModule(name, value, this.formatCodeSettings);
|
||||
if (outputBaseline) {
|
||||
if (actual === undefined) throw ts.Debug.fail();
|
||||
Harness.Baseline.runBaseline(ts.combinePaths("generateTypes", outputBaseline + ts.Extension.Dts), actual);
|
||||
}
|
||||
else {
|
||||
assert.equal(actual, output, `generateTypes output for ${name} does not match`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateTextRangeForTextChanges({ pos, end }: ts.TextRange, textChanges: ReadonlyArray<ts.TextChange>): ts.TextRange {
|
||||
@@ -3442,7 +3452,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
// Parse out the files and their metadata
|
||||
const testData = parseTestData(absoluteBasePath, content, absoluteFileName);
|
||||
const state = new TestState(absoluteBasePath, testType, testData);
|
||||
const output = ts.transpileModule(content, { reportDiagnostics: true });
|
||||
const output = ts.transpileModule(content, { reportDiagnostics: true, compilerOptions: { target: ts.ScriptTarget.ES2015 } });
|
||||
if (output.diagnostics!.length > 0) {
|
||||
throw new Error(`Syntax error in ${absoluteBasePath}: ${output.diagnostics![0].messageText}`);
|
||||
}
|
||||
@@ -4208,7 +4218,7 @@ namespace FourSlashInterface {
|
||||
this.state.verifyQuickInfoString(expectedText, expectedDocumentation);
|
||||
}
|
||||
|
||||
public quickInfoAt(markerName: string, expectedText: string, expectedDocumentation?: string) {
|
||||
public quickInfoAt(markerName: string | FourSlash.Range, expectedText: string, expectedDocumentation?: string) {
|
||||
this.state.verifyQuickInfoAt(markerName, expectedText, expectedDocumentation);
|
||||
}
|
||||
|
||||
@@ -4375,6 +4385,10 @@ namespace FourSlashInterface {
|
||||
this.state.verifyRangeAfterCodeFix(expectedText, includeWhiteSpace, errorCode, index);
|
||||
}
|
||||
|
||||
public fileAfterCodeFix(expectedContents: string, fileName?: string, index?: number) {
|
||||
this.state.verifyFileAfterCodeFix(expectedContents, fileName, index);
|
||||
}
|
||||
|
||||
public codeFixAll(options: VerifyCodeFixAllOptions): void {
|
||||
this.state.verifyCodeFixAll(options);
|
||||
}
|
||||
@@ -4473,7 +4487,7 @@ namespace FourSlashInterface {
|
||||
this.state.verifyRenameInfoFailed(message);
|
||||
}
|
||||
|
||||
public renameLocations(startRanges: ArrayOrSingle<FourSlash.Range>, options: FourSlash.Range[] | { findInStrings?: boolean, findInComments?: boolean, ranges: FourSlash.Range[] }) {
|
||||
public renameLocations(startRanges: ArrayOrSingle<FourSlash.Range>, options: RenameLocationsOptions) {
|
||||
this.state.verifyRenameLocations(startRanges, options);
|
||||
}
|
||||
|
||||
@@ -4512,6 +4526,18 @@ namespace FourSlashInterface {
|
||||
public noMoveToNewFile(): void {
|
||||
this.state.noMoveToNewFile();
|
||||
}
|
||||
|
||||
public generateTypes(...options: GenerateTypesOptions[]): void {
|
||||
this.state.generateTypes(options);
|
||||
}
|
||||
}
|
||||
|
||||
export interface GenerateTypesOptions {
|
||||
readonly name?: string;
|
||||
readonly value: unknown;
|
||||
// Exactly one of these should be set:
|
||||
readonly output?: string;
|
||||
readonly outputBaseline?: string;
|
||||
}
|
||||
|
||||
export class Edit {
|
||||
@@ -4901,7 +4927,7 @@ namespace FourSlashInterface {
|
||||
export interface VerifyCodeFixAllOptions {
|
||||
fixId: string;
|
||||
fixAllDescription: string;
|
||||
newFileContent: string;
|
||||
newFileContent: NewFileContent;
|
||||
commands: ReadonlyArray<{}>;
|
||||
}
|
||||
|
||||
@@ -4936,4 +4962,11 @@ namespace FourSlashInterface {
|
||||
readonly newFileContents: { readonly [fileName: string]: string };
|
||||
readonly preferences?: ts.UserPreferences;
|
||||
}
|
||||
|
||||
export type RenameLocationsOptions = ReadonlyArray<RenameLocationOptions> | {
|
||||
readonly findInStrings?: boolean;
|
||||
readonly findInComments?: boolean;
|
||||
readonly ranges: ReadonlyArray<RenameLocationOptions>;
|
||||
};
|
||||
export type RenameLocationOptions = FourSlash.Range | { readonly range: FourSlash.Range, readonly prefixText?: string, readonly suffixText?: 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);
|
||||
}
|
||||
|
||||
@@ -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 {}
|
||||
@@ -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}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -934,7 +937,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) {
|
||||
|
||||
@@ -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";
|
||||
|
||||
+16
-3
@@ -2,6 +2,7 @@ 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";
|
||||
@@ -12,7 +13,7 @@ declare namespace ts.server {
|
||||
}
|
||||
|
||||
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 +21,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 +48,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 +66,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 +119,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
+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
+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];
|
||||
|
||||
+116
-42
@@ -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;
|
||||
@@ -104,7 +134,15 @@ namespace ts.server {
|
||||
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;
|
||||
|
||||
@@ -448,7 +486,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 */
|
||||
@@ -600,14 +638,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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -703,6 +741,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);
|
||||
@@ -853,15 +918,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -937,6 +1007,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
|
||||
@@ -1595,22 +1666,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;
|
||||
}
|
||||
@@ -1619,7 +1691,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());
|
||||
|
||||
@@ -1656,6 +1730,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);
|
||||
@@ -1748,7 +1823,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();
|
||||
}
|
||||
@@ -1757,7 +1832,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();
|
||||
|
||||
@@ -1767,7 +1842,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);
|
||||
@@ -2120,7 +2195,6 @@ namespace ts.server {
|
||||
if (project.hasExternalProjectRef() &&
|
||||
project.pendingReload === ConfigFileProgramReloadLevel.Full &&
|
||||
!this.pendingProjectUpdates.has(project.getProjectName())) {
|
||||
this.loadConfiguredProject(project);
|
||||
project.updateGraph();
|
||||
}
|
||||
});
|
||||
@@ -2152,7 +2226,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();
|
||||
}
|
||||
|
||||
@@ -2163,7 +2237,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();
|
||||
}
|
||||
@@ -2175,7 +2250,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) => {
|
||||
@@ -2196,11 +2271,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);
|
||||
}
|
||||
@@ -2287,7 +2363,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);
|
||||
@@ -2337,7 +2414,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
|
||||
@@ -2415,17 +2492,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2649,13 +2723,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);
|
||||
@@ -2778,8 +2852,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
|
||||
|
||||
+53
-32
@@ -254,6 +254,11 @@ namespace ts.server {
|
||||
installPackage(options: InstallPackageOptions): Promise<ApplyCodeActionCommandResult> {
|
||||
return this.typingsCache.installPackage({ ...options, projectName: this.projectName, projectRootPath: this.toPath(this.currentDirectory) });
|
||||
}
|
||||
/* @internal */
|
||||
inspectValue(options: InspectValueOptions): Promise<ValueInfo> {
|
||||
return this.typingsCache.inspectValue(options);
|
||||
}
|
||||
|
||||
private get typingsCache(): TypingsCache {
|
||||
return this.projectService.typingsCache;
|
||||
}
|
||||
@@ -276,8 +281,8 @@ namespace ts.server {
|
||||
return this.projectStateVersion.toString();
|
||||
}
|
||||
|
||||
getProjectReferences(): ReadonlyArray<ProjectReference> {
|
||||
return emptyArray;
|
||||
getProjectReferences(): ReadonlyArray<ProjectReference> | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getScriptFileNames() {
|
||||
@@ -352,6 +357,10 @@ namespace ts.server {
|
||||
return this.projectService.host.readFile(fileName);
|
||||
}
|
||||
|
||||
writeFile(fileName: string, content: string): void {
|
||||
return this.projectService.host.writeFile(fileName, content);
|
||||
}
|
||||
|
||||
fileExists(file: string): boolean {
|
||||
// As an optimization, don't hit the disks for files we already know don't exist
|
||||
// (because we're watching for their creation).
|
||||
@@ -359,16 +368,16 @@ namespace ts.server {
|
||||
return !this.isWatchedMissingFile(path) && this.directoryStructureHost.fileExists(file);
|
||||
}
|
||||
|
||||
resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModuleFull[] {
|
||||
return this.resolutionCache.resolveModuleNames(moduleNames, containingFile, reusedNames);
|
||||
resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames?: string[], redirectedReference?: ResolvedProjectReference): ResolvedModuleFull[] {
|
||||
return this.resolutionCache.resolveModuleNames(moduleNames, containingFile, reusedNames, redirectedReference);
|
||||
}
|
||||
|
||||
getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations | undefined {
|
||||
return this.resolutionCache.getResolvedModuleWithFailedLookupLocationsFromCache(moduleName, containingFile);
|
||||
}
|
||||
|
||||
resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[] {
|
||||
return this.resolutionCache.resolveTypeReferenceDirectives(typeDirectiveNames, containingFile);
|
||||
resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): ResolvedTypeReferenceDirective[] {
|
||||
return this.resolutionCache.resolveTypeReferenceDirectives(typeDirectiveNames, containingFile, redirectedReference);
|
||||
}
|
||||
|
||||
directoryExists(path: string): boolean {
|
||||
@@ -574,14 +583,11 @@ namespace ts.server {
|
||||
for (const f of this.program.getSourceFiles()) {
|
||||
this.detachScriptInfoIfNotRoot(f.fileName);
|
||||
}
|
||||
const projectReferences = this.program.getResolvedProjectReferences();
|
||||
if (projectReferences) {
|
||||
for (const ref of projectReferences) {
|
||||
if (ref) {
|
||||
this.detachScriptInfoFromProject(ref.sourceFile.fileName);
|
||||
}
|
||||
this.program.forEachResolvedProjectReference(ref => {
|
||||
if (ref) {
|
||||
this.detachScriptInfoFromProject(ref.sourceFile.fileName);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
// Release external files
|
||||
forEach(this.externalFiles, externalFile => this.detachScriptInfoIfNotRoot(externalFile));
|
||||
@@ -653,7 +659,7 @@ namespace ts.server {
|
||||
return this.rootFiles;
|
||||
}
|
||||
return map(this.program.getSourceFiles(), sourceFile => {
|
||||
const scriptInfo = this.projectService.getScriptInfoForPath(sourceFile.resolvedPath || sourceFile.path);
|
||||
const scriptInfo = this.projectService.getScriptInfoForPath(sourceFile.resolvedPath);
|
||||
Debug.assert(!!scriptInfo, "getScriptInfo", () => `scriptInfo for a file '${sourceFile.fileName}' Path: '${sourceFile.path}' / '${sourceFile.resolvedPath}' is missing.`);
|
||||
return scriptInfo!;
|
||||
});
|
||||
@@ -916,12 +922,19 @@ namespace ts.server {
|
||||
if (hasNewProgram) {
|
||||
if (oldProgram) {
|
||||
for (const f of oldProgram.getSourceFiles()) {
|
||||
if (this.program.getSourceFileByPath(f.path)) {
|
||||
continue;
|
||||
const newFile = this.program.getSourceFileByPath(f.resolvedPath);
|
||||
if (!newFile || (f.resolvedPath === f.path && newFile.resolvedPath !== f.path)) {
|
||||
// new program does not contain this file - detach it from the project
|
||||
// - remove resolutions only if the new program doesnt contain source file by the path (not resolvedPath since path is used for resolution)
|
||||
this.detachScriptInfoFromProject(f.fileName, !!this.program.getSourceFileByPath(f.path));
|
||||
}
|
||||
// new program does not contain this file - detach it from the project
|
||||
this.detachScriptInfoFromProject(f.fileName);
|
||||
}
|
||||
|
||||
oldProgram.forEachResolvedProjectReference((resolvedProjectReference, resolvedProjectReferencePath) => {
|
||||
if (resolvedProjectReference && !this.program.getResolvedProjectReferenceByPath(resolvedProjectReferencePath)) {
|
||||
this.detachScriptInfoFromProject(resolvedProjectReference.sourceFile.fileName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Update the missing file paths watcher
|
||||
@@ -955,11 +968,13 @@ namespace ts.server {
|
||||
return hasNewProgram;
|
||||
}
|
||||
|
||||
private detachScriptInfoFromProject(uncheckedFileName: string) {
|
||||
private detachScriptInfoFromProject(uncheckedFileName: string, noRemoveResolution?: boolean) {
|
||||
const scriptInfoToDetach = this.projectService.getScriptInfo(uncheckedFileName);
|
||||
if (scriptInfoToDetach) {
|
||||
scriptInfoToDetach.detachFromProject(this);
|
||||
this.resolutionCache.removeResolutionsOfFile(scriptInfoToDetach.path);
|
||||
if (!noRemoveResolution) {
|
||||
this.resolutionCache.removeResolutionsOfFile(scriptInfoToDetach.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1311,10 +1326,15 @@ namespace ts.server {
|
||||
|
||||
/* @internal */
|
||||
pendingReload: ConfigFileProgramReloadLevel;
|
||||
/* @internal */
|
||||
pendingReloadReason: string | undefined;
|
||||
|
||||
/*@internal*/
|
||||
configFileSpecs: ConfigFileSpecs | undefined;
|
||||
|
||||
/*@internal*/
|
||||
canConfigFileJsonReportNoInputFiles: boolean;
|
||||
|
||||
/** Ref count to the project when opened from external project */
|
||||
private externalProjectRefCount = 0;
|
||||
|
||||
@@ -1327,6 +1347,9 @@ namespace ts.server {
|
||||
|
||||
protected isInitialLoadPending: () => boolean = returnTrue;
|
||||
|
||||
/*@internal*/
|
||||
sendLoadingProjectFinish = false;
|
||||
|
||||
/*@internal*/
|
||||
constructor(configFileName: NormalizedPath,
|
||||
projectService: ProjectService,
|
||||
@@ -1359,12 +1382,15 @@ namespace ts.server {
|
||||
result = this.projectService.reloadFileNamesOfConfiguredProject(this);
|
||||
break;
|
||||
case ConfigFileProgramReloadLevel.Full:
|
||||
this.projectService.reloadConfiguredProject(this);
|
||||
const reason = Debug.assertDefined(this.pendingReloadReason);
|
||||
this.pendingReloadReason = undefined;
|
||||
this.projectService.reloadConfiguredProject(this, reason);
|
||||
result = true;
|
||||
break;
|
||||
default:
|
||||
result = super.updateGraph();
|
||||
}
|
||||
this.projectService.sendProjectLoadingFinishEvent(this);
|
||||
this.projectService.sendProjectTelemetry(this);
|
||||
this.projectService.sendSurveyReady(this);
|
||||
return result;
|
||||
@@ -1379,8 +1405,8 @@ namespace ts.server {
|
||||
return asNormalizedPath(this.getProjectName());
|
||||
}
|
||||
|
||||
getProjectReferences(): ReadonlyArray<ProjectReference> {
|
||||
return this.projectReferences || emptyArray;
|
||||
getProjectReferences(): ReadonlyArray<ProjectReference> | undefined {
|
||||
return this.projectReferences;
|
||||
}
|
||||
|
||||
updateReferences(refs: ReadonlyArray<ProjectReference> | undefined) {
|
||||
@@ -1388,9 +1414,9 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getResolvedProjectReferences() {
|
||||
forEachResolvedProjectReference<T>(cb: (resolvedProjectReference: ResolvedProjectReference | undefined, resolvedProjectReferencePath: Path) => T | undefined): T | undefined {
|
||||
const program = this.getCurrentProgram();
|
||||
return program && program.getResolvedProjectReferences();
|
||||
return program && program.forEachResolvedProjectReference(cb);
|
||||
}
|
||||
|
||||
enablePlugins() {
|
||||
@@ -1531,13 +1557,8 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
updateErrorOnNoInputFiles(hasFileNames: boolean) {
|
||||
if (hasFileNames) {
|
||||
filterMutate(this.projectErrors!, error => !isErrorNoInputFiles(error)); // TODO: GH#18217
|
||||
}
|
||||
else if (!this.configFileSpecs!.filesSpecs && !some(this.projectErrors, isErrorNoInputFiles)) { // TODO: GH#18217
|
||||
this.projectErrors!.push(getErrorForNoInputFiles(this.configFileSpecs!, this.getConfigFilePath()));
|
||||
}
|
||||
updateErrorOnNoInputFiles(fileNameResult: ExpandResult) {
|
||||
updateErrorForNoInputFiles(fileNameResult, this.getConfigFilePath(), this.configFileSpecs!, this.projectErrors!, this.canConfigFileJsonReportNoInputFiles);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+51
-9
@@ -1087,23 +1087,18 @@ namespace ts.server.protocol {
|
||||
/**
|
||||
* Information about the item to be renamed.
|
||||
*/
|
||||
export interface RenameInfo {
|
||||
export type RenameInfo = RenameInfoSuccess | RenameInfoFailure;
|
||||
export interface RenameInfoSuccess {
|
||||
/**
|
||||
* True if item can be renamed.
|
||||
*/
|
||||
canRename: boolean;
|
||||
|
||||
canRename: true;
|
||||
/**
|
||||
* File or directory to rename.
|
||||
* If set, `getEditsForFileRename` should be called instead of `findRenameLocations`.
|
||||
*/
|
||||
fileToRename?: string;
|
||||
|
||||
/**
|
||||
* Error message if item can not be renamed.
|
||||
*/
|
||||
localizedErrorMessage?: string;
|
||||
|
||||
/**
|
||||
* Display name of the item to be renamed.
|
||||
*/
|
||||
@@ -1123,6 +1118,16 @@ namespace ts.server.protocol {
|
||||
* Optional modifiers for the kind (such as 'public').
|
||||
*/
|
||||
kindModifiers: string;
|
||||
|
||||
/** Span of text to rename. */
|
||||
triggerSpan: TextSpan;
|
||||
}
|
||||
export interface RenameInfoFailure {
|
||||
canRename: false;
|
||||
/**
|
||||
* Error message if item can not be renamed.
|
||||
*/
|
||||
localizedErrorMessage: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1132,7 +1137,12 @@ namespace ts.server.protocol {
|
||||
/** The file to which the spans apply */
|
||||
file: string;
|
||||
/** The text spans in this group */
|
||||
locs: TextSpan[];
|
||||
locs: RenameTextSpan[];
|
||||
}
|
||||
|
||||
export interface RenameTextSpan extends TextSpan {
|
||||
readonly prefixText?: string;
|
||||
readonly suffixText?: string;
|
||||
}
|
||||
|
||||
export interface RenameResponseBody {
|
||||
@@ -2442,6 +2452,30 @@ namespace ts.server.protocol {
|
||||
openFiles: string[];
|
||||
}
|
||||
|
||||
export type ProjectLoadingStartEventName = "projectLoadingStart";
|
||||
export interface ProjectLoadingStartEvent extends Event {
|
||||
event: ProjectLoadingStartEventName;
|
||||
body: ProjectLoadingStartEventBody;
|
||||
}
|
||||
|
||||
export interface ProjectLoadingStartEventBody {
|
||||
/** name of the project */
|
||||
projectName: string;
|
||||
/** reason for loading */
|
||||
reason: string;
|
||||
}
|
||||
|
||||
export type ProjectLoadingFinishEventName = "projectLoadingFinish";
|
||||
export interface ProjectLoadingFinishEvent extends Event {
|
||||
event: ProjectLoadingFinishEventName;
|
||||
body: ProjectLoadingFinishEventBody;
|
||||
}
|
||||
|
||||
export interface ProjectLoadingFinishEventBody {
|
||||
/** name of the project */
|
||||
projectName: string;
|
||||
}
|
||||
|
||||
export type SurveyReadyEventName = "surveyReady";
|
||||
|
||||
export interface SurveyReadyEvent extends Event {
|
||||
@@ -2734,6 +2768,14 @@ namespace ts.server.protocol {
|
||||
payload: TypingsInstalledTelemetryEventPayload;
|
||||
}
|
||||
|
||||
/* __GDPR__
|
||||
"typingsinstalled" : {
|
||||
"${include}": ["${TypeScriptCommonProperties}"],
|
||||
"installedPackages": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
|
||||
"installSuccess": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"typingsInstallerVersion": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
export interface TypingsInstalledTelemetryEventPayload {
|
||||
/**
|
||||
* Comma separated list of installed typing packages
|
||||
|
||||
+73
-23
@@ -336,16 +336,23 @@ namespace ts.server {
|
||||
function combineProjectOutputForReferences(projects: Projects, defaultProject: Project, initialLocation: sourcemaps.SourceMappableLocation, projectService: ProjectService): ReadonlyArray<ReferencedSymbol> {
|
||||
const outputs: ReferencedSymbol[] = [];
|
||||
|
||||
combineProjectOutputWorker<sourcemaps.SourceMappableLocation>(projects, defaultProject, initialLocation, projectService, ({ project, location }, tryAddToTodo) => {
|
||||
combineProjectOutputWorker<sourcemaps.SourceMappableLocation>(projects, defaultProject, initialLocation, projectService, ({ project, location }, getMappedLocation) => {
|
||||
for (const outputReferencedSymbol of project.getLanguageService().findReferences(location.fileName, location.position) || emptyArray) {
|
||||
let symbolToAddTo = find(outputs, o => documentSpansEqual(o.definition, outputReferencedSymbol.definition));
|
||||
const mappedDefinitionFile = getMappedLocation(project, documentSpanLocation(outputReferencedSymbol.definition));
|
||||
const definition: ReferencedSymbolDefinitionInfo = mappedDefinitionFile === undefined ? outputReferencedSymbol.definition : {
|
||||
...outputReferencedSymbol.definition,
|
||||
textSpan: createTextSpan(mappedDefinitionFile.position, outputReferencedSymbol.definition.textSpan.length),
|
||||
fileName: mappedDefinitionFile.fileName,
|
||||
};
|
||||
let symbolToAddTo = find(outputs, o => documentSpansEqual(o.definition, definition));
|
||||
if (!symbolToAddTo) {
|
||||
symbolToAddTo = { definition: outputReferencedSymbol.definition, references: [] };
|
||||
symbolToAddTo = { definition, references: [] };
|
||||
outputs.push(symbolToAddTo);
|
||||
}
|
||||
|
||||
for (const ref of outputReferencedSymbol.references) {
|
||||
if (!contains(symbolToAddTo.references, ref, documentSpansEqual) && !tryAddToTodo(project, documentSpanLocation(ref))) {
|
||||
// If it's in a mapped file, that is added to the todo list by `getMappedLocation`.
|
||||
if (!contains(symbolToAddTo.references, ref, documentSpansEqual) && !getMappedLocation(project, documentSpanLocation(ref))) {
|
||||
symbolToAddTo.references.push(ref);
|
||||
}
|
||||
}
|
||||
@@ -373,12 +380,17 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
type CombineProjectOutputCallback<TLocation extends sourcemaps.SourceMappableLocation | undefined> = (
|
||||
where: ProjectAndLocation<TLocation>,
|
||||
getMappedLocation: (project: Project, location: sourcemaps.SourceMappableLocation) => sourcemaps.SourceMappableLocation | undefined,
|
||||
) => void;
|
||||
|
||||
function combineProjectOutputWorker<TLocation extends sourcemaps.SourceMappableLocation | undefined>(
|
||||
projects: Projects,
|
||||
defaultProject: Project,
|
||||
initialLocation: TLocation,
|
||||
projectService: ProjectService,
|
||||
cb: (where: ProjectAndLocation<TLocation>, getMappedLocation: (project: Project, location: sourcemaps.SourceMappableLocation) => boolean) => void,
|
||||
cb: CombineProjectOutputCallback<TLocation>,
|
||||
getDefinition: (() => sourcemaps.SourceMappableLocation | undefined) | undefined,
|
||||
): void {
|
||||
let toDo: ProjectAndLocation<TLocation>[] | undefined;
|
||||
@@ -417,13 +429,13 @@ namespace ts.server {
|
||||
projectService: ProjectService,
|
||||
toDo: ProjectAndLocation<TLocation>[] | undefined,
|
||||
seenProjects: Map<true>,
|
||||
cb: (where: ProjectAndLocation<TLocation>, getMappedLocation: (project: Project, location: sourcemaps.SourceMappableLocation) => boolean) => void,
|
||||
cb: CombineProjectOutputCallback<TLocation>,
|
||||
): ProjectAndLocation<TLocation>[] | undefined {
|
||||
if (projectAndLocation.project.getCancellationToken().isCancellationRequested()) return undefined; // Skip rest of toDo if cancelled
|
||||
cb(projectAndLocation, (project, location) => {
|
||||
seenProjects.set(projectAndLocation.project.projectName, true);
|
||||
const originalLocation = projectService.getOriginalLocationEnsuringConfiguredProject(project, location);
|
||||
if (!originalLocation) return false;
|
||||
if (!originalLocation) return undefined;
|
||||
|
||||
const originalScriptInfo = projectService.getScriptInfo(originalLocation.fileName)!;
|
||||
toDo = toDo || [];
|
||||
@@ -437,7 +449,7 @@ namespace ts.server {
|
||||
for (const symlinkedProject of symlinkedProjects) addToTodo({ project: symlinkedProject, location: originalLocation as TLocation }, toDo!, seenProjects);
|
||||
});
|
||||
}
|
||||
return true;
|
||||
return originalLocation;
|
||||
});
|
||||
return toDo;
|
||||
}
|
||||
@@ -478,6 +490,7 @@ namespace ts.server {
|
||||
globalPlugins?: ReadonlyArray<string>;
|
||||
pluginProbeLocations?: ReadonlyArray<string>;
|
||||
allowLocalPluginLoads?: boolean;
|
||||
typesMapLocation?: string;
|
||||
}
|
||||
|
||||
export class Session implements EventSender {
|
||||
@@ -538,6 +551,7 @@ namespace ts.server {
|
||||
globalPlugins: opts.globalPlugins,
|
||||
pluginProbeLocations: opts.pluginProbeLocations,
|
||||
allowLocalPluginLoads: opts.allowLocalPluginLoads,
|
||||
typesMapLocation: opts.typesMapLocation,
|
||||
syntaxOnly: opts.syntaxOnly,
|
||||
};
|
||||
this.projectService = new ProjectService(settings);
|
||||
@@ -554,9 +568,19 @@ namespace ts.server {
|
||||
const { openFiles } = event.data;
|
||||
this.projectsUpdatedInBackgroundEvent(openFiles);
|
||||
break;
|
||||
case ProjectLoadingStartEvent:
|
||||
const { project, reason } = event.data;
|
||||
this.event<protocol.ProjectLoadingStartEventBody>(
|
||||
{ projectName: project.getProjectName(), reason },
|
||||
ProjectLoadingStartEvent);
|
||||
break;
|
||||
case ProjectLoadingFinishEvent:
|
||||
const { project: finishProject } = event.data;
|
||||
this.event<protocol.ProjectLoadingFinishEventBody>({ projectName: finishProject.getProjectName() }, ProjectLoadingStartEvent);
|
||||
break;
|
||||
case LargeFileReferencedEvent:
|
||||
const { file, fileSize, maxFileSize } = event.data;
|
||||
this.event<protocol.LargeFileReferencedEventBody>({ file, fileSize, maxFileSize }, "largeFileReferenced");
|
||||
this.event<protocol.LargeFileReferencedEventBody>({ file, fileSize, maxFileSize }, LargeFileReferencedEvent);
|
||||
break;
|
||||
case ConfigFileDiagEvent:
|
||||
const { triggerFile, configFileName: configFile, diagnostics } = event.data;
|
||||
@@ -565,14 +589,14 @@ namespace ts.server {
|
||||
triggerFile,
|
||||
configFile,
|
||||
diagnostics: bakedDiags
|
||||
}, "configFileDiag");
|
||||
}, ConfigFileDiagEvent);
|
||||
break;
|
||||
case SurveyReady:
|
||||
const { surveyId } = event.data;
|
||||
this.event<protocol.SurveyReadyEventBody>({ surveyId }, "surveyReady");
|
||||
this.event<protocol.SurveyReadyEventBody>({ surveyId }, SurveyReady);
|
||||
break;
|
||||
case ProjectLanguageServiceStateEvent: {
|
||||
const eventName: protocol.ProjectLanguageServiceStateEventName = "projectLanguageServiceState";
|
||||
const eventName: protocol.ProjectLanguageServiceStateEventName = ProjectLanguageServiceStateEvent;
|
||||
this.event<protocol.ProjectLanguageServiceStateEventBody>({
|
||||
projectName: event.data.project.getProjectName(),
|
||||
languageServiceEnabled: event.data.languageServiceEnabled
|
||||
@@ -603,11 +627,15 @@ namespace ts.server {
|
||||
// Send project changed event
|
||||
this.event<protocol.ProjectsUpdatedInBackgroundEventBody>({
|
||||
openFiles
|
||||
}, "projectsUpdatedInBackground");
|
||||
}, ProjectsUpdatedInBackgroundEvent);
|
||||
}
|
||||
}
|
||||
|
||||
public logError(err: Error, cmd: string) {
|
||||
public logError(err: Error, cmd: string): void {
|
||||
this.logErrorWorker(err, cmd);
|
||||
}
|
||||
|
||||
private logErrorWorker(err: Error, cmd: string, fileRequest?: protocol.FileRequestArgs): void {
|
||||
let msg = "Exception on executing command " + cmd;
|
||||
if (err.message) {
|
||||
msg += ":\n" + indent(err.message);
|
||||
@@ -615,6 +643,19 @@ namespace ts.server {
|
||||
msg += "\n" + indent((<StackTraceError>err).stack!);
|
||||
}
|
||||
}
|
||||
|
||||
if (fileRequest && this.logger.hasLevel(LogLevel.verbose)) {
|
||||
try {
|
||||
const { file, project } = this.getFileAndProject(fileRequest);
|
||||
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
|
||||
if (scriptInfo) {
|
||||
const text = getSnapshotText(scriptInfo.getSnapshot());
|
||||
msg += `\n\nFile text of ${fileRequest.file}:${indent(text)}\n`;
|
||||
}
|
||||
}
|
||||
catch {} // tslint:disable-line no-empty
|
||||
}
|
||||
|
||||
this.logger.msg(msg, Msg.Err);
|
||||
}
|
||||
|
||||
@@ -1149,21 +1190,28 @@ namespace ts.server {
|
||||
if (!simplifiedResult) return locations;
|
||||
|
||||
const defaultProject = this.getDefaultProject(args);
|
||||
const renameInfo = Session.mapRenameInfo(defaultProject.getLanguageService().getRenameInfo(file, position));
|
||||
const renameInfo: protocol.RenameInfo = this.mapRenameInfo(defaultProject.getLanguageService().getRenameInfo(file, position), Debug.assertDefined(this.projectService.getScriptInfo(file)));
|
||||
return { info: renameInfo, locs: this.toSpanGroups(locations) };
|
||||
}
|
||||
|
||||
// strips 'triggerSpan'
|
||||
private static mapRenameInfo({ canRename, localizedErrorMessage, displayName, fullDisplayName, kind, kindModifiers }: RenameInfo): protocol.RenameInfo {
|
||||
return { canRename, localizedErrorMessage, displayName, fullDisplayName, kind, kindModifiers };
|
||||
private mapRenameInfo(info: RenameInfo, scriptInfo: ScriptInfo): protocol.RenameInfo {
|
||||
if (info.canRename) {
|
||||
const { canRename, fileToRename, displayName, fullDisplayName, kind, kindModifiers, triggerSpan } = info;
|
||||
return identity<protocol.RenameInfoSuccess>(
|
||||
{ canRename, fileToRename, displayName, fullDisplayName, kind, kindModifiers, triggerSpan: this.toLocationTextSpan(triggerSpan, scriptInfo) });
|
||||
}
|
||||
else {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
private toSpanGroups(locations: ReadonlyArray<RenameLocation>): ReadonlyArray<protocol.SpanGroup> {
|
||||
const map = createMap<protocol.SpanGroup>();
|
||||
for (const { fileName, textSpan } of locations) {
|
||||
for (const { fileName, textSpan, originalTextSpan: _, originalFileName: _1, ...prefixSuffixText } of locations) {
|
||||
let group = map.get(fileName);
|
||||
if (!group) map.set(fileName, group = { file: fileName, locs: [] });
|
||||
group.locs.push(this.toLocationTextSpan(textSpan, Debug.assertDefined(this.projectService.getScriptInfo(fileName))));
|
||||
const scriptInfo = Debug.assertDefined(this.projectService.getScriptInfo(fileName));
|
||||
group.locs.push({ ...this.toLocationTextSpan(textSpan, scriptInfo), ...prefixSuffixText });
|
||||
}
|
||||
return arrayFrom(map.values());
|
||||
}
|
||||
@@ -1818,8 +1866,8 @@ namespace ts.server {
|
||||
private applyCodeActionCommand(args: protocol.ApplyCodeActionCommandRequestArgs): {} {
|
||||
const commands = args.command as CodeActionCommand | CodeActionCommand[]; // They should be sending back the command we sent them.
|
||||
for (const command of toArray(commands)) {
|
||||
const { project } = this.getFileAndProject(command);
|
||||
project.getLanguageService().applyCodeActionCommand(command).then(
|
||||
const { file, project } = this.getFileAndProject(command);
|
||||
project.getLanguageService().applyCodeActionCommand(command, this.getFormatOptions(file)).then(
|
||||
_result => { /* TODO: GH#20447 report success message? */ },
|
||||
_error => { /* TODO: GH#20447 report errors */ });
|
||||
}
|
||||
@@ -2310,8 +2358,10 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
let request: protocol.Request | undefined;
|
||||
let relevantFile: protocol.FileRequestArgs | undefined;
|
||||
try {
|
||||
request = <protocol.Request>JSON.parse(message);
|
||||
relevantFile = request.arguments && (request as protocol.FileRequest).arguments.file ? (request as protocol.FileRequest).arguments : undefined;
|
||||
const { response, responseRequired } = this.executeCommand(request);
|
||||
|
||||
if (this.logger.hasLevel(LogLevel.requestTime)) {
|
||||
@@ -2337,7 +2387,7 @@ namespace ts.server {
|
||||
this.doOutput({ canceled: true }, request!.command, request!.seq, /*success*/ true);
|
||||
return;
|
||||
}
|
||||
this.logError(err, message);
|
||||
this.logErrorWorker(err, message, relevantFile);
|
||||
this.doOutput(
|
||||
/*info*/ undefined,
|
||||
request ? request.command : CommandNames.Unknown,
|
||||
|
||||
@@ -8,6 +8,8 @@ namespace ts.server {
|
||||
export interface ITypingsInstaller {
|
||||
isKnownTypesPackageName(name: string): boolean;
|
||||
installPackage(options: InstallPackageOptionsWithProject): Promise<ApplyCodeActionCommandResult>;
|
||||
/* @internal */
|
||||
inspectValue(options: InspectValueOptions): Promise<ValueInfo>;
|
||||
enqueueInstallTypingsRequest(p: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string> | undefined): void;
|
||||
attach(projectService: ProjectService): void;
|
||||
onProjectClosed(p: Project): void;
|
||||
@@ -18,6 +20,7 @@ namespace ts.server {
|
||||
isKnownTypesPackageName: returnFalse,
|
||||
// Should never be called because we never provide a types registry.
|
||||
installPackage: notImplemented,
|
||||
inspectValue: notImplemented,
|
||||
enqueueInstallTypingsRequest: noop,
|
||||
attach: noop,
|
||||
onProjectClosed: noop,
|
||||
@@ -95,6 +98,10 @@ namespace ts.server {
|
||||
return this.installer.installPackage(options);
|
||||
}
|
||||
|
||||
inspectValue(options: InspectValueOptions): Promise<ValueInfo> {
|
||||
return this.installer.inspectValue(options);
|
||||
}
|
||||
|
||||
enqueueInstallTypingsForProject(project: Project, unresolvedImports: SortedReadonlyArray<string> | undefined, forceRefresh: boolean) {
|
||||
const typeAcquisition = project.getTypeAcquisition();
|
||||
|
||||
|
||||
@@ -246,14 +246,16 @@ namespace ts.server {
|
||||
return index === 0 || value !== array[index - 1];
|
||||
}
|
||||
|
||||
const indentStr = "\n ";
|
||||
|
||||
/* @internal */
|
||||
export function indent(str: string): string {
|
||||
return "\n " + str;
|
||||
return indentStr + str.replace(/\n/g, indentStr);
|
||||
}
|
||||
|
||||
/** Put stringified JSON on the next line, indented. */
|
||||
/* @internal */
|
||||
export function stringifyIndented(json: {}): string {
|
||||
return "\n " + JSON.stringify(json);
|
||||
return indentStr + JSON.stringify(json);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,32 +14,25 @@ namespace ts.codefix {
|
||||
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, err) => convertToAsyncFunction(changes, err.file, err.start, context.program.getTypeChecker(), context)),
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
custom type to encapsulate information for variable declarations synthesized in the refactor
|
||||
numberOfUsesOriginal - number of times the variable should be assigned in the refactor
|
||||
numberOfUsesSynthesized - count of how many times the variable has been assigned so far
|
||||
At the end of the refactor, numberOfUsesOriginal should === numberOfUsesSynthesized
|
||||
*/
|
||||
interface SynthIdentifier {
|
||||
identifier: Identifier;
|
||||
types: Type[];
|
||||
numberOfAssignmentsOriginal: number;
|
||||
readonly identifier: Identifier;
|
||||
readonly types: Type[];
|
||||
numberOfAssignmentsOriginal: number; // number of times the variable should be assigned in the refactor
|
||||
}
|
||||
|
||||
interface SymbolAndIdentifier {
|
||||
identifier: Identifier;
|
||||
symbol: Symbol;
|
||||
readonly identifier: Identifier;
|
||||
readonly symbol: Symbol;
|
||||
}
|
||||
|
||||
interface Transformer {
|
||||
checker: TypeChecker;
|
||||
synthNamesMap: Map<SynthIdentifier>; // keys are the symbol id of the identifier
|
||||
allVarNames: SymbolAndIdentifier[];
|
||||
setOfExpressionsToReturn: Map<true>; // keys are the node ids of the expressions
|
||||
constIdentifiers: Identifier[];
|
||||
originalTypeMap: Map<Type>; // keys are the node id of the identifier
|
||||
isInJSFile: boolean;
|
||||
readonly checker: TypeChecker;
|
||||
readonly synthNamesMap: Map<SynthIdentifier>; // keys are the symbol id of the identifier
|
||||
readonly allVarNames: ReadonlyArray<SymbolAndIdentifier>;
|
||||
readonly setOfExpressionsToReturn: ReadonlyMap<true>; // keys are the node ids of the expressions
|
||||
readonly constIdentifiers: Identifier[];
|
||||
readonly originalTypeMap: ReadonlyMap<Type>; // keys are the node id of the identifier
|
||||
readonly isInJSFile: boolean;
|
||||
}
|
||||
|
||||
function convertToAsyncFunction(changes: textChanges.ChangeTracker, sourceFile: SourceFile, position: number, checker: TypeChecker, context: CodeFixContextBase): void {
|
||||
@@ -68,14 +61,14 @@ namespace ts.codefix {
|
||||
const functionToConvertRenamed: FunctionLikeDeclaration = renameCollidingVarNames(functionToConvert, checker, synthNamesMap, context, setOfExpressionsToReturn, originalTypeMap, allVarNames);
|
||||
const constIdentifiers = getConstIdentifiers(synthNamesMap);
|
||||
const returnStatements = getReturnStatementsWithPromiseHandlers(functionToConvertRenamed);
|
||||
const transformer = { checker, synthNamesMap, allVarNames, setOfExpressionsToReturn, constIdentifiers, originalTypeMap, isInJSFile: isInJavascript };
|
||||
const transformer: Transformer = { checker, synthNamesMap, allVarNames, setOfExpressionsToReturn, constIdentifiers, originalTypeMap, isInJSFile: isInJavascript };
|
||||
|
||||
if (!returnStatements.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
// add the async keyword
|
||||
changes.insertModifierBefore(sourceFile, SyntaxKind.AsyncKeyword, functionToConvert);
|
||||
changes.insertLastModifierBefore(sourceFile, SyntaxKind.AsyncKeyword, functionToConvert);
|
||||
|
||||
function startTransformation(node: CallExpression, nodeToReplace: Node) {
|
||||
const newNodes = transformExpression(node, transformer, node);
|
||||
@@ -95,7 +88,7 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
// Returns the identifiers that are never reassigned in the refactor
|
||||
function getConstIdentifiers(synthNamesMap: Map<SynthIdentifier>): Identifier[] {
|
||||
function getConstIdentifiers(synthNamesMap: ReadonlyMap<SynthIdentifier>): Identifier[] {
|
||||
const constIdentifiers: Identifier[] = [];
|
||||
synthNamesMap.forEach((val) => {
|
||||
if (val.numberOfAssignmentsOriginal === 0) {
|
||||
@@ -179,9 +172,9 @@ namespace ts.codefix {
|
||||
|
||||
// if the identifier refers to a function we want to add the new synthesized variable for the declaration (ex. blob in let blob = res(arg))
|
||||
// Note - the choice of the last call signature is arbitrary
|
||||
if (lastCallSignature && lastCallSignature.parameters.length && !synthNamesMap.has(symbolIdString)) {
|
||||
const firstParameter = lastCallSignature.parameters[0];
|
||||
const ident = isParameter(firstParameter.valueDeclaration) && tryCast(firstParameter.valueDeclaration.name, isIdentifier) || createOptimisticUniqueName("result");
|
||||
if (lastCallSignature && !isFunctionLikeDeclaration(node.parent) && !synthNamesMap.has(symbolIdString)) {
|
||||
const firstParameter = firstOrUndefined(lastCallSignature.parameters);
|
||||
const ident = firstParameter && isParameter(firstParameter.valueDeclaration) && tryCast(firstParameter.valueDeclaration.name, isIdentifier) || createOptimisticUniqueName("result");
|
||||
const synthName = getNewNameIfConflict(ident, collidingSymbolMap);
|
||||
synthNamesMap.set(symbolIdString, synthName);
|
||||
allVarNames.push({ identifier: synthName.identifier, symbol });
|
||||
@@ -234,9 +227,7 @@ namespace ts.codefix {
|
||||
|
||||
if (renameInfo) {
|
||||
const type = checker.getTypeAtLocation(node);
|
||||
if (type) {
|
||||
originalType.set(getNodeId(clone).toString(), type);
|
||||
}
|
||||
originalType.set(getNodeId(clone).toString(), type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,8 +249,8 @@ namespace ts.codefix {
|
||||
}
|
||||
}
|
||||
|
||||
function getNewNameIfConflict(name: Identifier, originalNames: Map<Symbol[]>): SynthIdentifier {
|
||||
const numVarsSameName = (originalNames.get(name.text) || []).length;
|
||||
function getNewNameIfConflict(name: Identifier, originalNames: ReadonlyMap<Symbol[]>): SynthIdentifier {
|
||||
const numVarsSameName = (originalNames.get(name.text) || emptyArray).length;
|
||||
const numberOfAssignmentsOriginal = 0;
|
||||
const identifier = numVarsSameName === 0 ? name : createIdentifier(name.text + "_" + numVarsSameName);
|
||||
return { identifier, types: [], numberOfAssignmentsOriginal };
|
||||
@@ -267,9 +258,9 @@ namespace ts.codefix {
|
||||
|
||||
// dispatch function to recursively build the refactoring
|
||||
// should be kept up to date with isFixablePromiseHandler in suggestionDiagnostics.ts
|
||||
function transformExpression(node: Expression, transformer: Transformer, outermostParent: CallExpression, prevArgName?: SynthIdentifier): Statement[] {
|
||||
function transformExpression(node: Expression, transformer: Transformer, outermostParent: CallExpression, prevArgName?: SynthIdentifier): ReadonlyArray<Statement> {
|
||||
if (!node) {
|
||||
return [];
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
const originalType = isIdentifier(node) && transformer.originalTypeMap.get(getNodeId(node).toString());
|
||||
@@ -289,10 +280,10 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
codeActionSucceeded = false;
|
||||
return [];
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
function transformCatch(node: CallExpression, transformer: Transformer, prevArgName?: SynthIdentifier): Statement[] {
|
||||
function transformCatch(node: CallExpression, transformer: Transformer, prevArgName?: SynthIdentifier): ReadonlyArray<Statement> {
|
||||
const func = node.arguments[0];
|
||||
const argName = getArgName(func, transformer);
|
||||
const shouldReturn = transformer.setOfExpressionsToReturn.get(getNodeId(node).toString());
|
||||
@@ -320,7 +311,7 @@ namespace ts.codefix {
|
||||
const tryBlock = createBlock(transformExpression(node.expression, transformer, node, prevArgName));
|
||||
|
||||
const transformationBody = getTransformationBody(func, prevArgName, argName, node, transformer);
|
||||
const catchArg = argName.identifier.text.length > 0 ? argName.identifier.text : "e";
|
||||
const catchArg = argName ? argName.identifier.text : "e";
|
||||
const catchClause = createCatchClause(catchArg, createBlock(transformationBody));
|
||||
|
||||
/*
|
||||
@@ -345,7 +336,7 @@ namespace ts.codefix {
|
||||
return newSynthName;
|
||||
}
|
||||
|
||||
function transformThen(node: CallExpression, transformer: Transformer, outermostParent: CallExpression, prevArgName?: SynthIdentifier): Statement[] {
|
||||
function transformThen(node: CallExpression, transformer: Transformer, outermostParent: CallExpression, prevArgName?: SynthIdentifier): ReadonlyArray<Statement> {
|
||||
const [res, rej] = node.arguments;
|
||||
|
||||
if (!res) {
|
||||
@@ -362,82 +353,91 @@ namespace ts.codefix {
|
||||
|
||||
const transformationBody2 = getTransformationBody(rej, prevArgName, argNameRej, node, transformer);
|
||||
|
||||
const catchArg = argNameRej.identifier.text.length > 0 ? argNameRej.identifier.text : "e";
|
||||
const catchArg = argNameRej ? argNameRej.identifier.text : "e";
|
||||
const catchClause = createCatchClause(catchArg, createBlock(transformationBody2));
|
||||
|
||||
return [createTry(tryBlock, catchClause, /* finallyBlock */ undefined) as Statement];
|
||||
return [createTry(tryBlock, catchClause, /* finallyBlock */ undefined)];
|
||||
}
|
||||
|
||||
return transformExpression(node.expression, transformer, node, argNameRes).concat(transformationBody);
|
||||
}
|
||||
|
||||
function getFlagOfIdentifier(node: Identifier, constIdentifiers: Identifier[]): NodeFlags {
|
||||
function getFlagOfIdentifier(node: Identifier, constIdentifiers: ReadonlyArray<Identifier>): NodeFlags {
|
||||
const inArr: boolean = constIdentifiers.some(elem => elem.text === node.text);
|
||||
return inArr ? NodeFlags.Const : NodeFlags.Let;
|
||||
}
|
||||
|
||||
function transformPromiseCall(node: Expression, transformer: Transformer, prevArgName?: SynthIdentifier): Statement[] {
|
||||
function transformPromiseCall(node: Expression, transformer: Transformer, prevArgName?: SynthIdentifier): ReadonlyArray<Statement> {
|
||||
const shouldReturn = transformer.setOfExpressionsToReturn.get(getNodeId(node).toString());
|
||||
// the identifier is empty when the handler (.then()) ignores the argument - In this situation we do not need to save the result of the promise returning call
|
||||
const hasPrevArgName = prevArgName && prevArgName.identifier.text.length > 0;
|
||||
const originalNodeParent = node.original ? node.original.parent : node.parent;
|
||||
if (hasPrevArgName && !shouldReturn && (!originalNodeParent || isPropertyAccessExpression(originalNodeParent))) {
|
||||
return createVariableDeclarationOrAssignment(prevArgName!, createAwait(node), transformer).concat(); // hack to make the types match
|
||||
if (prevArgName && !shouldReturn && (!originalNodeParent || isPropertyAccessExpression(originalNodeParent))) {
|
||||
return createTransformedStatement(prevArgName, createAwait(node), transformer);
|
||||
}
|
||||
else if (!hasPrevArgName && !shouldReturn && (!originalNodeParent || isPropertyAccessExpression(originalNodeParent))) {
|
||||
else if (!prevArgName && !shouldReturn && (!originalNodeParent || isPropertyAccessExpression(originalNodeParent))) {
|
||||
return [createStatement(createAwait(node))];
|
||||
}
|
||||
|
||||
return [createReturn(getSynthesizedDeepClone(node))];
|
||||
}
|
||||
|
||||
function createVariableDeclarationOrAssignment(prevArgName: SynthIdentifier, rightHandSide: Expression, transformer: Transformer): NodeArray<Statement> {
|
||||
|
||||
if (prevArgName.types.length < prevArgName.numberOfAssignmentsOriginal) {
|
||||
return createNodeArray([createStatement(createAssignment(getSynthesizedDeepClone(prevArgName.identifier), rightHandSide))]);
|
||||
function createTransformedStatement(prevArgName: SynthIdentifier | undefined, rightHandSide: Expression, transformer: Transformer): ReadonlyArray<Statement> {
|
||||
if (!prevArgName || prevArgName.identifier.text.length === 0) {
|
||||
// if there's no argName to assign to, there still might be side effects
|
||||
return [createStatement(rightHandSide)];
|
||||
}
|
||||
|
||||
return createNodeArray([createVariableStatement(/*modifiers*/ undefined,
|
||||
(createVariableDeclarationList([createVariableDeclaration(getSynthesizedDeepClone(prevArgName.identifier), /*type*/ undefined, rightHandSide)], getFlagOfIdentifier(prevArgName.identifier, transformer.constIdentifiers))))]);
|
||||
if (prevArgName.types.length < prevArgName.numberOfAssignmentsOriginal) {
|
||||
// if the variable has already been declared, we don't need "let" or "const"
|
||||
return [createStatement(createAssignment(getSynthesizedDeepClone(prevArgName.identifier), rightHandSide))];
|
||||
}
|
||||
|
||||
return [createVariableStatement(/*modifiers*/ undefined,
|
||||
(createVariableDeclarationList([createVariableDeclaration(getSynthesizedDeepClone(prevArgName.identifier), /*type*/ undefined, rightHandSide)], getFlagOfIdentifier(prevArgName.identifier, transformer.constIdentifiers))))];
|
||||
}
|
||||
|
||||
// should be kept up to date with isFixablePromiseArgument in suggestionDiagnostics.ts
|
||||
function getTransformationBody(func: Node, prevArgName: SynthIdentifier | undefined, argName: SynthIdentifier, parent: CallExpression, transformer: Transformer): NodeArray<Statement> {
|
||||
function getTransformationBody(func: Expression, prevArgName: SynthIdentifier | undefined, argName: SynthIdentifier | undefined, parent: CallExpression, transformer: Transformer): ReadonlyArray<Statement> {
|
||||
|
||||
const hasPrevArgName = prevArgName && prevArgName.identifier.text.length > 0;
|
||||
const hasArgName = argName && argName.identifier.text.length > 0;
|
||||
const shouldReturn = transformer.setOfExpressionsToReturn.get(getNodeId(parent).toString());
|
||||
switch (func.kind) {
|
||||
case SyntaxKind.NullKeyword:
|
||||
// do not produce a transformed statement for a null argument
|
||||
break;
|
||||
case SyntaxKind.Identifier:
|
||||
// identifier includes undefined
|
||||
if (!hasArgName) break;
|
||||
|
||||
const synthCall = createCall(getSynthesizedDeepClone(func) as Identifier, /*typeArguments*/ undefined, [argName.identifier]);
|
||||
if (shouldReturn) {
|
||||
return createNodeArray([createReturn(synthCall)]);
|
||||
case SyntaxKind.Identifier: // identifier includes undefined
|
||||
if (!argName) {
|
||||
// undefined was argument passed to promise handler
|
||||
break;
|
||||
}
|
||||
|
||||
if (!hasPrevArgName) break;
|
||||
const synthCall = createCall(getSynthesizedDeepClone(func as Identifier), /*typeArguments*/ undefined, [argName.identifier]);
|
||||
if (shouldReturn) {
|
||||
return [createReturn(synthCall)];
|
||||
}
|
||||
|
||||
const type = transformer.originalTypeMap.get(getNodeId(func).toString());
|
||||
const callSignatures = type && transformer.checker.getSignaturesOfType(type, SignatureKind.Call);
|
||||
const returnType = callSignatures && callSignatures[0].getReturnType();
|
||||
const varDeclOrAssignment = createVariableDeclarationOrAssignment(prevArgName!, createAwait(synthCall), transformer);
|
||||
prevArgName!.types.push(returnType!);
|
||||
const type = transformer.originalTypeMap.get(getNodeId(func).toString()) || transformer.checker.getTypeAtLocation(func);
|
||||
const callSignatures = transformer.checker.getSignaturesOfType(type, SignatureKind.Call);
|
||||
if (!callSignatures.length) {
|
||||
// if identifier in handler has no call signatures, it's invalid
|
||||
codeActionSucceeded = false;
|
||||
break;
|
||||
}
|
||||
const returnType = callSignatures[0].getReturnType();
|
||||
const varDeclOrAssignment = createTransformedStatement(prevArgName, createAwait(synthCall), transformer);
|
||||
if (prevArgName) {
|
||||
prevArgName.types.push(returnType);
|
||||
}
|
||||
return varDeclOrAssignment;
|
||||
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.ArrowFunction: {
|
||||
const funcBody = (func as FunctionExpression | ArrowFunction).body;
|
||||
// Arrow functions with block bodies { } will enter this control flow
|
||||
if (isFunctionLikeDeclaration(func) && func.body && isBlock(func.body) && func.body.statements) {
|
||||
if (isBlock(funcBody)) {
|
||||
let refactoredStmts: Statement[] = [];
|
||||
let seenReturnStatement = false;
|
||||
|
||||
for (const statement of func.body.statements) {
|
||||
for (const statement of funcBody.statements) {
|
||||
if (isReturnStatement(statement)) {
|
||||
seenReturnStatement = true;
|
||||
}
|
||||
@@ -450,35 +450,43 @@ namespace ts.codefix {
|
||||
}
|
||||
}
|
||||
|
||||
return shouldReturn ? getSynthesizedDeepClones(createNodeArray(refactoredStmts)) :
|
||||
removeReturns(createNodeArray(refactoredStmts), prevArgName!.identifier, transformer.constIdentifiers, seenReturnStatement);
|
||||
return shouldReturn ? refactoredStmts.map(s => getSynthesizedDeepClone(s)) :
|
||||
removeReturns(
|
||||
refactoredStmts,
|
||||
prevArgName === undefined ? undefined : prevArgName.identifier,
|
||||
transformer,
|
||||
seenReturnStatement);
|
||||
}
|
||||
else {
|
||||
const funcBody = (<ArrowFunction>func).body;
|
||||
const innerRetStmts = getReturnStatementsWithPromiseHandlers(createReturn(funcBody as Expression));
|
||||
const innerRetStmts = getReturnStatementsWithPromiseHandlers(createReturn(funcBody));
|
||||
const innerCbBody = getInnerTransformationBody(transformer, innerRetStmts, prevArgName);
|
||||
|
||||
if (innerCbBody.length > 0) {
|
||||
return createNodeArray(innerCbBody);
|
||||
return innerCbBody;
|
||||
}
|
||||
|
||||
if (hasPrevArgName && !shouldReturn) {
|
||||
const type = transformer.checker.getTypeAtLocation(func);
|
||||
const returnType = getLastCallSignature(type, transformer.checker)!.getReturnType();
|
||||
const varDeclOrAssignment = createVariableDeclarationOrAssignment(prevArgName!, getSynthesizedDeepClone(funcBody) as Expression, transformer);
|
||||
prevArgName!.types.push(returnType);
|
||||
return varDeclOrAssignment;
|
||||
const type = transformer.checker.getTypeAtLocation(func);
|
||||
const returnType = getLastCallSignature(type, transformer.checker)!.getReturnType();
|
||||
const rightHandSide = getSynthesizedDeepClone(funcBody);
|
||||
const possiblyAwaitedRightHandSide = !!transformer.checker.getPromisedTypeOfPromise(returnType) ? createAwait(rightHandSide) : rightHandSide;
|
||||
if (!shouldReturn) {
|
||||
const transformedStatement = createTransformedStatement(prevArgName, possiblyAwaitedRightHandSide, transformer);
|
||||
if (prevArgName) {
|
||||
prevArgName.types.push(returnType);
|
||||
}
|
||||
return transformedStatement;
|
||||
}
|
||||
else {
|
||||
return createNodeArray([createReturn(getSynthesizedDeepClone(funcBody) as Expression)]);
|
||||
return [createReturn(possiblyAwaitedRightHandSide)];
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
// We've found a transformation body we don't know how to handle, so the refactoring should no-op to avoid deleting code.
|
||||
// If no cases apply, we've found a transformation body we don't know how to handle, so the refactoring should no-op to avoid deleting code.
|
||||
codeActionSucceeded = false;
|
||||
break;
|
||||
}
|
||||
return createNodeArray([]);
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
function getLastCallSignature(type: Type, checker: TypeChecker): Signature | undefined {
|
||||
@@ -487,13 +495,19 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
|
||||
function removeReturns(stmts: NodeArray<Statement>, prevArgName: Identifier, constIdentifiers: Identifier[], seenReturnStatement: boolean): NodeArray<Statement> {
|
||||
function removeReturns(stmts: ReadonlyArray<Statement>, prevArgName: Identifier | undefined, transformer: Transformer, seenReturnStatement: boolean): ReadonlyArray<Statement> {
|
||||
const ret: Statement[] = [];
|
||||
for (const stmt of stmts) {
|
||||
if (isReturnStatement(stmt)) {
|
||||
if (stmt.expression) {
|
||||
ret.push(createVariableStatement(/*modifiers*/ undefined,
|
||||
(createVariableDeclarationList([createVariableDeclaration(prevArgName, /*type*/ undefined, stmt.expression)], getFlagOfIdentifier(prevArgName, constIdentifiers)))));
|
||||
const possiblyAwaitedExpression = isPromiseReturningExpression(stmt.expression, transformer.checker) ? createAwait(stmt.expression) : stmt.expression;
|
||||
if (prevArgName === undefined) {
|
||||
ret.push(createExpressionStatement(possiblyAwaitedExpression));
|
||||
}
|
||||
else {
|
||||
ret.push(createVariableStatement(/*modifiers*/ undefined,
|
||||
(createVariableDeclarationList([createVariableDeclaration(prevArgName, /*type*/ undefined, possiblyAwaitedExpression)], getFlagOfIdentifier(prevArgName, transformer.constIdentifiers)))));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -502,20 +516,20 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
// if block has no return statement, need to define prevArgName as undefined to prevent undeclared variables
|
||||
if (!seenReturnStatement) {
|
||||
if (!seenReturnStatement && prevArgName !== undefined) {
|
||||
ret.push(createVariableStatement(/*modifiers*/ undefined,
|
||||
(createVariableDeclarationList([createVariableDeclaration(prevArgName, /*type*/ undefined, createIdentifier("undefined"))], getFlagOfIdentifier(prevArgName, constIdentifiers)))));
|
||||
(createVariableDeclarationList([createVariableDeclaration(prevArgName, /*type*/ undefined, createIdentifier("undefined"))], getFlagOfIdentifier(prevArgName, transformer.constIdentifiers)))));
|
||||
}
|
||||
|
||||
return createNodeArray(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
function getInnerTransformationBody(transformer: Transformer, innerRetStmts: Node[], prevArgName?: SynthIdentifier) {
|
||||
function getInnerTransformationBody(transformer: Transformer, innerRetStmts: ReadonlyArray<Node>, prevArgName?: SynthIdentifier) {
|
||||
|
||||
let innerCbBody: Statement[] = [];
|
||||
for (const stmt of innerRetStmts) {
|
||||
forEachChild(stmt, function visit(node: Node) {
|
||||
forEachChild(stmt, function visit(node) {
|
||||
if (isCallExpression(node)) {
|
||||
const temp = transformExpression(node, transformer, node, prevArgName);
|
||||
innerCbBody = innerCbBody.concat(temp);
|
||||
@@ -531,7 +545,7 @@ namespace ts.codefix {
|
||||
return innerCbBody;
|
||||
}
|
||||
|
||||
function getArgName(funcNode: Node, transformer: Transformer): SynthIdentifier {
|
||||
function getArgName(funcNode: Expression, transformer: Transformer): SynthIdentifier | undefined {
|
||||
|
||||
const numberOfAssignmentsOriginal = 0;
|
||||
const types: Type[] = [];
|
||||
@@ -541,20 +555,21 @@ namespace ts.codefix {
|
||||
if (isFunctionLikeDeclaration(funcNode)) {
|
||||
if (funcNode.parameters.length > 0) {
|
||||
const param = funcNode.parameters[0].name as Identifier;
|
||||
name = getMapEntryIfExists(param);
|
||||
name = getMapEntryOrDefault(param);
|
||||
}
|
||||
}
|
||||
else if (isIdentifier(funcNode)) {
|
||||
name = getMapEntryIfExists(funcNode);
|
||||
name = getMapEntryOrDefault(funcNode);
|
||||
}
|
||||
|
||||
if (!name || name.identifier === undefined || name.identifier.text === "_" || name.identifier.text === "undefined") {
|
||||
return { identifier: createIdentifier(""), types, numberOfAssignmentsOriginal };
|
||||
// return undefined argName when arg is null or undefined
|
||||
if (!name || name.identifier.text === "undefined") {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return name;
|
||||
|
||||
function getMapEntryIfExists(identifier: Identifier): SynthIdentifier {
|
||||
function getMapEntryOrDefault(identifier: Identifier): SynthIdentifier {
|
||||
const originalNode = getOriginalNode(identifier);
|
||||
const symbol = getSymbol(originalNode);
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
const fixId = "fixCannotFindModule";
|
||||
const fixName = "fixCannotFindModule";
|
||||
const fixIdInstallTypesPackage = "installTypesPackage";
|
||||
const fixIdGenerateTypes = "generateTypes";
|
||||
|
||||
const errorCodeCannotFindModule = Diagnostics.Cannot_find_module_0.code;
|
||||
const errorCodes = [
|
||||
errorCodeCannotFindModule,
|
||||
@@ -10,26 +13,141 @@ namespace ts.codefix {
|
||||
errorCodes,
|
||||
getCodeActions: context => {
|
||||
const { host, sourceFile, span: { start } } = context;
|
||||
const packageName = getTypesPackageNameToInstall(host, sourceFile, start, context.errorCode);
|
||||
return packageName === undefined ? []
|
||||
: [createCodeFixAction(fixId, /*changes*/ [], [Diagnostics.Install_0, packageName], fixId, Diagnostics.Install_all_missing_types_packages, getCommand(sourceFile.fileName, packageName))];
|
||||
const packageName = tryGetImportedPackageName(sourceFile, start);
|
||||
if (packageName === undefined) return undefined;
|
||||
const typesPackageName = getTypesPackageNameToInstall(packageName, host, context.errorCode);
|
||||
return typesPackageName === undefined
|
||||
? singleElementArray(tryGetGenerateTypesAction(context, packageName))
|
||||
: [createCodeFixAction(fixName, /*changes*/ [], [Diagnostics.Install_0, typesPackageName], fixIdInstallTypesPackage, Diagnostics.Install_all_missing_types_packages, getInstallCommand(sourceFile.fileName, typesPackageName))];
|
||||
},
|
||||
fixIds: [fixIdInstallTypesPackage, fixIdGenerateTypes],
|
||||
getAllCodeActions: context => {
|
||||
let savedTypesDir: string | null | undefined = null; // tslint:disable-line no-null-keyword
|
||||
return codeFixAll(context, errorCodes, (changes, diag, commands) => {
|
||||
const packageName = tryGetImportedPackageName(diag.file, diag.start);
|
||||
if (packageName === undefined) return undefined;
|
||||
switch (context.fixId) {
|
||||
case fixIdInstallTypesPackage: {
|
||||
const pkg = getTypesPackageNameToInstall(packageName, context.host, diag.code);
|
||||
if (pkg) {
|
||||
commands.push(getInstallCommand(diag.file.fileName, pkg));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case fixIdGenerateTypes: {
|
||||
const typesDir = savedTypesDir !== null ? savedTypesDir : savedTypesDir = getOrCreateTypesDirectory(changes, context);
|
||||
const command = typesDir === undefined ? undefined : tryGenerateTypes(typesDir, packageName, context);
|
||||
if (command) commands.push(command);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Debug.fail(`Bad fixId: ${context.fixId}`);
|
||||
}
|
||||
});
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: context => codeFixAll(context, errorCodes, (_, diag, commands) => {
|
||||
const pkg = getTypesPackageNameToInstall(context.host, diag.file, diag.start, diag.code);
|
||||
if (pkg) {
|
||||
commands.push(getCommand(diag.file.fileName, pkg));
|
||||
}
|
||||
}),
|
||||
});
|
||||
|
||||
function getCommand(fileName: string, packageName: string): InstallPackageAction {
|
||||
function tryGetGenerateTypesAction(context: CodeFixContextBase, packageName: string): CodeFixAction | undefined {
|
||||
let command: GenerateTypesAction | undefined;
|
||||
const changes = textChanges.ChangeTracker.with(context, t => {
|
||||
const typesDir = getOrCreateTypesDirectory(t, context);
|
||||
command = typesDir === undefined ? undefined : tryGenerateTypes(typesDir, packageName, context);
|
||||
});
|
||||
return command && createCodeFixAction(fixName, changes, [Diagnostics.Generate_types_for_0, packageName], fixIdGenerateTypes, Diagnostics.Generate_types_for_all_packages_without_types, command);
|
||||
}
|
||||
|
||||
function tryGenerateTypes(typesDir: string, packageName: string, context: CodeFixContextBase): GenerateTypesAction | undefined {
|
||||
const file = context.sourceFile.fileName;
|
||||
const fileToGenerateTypesFor = tryResolveJSModule(packageName, getDirectoryPath(file), context.host as ModuleResolutionHost); // TODO: GH#18217
|
||||
if (fileToGenerateTypesFor === undefined) return undefined;
|
||||
|
||||
const outputFileName = resolvePath(getDirectoryPath(context.program.getCompilerOptions().configFile!.fileName), typesDir, packageName + ".d.ts");
|
||||
if (context.host.fileExists!(outputFileName)) return undefined;
|
||||
return { type: "generate types", file, fileToGenerateTypesFor, outputFileName };
|
||||
}
|
||||
|
||||
// If no types directory exists yet, adds it to tsconfig.json
|
||||
function getOrCreateTypesDirectory(changes: textChanges.ChangeTracker, context: CodeFixContextBase): string | undefined {
|
||||
const { configFile } = context.program.getCompilerOptions();
|
||||
if (!configFile) return undefined;
|
||||
|
||||
const tsconfigObjectLiteral = getTsConfigObjectLiteralExpression(configFile);
|
||||
if (!tsconfigObjectLiteral) return undefined;
|
||||
|
||||
const compilerOptionsProperty = findProperty(tsconfigObjectLiteral, "compilerOptions");
|
||||
if (!compilerOptionsProperty) {
|
||||
const newCompilerOptions = createObjectLiteral([makeDefaultBaseUrl(), makeDefaultPaths()]);
|
||||
changes.insertNodeAtObjectStart(configFile, tsconfigObjectLiteral, createJsonPropertyAssignment("compilerOptions", newCompilerOptions));
|
||||
return defaultTypesDirectoryName;
|
||||
}
|
||||
|
||||
const compilerOptions = compilerOptionsProperty.initializer;
|
||||
if (!isObjectLiteralExpression(compilerOptions)) return defaultTypesDirectoryName;
|
||||
|
||||
const baseUrl = getOrAddBaseUrl(changes, configFile, compilerOptions);
|
||||
const typesDirectoryFromPathMapping = getOrAddPathMapping(changes, configFile, compilerOptions);
|
||||
return combinePaths(baseUrl, typesDirectoryFromPathMapping);
|
||||
}
|
||||
|
||||
const defaultBaseUrl = ".";
|
||||
function makeDefaultBaseUrl(): PropertyAssignment {
|
||||
return createJsonPropertyAssignment("baseUrl", createStringLiteral(defaultBaseUrl));
|
||||
}
|
||||
function getOrAddBaseUrl(changes: textChanges.ChangeTracker, tsconfig: TsConfigSourceFile, compilerOptions: ObjectLiteralExpression): string {
|
||||
const baseUrlProp = findProperty(compilerOptions, "baseUrl");
|
||||
if (baseUrlProp) {
|
||||
return isStringLiteral(baseUrlProp.initializer) ? baseUrlProp.initializer.text : defaultBaseUrl;
|
||||
}
|
||||
else {
|
||||
changes.insertNodeAtObjectStart(tsconfig, compilerOptions, makeDefaultBaseUrl());
|
||||
return defaultBaseUrl;
|
||||
}
|
||||
}
|
||||
|
||||
const defaultTypesDirectoryName = "types";
|
||||
function makeDefaultPathMapping(): PropertyAssignment {
|
||||
return createJsonPropertyAssignment("*", createArrayLiteral([createStringLiteral(`${defaultTypesDirectoryName}/*`)]));
|
||||
}
|
||||
function makeDefaultPaths(): PropertyAssignment {
|
||||
return createJsonPropertyAssignment("paths", createObjectLiteral([makeDefaultPathMapping()]));
|
||||
}
|
||||
function getOrAddPathMapping(changes: textChanges.ChangeTracker, tsconfig: TsConfigSourceFile, compilerOptions: ObjectLiteralExpression) {
|
||||
const paths = findProperty(compilerOptions, "paths");
|
||||
if (!paths || !isObjectLiteralExpression(paths.initializer)) {
|
||||
changes.insertNodeAtObjectStart(tsconfig, compilerOptions, makeDefaultPaths());
|
||||
return defaultTypesDirectoryName;
|
||||
}
|
||||
|
||||
// Look for an existing path mapping. Should look like `"*": "foo/*"`.
|
||||
const existing = firstDefined(paths.initializer.properties, prop =>
|
||||
isPropertyAssignment(prop) && isStringLiteral(prop.name) && prop.name.text === "*" && isArrayLiteralExpression(prop.initializer)
|
||||
? firstDefined(prop.initializer.elements, value => isStringLiteral(value) ? tryRemoveSuffix(value.text, "/*") : undefined)
|
||||
: undefined);
|
||||
if (existing) return existing;
|
||||
|
||||
changes.insertNodeAtObjectStart(tsconfig, paths.initializer, makeDefaultPathMapping());
|
||||
return defaultTypesDirectoryName;
|
||||
}
|
||||
|
||||
function createJsonPropertyAssignment(name: string, initializer: Expression) {
|
||||
return createPropertyAssignment(createStringLiteral(name), initializer);
|
||||
}
|
||||
|
||||
function findProperty(obj: ObjectLiteralExpression, name: string): PropertyAssignment | undefined {
|
||||
return find(obj.properties, (p): p is PropertyAssignment => isPropertyAssignment(p) && !!p.name && isStringLiteral(p.name) && p.name.text === name);
|
||||
}
|
||||
|
||||
function getInstallCommand(fileName: string, packageName: string): InstallPackageAction {
|
||||
return { type: "install package", file: fileName, packageName };
|
||||
}
|
||||
|
||||
function getTypesPackageNameToInstall(host: LanguageServiceHost, sourceFile: SourceFile, pos: number, diagCode: number): string | undefined {
|
||||
function tryGetImportedPackageName(sourceFile: SourceFile, pos: number): string | undefined {
|
||||
const moduleName = cast(getTokenAtPosition(sourceFile, pos), isStringLiteral).text;
|
||||
const { packageName } = parsePackageName(moduleName);
|
||||
return isExternalModuleNameRelative(packageName) ? undefined : packageName;
|
||||
}
|
||||
|
||||
function getTypesPackageNameToInstall(packageName: string, host: LanguageServiceHost, diagCode: number): string | undefined {
|
||||
return diagCode === errorCodeCannotFindModule
|
||||
? (JsTyping.nodeCoreModules.has(packageName) ? "@types/node" : undefined)
|
||||
: (host.isKnownTypesPackageName!(packageName) ? getTypesPackageName(packageName) : undefined); // TODO: GH#18217
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
export function generateTypesForModule(name: string, moduleValue: unknown, formatSettings: FormatCodeSettings): string {
|
||||
return valueInfoToDeclarationFileText(inspectValue(name, moduleValue), formatSettings);
|
||||
}
|
||||
|
||||
export function valueInfoToDeclarationFileText(valueInfo: ValueInfo, formatSettings: FormatCodeSettings): string {
|
||||
return textChanges.getNewFileText(toStatements(valueInfo, OutputKind.ExportEquals), ScriptKind.TS, "\n", formatting.getFormatContext(formatSettings));
|
||||
}
|
||||
|
||||
const enum OutputKind { ExportEquals, NamedExport, NamespaceMember }
|
||||
function toNamespaceMemberStatements(info: ValueInfo): ReadonlyArray<Statement> {
|
||||
return toStatements(info, OutputKind.NamespaceMember);
|
||||
}
|
||||
function toStatements(info: ValueInfo, kind: OutputKind): ReadonlyArray<Statement> {
|
||||
const isDefault = info.name === InternalSymbolName.Default;
|
||||
const name = isDefault ? "_default" : info.name;
|
||||
if (!isValidIdentifier(name) || isDefault && kind !== OutputKind.NamedExport) return emptyArray;
|
||||
|
||||
const modifiers = isDefault && info.kind === ValueKind.FunctionOrClass ? [createModifier(SyntaxKind.ExportKeyword), createModifier(SyntaxKind.DefaultKeyword)]
|
||||
: kind === OutputKind.ExportEquals ? [createModifier(SyntaxKind.DeclareKeyword)]
|
||||
: kind === OutputKind.NamedExport ? [createModifier(SyntaxKind.ExportKeyword)]
|
||||
: undefined;
|
||||
const exportEquals = () => kind === OutputKind.ExportEquals ? [exportEqualsOrDefault(info.name, /*isExportEquals*/ true)] : emptyArray;
|
||||
const exportDefault = () => isDefault ? [exportEqualsOrDefault("_default", /*isExportEquals*/ false)] : emptyArray;
|
||||
|
||||
switch (info.kind) {
|
||||
case ValueKind.FunctionOrClass:
|
||||
return [...exportEquals(), ...functionOrClassToStatements(modifiers, name, info)];
|
||||
case ValueKind.Object:
|
||||
const { members } = info;
|
||||
if (kind === OutputKind.ExportEquals) {
|
||||
return flatMap(members, v => toStatements(v, OutputKind.NamedExport));
|
||||
}
|
||||
if (members.some(m => m.kind === ValueKind.FunctionOrClass)) {
|
||||
// If some member is a function, use a namespace so it gets a FunctionDeclaration or ClassDeclaration.
|
||||
return [...exportDefault(), createNamespace(modifiers, name, flatMap(members, toNamespaceMemberStatements))];
|
||||
}
|
||||
// falls through
|
||||
case ValueKind.Const:
|
||||
case ValueKind.Array: {
|
||||
const comment = info.kind === ValueKind.Const ? info.comment : undefined;
|
||||
const constVar = createVariableStatement(modifiers, createVariableDeclarationList([createVariableDeclaration(name, toType(info))], NodeFlags.Const));
|
||||
return [...exportEquals(), ...exportDefault(), addComment(constVar, comment)];
|
||||
}
|
||||
default:
|
||||
return Debug.assertNever(info);
|
||||
}
|
||||
}
|
||||
function exportEqualsOrDefault(name: string, isExportEquals: boolean): ExportAssignment {
|
||||
return createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, isExportEquals, createIdentifier(name));
|
||||
}
|
||||
|
||||
function functionOrClassToStatements(modifiers: Modifiers, name: string, { source, prototypeMembers, namespaceMembers }: ValueInfoFunctionOrClass): ReadonlyArray<Statement> {
|
||||
const fnAst = parseClassOrFunctionBody(source);
|
||||
const { parameters, returnType } = fnAst === undefined ? { parameters: emptyArray, returnType: anyType() } : getParametersAndReturnType(fnAst);
|
||||
const instanceProperties = typeof fnAst === "object" ? getConstructorFunctionInstanceProperties(fnAst) : emptyArray;
|
||||
|
||||
const classStaticMembers: ClassElement[] | undefined =
|
||||
instanceProperties.length !== 0 || prototypeMembers.length !== 0 || fnAst === undefined || typeof fnAst !== "number" && fnAst.kind === SyntaxKind.Constructor ? [] : undefined;
|
||||
|
||||
const namespaceStatements = flatMap(namespaceMembers, info => {
|
||||
if (!isValidIdentifier(info.name)) return undefined;
|
||||
if (classStaticMembers) {
|
||||
switch (info.kind) {
|
||||
case ValueKind.Object:
|
||||
if (info.members.some(m => m.kind === ValueKind.FunctionOrClass)) {
|
||||
break;
|
||||
}
|
||||
// falls through
|
||||
case ValueKind.Array:
|
||||
case ValueKind.Const:
|
||||
classStaticMembers.push(
|
||||
addComment(
|
||||
createProperty(/*decorators*/ undefined, [createModifier(SyntaxKind.StaticKeyword)], info.name, /*questionOrExclamationToken*/ undefined, toType(info), /*initializer*/ undefined),
|
||||
info.kind === ValueKind.Const ? info.comment : undefined));
|
||||
return undefined;
|
||||
case ValueKind.FunctionOrClass:
|
||||
if (!info.namespaceMembers.length) { // Else, can't merge a static method with a namespace. Must make it a function on the namespace.
|
||||
const sig = tryGetMethod(info, [createModifier(SyntaxKind.StaticKeyword)]);
|
||||
if (sig) {
|
||||
classStaticMembers.push(sig);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return toStatements(info, OutputKind.NamespaceMember);
|
||||
});
|
||||
|
||||
const decl = classStaticMembers
|
||||
? createClassDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
modifiers,
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
/*heritageClauses*/ undefined,
|
||||
[
|
||||
...classStaticMembers,
|
||||
...(parameters.length ? [createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, parameters, /*body*/ undefined)] : emptyArray),
|
||||
...instanceProperties,
|
||||
// ignore non-functions on the prototype
|
||||
...mapDefined(prototypeMembers, info => info.kind === ValueKind.FunctionOrClass ? tryGetMethod(info) : undefined),
|
||||
])
|
||||
: createFunctionDeclaration(/*decorators*/ undefined, modifiers, /*asteriskToken*/ undefined, name, /*typeParameters*/ undefined, parameters, returnType, /*body*/ undefined);
|
||||
return [decl, ...(namespaceStatements.length === 0 ? emptyArray : [createNamespace(modifiers && modifiers.map(m => getSynthesizedDeepClone(m)), name, namespaceStatements)])];
|
||||
}
|
||||
|
||||
function tryGetMethod({ name, source }: ValueInfoFunctionOrClass, modifiers?: Modifiers): MethodDeclaration | undefined {
|
||||
if (!isValidIdentifier(name)) return undefined;
|
||||
const fnAst = parseClassOrFunctionBody(source);
|
||||
if (fnAst === undefined || (typeof fnAst !== "number" && fnAst.kind === SyntaxKind.Constructor)) return undefined;
|
||||
const sig = getParametersAndReturnType(fnAst);
|
||||
return sig && createMethod(
|
||||
/*decorators*/ undefined,
|
||||
modifiers,
|
||||
/*asteriskToken*/ undefined,
|
||||
name,
|
||||
/*questionToken*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
sig.parameters,
|
||||
sig.returnType,
|
||||
/*body*/ undefined);
|
||||
}
|
||||
|
||||
function toType(info: ValueInfo): TypeNode {
|
||||
switch (info.kind) {
|
||||
case ValueKind.Const:
|
||||
return createTypeReferenceNode(info.typeName, /*typeArguments*/ undefined);
|
||||
case ValueKind.Array:
|
||||
return createArrayTypeNode(toType(info.inner));
|
||||
case ValueKind.FunctionOrClass:
|
||||
return createTypeReferenceNode("Function", /*typeArguments*/ undefined); // Normally we create a FunctionDeclaration, but this can happen for a function in an array.
|
||||
case ValueKind.Object:
|
||||
return createTypeLiteralNode(info.members.map(m => createPropertySignature(/*modifiers*/ undefined, m.name, /*questionToken*/ undefined, toType(m), /*initializer*/ undefined)));
|
||||
default:
|
||||
return Debug.assertNever(info);
|
||||
}
|
||||
}
|
||||
|
||||
// Parses assignments to "this.x" in the constructor into class property declarations
|
||||
function getConstructorFunctionInstanceProperties(fnAst: FunctionOrConstructorNode): ReadonlyArray<PropertyDeclaration> {
|
||||
const members: PropertyDeclaration[] = [];
|
||||
forEachOwnNodeOfFunction(fnAst, node => {
|
||||
if (isAssignmentExpression(node, /*excludeCompoundAssignment*/ true) &&
|
||||
isPropertyAccessExpression(node.left) && node.left.expression.kind === SyntaxKind.ThisKeyword) {
|
||||
const name = node.left.name.text;
|
||||
if (!isJsPrivate(name)) members.push(createProperty(/*decorators*/ undefined, /*modifiers*/ undefined, name, /*questionOrExclamationToken*/ undefined, anyType(), /*initializer*/ undefined));
|
||||
}
|
||||
});
|
||||
return members;
|
||||
}
|
||||
|
||||
interface ParametersAndReturnType { readonly parameters: ReadonlyArray<ParameterDeclaration>; readonly returnType: TypeNode; }
|
||||
function getParametersAndReturnType(fnAst: FunctionOrConstructor): ParametersAndReturnType {
|
||||
if (typeof fnAst === "number") {
|
||||
return { parameters: fill(fnAst, i => makeParameter(`p${i}`, anyType())), returnType: anyType() };
|
||||
}
|
||||
let usedArguments = false, hasReturn = false;
|
||||
forEachOwnNodeOfFunction(fnAst, node => {
|
||||
usedArguments = usedArguments || isIdentifier(node) && node.text === "arguments";
|
||||
hasReturn = hasReturn || isReturnStatement(node) && !!node.expression && node.expression.kind !== SyntaxKind.VoidExpression;
|
||||
});
|
||||
const parameters = [
|
||||
...fnAst.parameters.map(p => makeParameter(`${p.name.getText()}`, inferParameterType(fnAst, p))),
|
||||
...(usedArguments ? [makeRestParameter()] : emptyArray),
|
||||
];
|
||||
return { parameters, returnType: hasReturn ? anyType() : createKeywordTypeNode(SyntaxKind.VoidKeyword) };
|
||||
}
|
||||
function makeParameter(name: string, type: TypeNode): ParameterDeclaration {
|
||||
return createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name, /*questionToken*/ undefined, type);
|
||||
}
|
||||
function makeRestParameter(): ParameterDeclaration {
|
||||
return createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, createToken(SyntaxKind.DotDotDotToken), "args", /*questionToken*/ undefined, createArrayTypeNode(anyType()));
|
||||
}
|
||||
|
||||
type FunctionOrConstructorNode = FunctionExpression | ArrowFunction | ConstructorDeclaration | MethodDeclaration;
|
||||
type FunctionOrConstructor = FunctionOrConstructorNode | number; // number is for native function
|
||||
/** Returns 'undefined' for class with no declared constructor */
|
||||
function parseClassOrFunctionBody(source: string | number): FunctionOrConstructor | undefined {
|
||||
if (typeof source === "number") return source;
|
||||
const classOrFunction = tryCast(parseExpression(source), (node): node is FunctionExpression | ArrowFunction | ClassExpression => isFunctionExpression(node) || isArrowFunction(node) || isClassExpression(node));
|
||||
return classOrFunction
|
||||
? isClassExpression(classOrFunction) ? find(classOrFunction.members, isConstructorDeclaration) : classOrFunction
|
||||
// If that didn't parse, it's a method `m() {}`. Parse again inside of an object literal.
|
||||
: cast(first(cast(parseExpression(`{ ${source} }`), isObjectLiteralExpression).properties), isMethodDeclaration);
|
||||
}
|
||||
|
||||
function parseExpression(expr: string): Expression {
|
||||
const text = `const _ = ${expr}`;
|
||||
const srcFile = createSourceFile("test.ts", text, ScriptTarget.Latest, /*setParentNodes*/ true);
|
||||
return first(cast(first(srcFile.statements), isVariableStatement).declarationList.declarations).initializer!;
|
||||
}
|
||||
|
||||
function inferParameterType(_fn: FunctionOrConstructor, _param: ParameterDeclaration): TypeNode {
|
||||
// TODO: Inspect function body for clues (see inferFromUsage.ts)
|
||||
return anyType();
|
||||
}
|
||||
|
||||
// Descends through all nodes in a function, but not in nested functions.
|
||||
function forEachOwnNodeOfFunction(fnAst: FunctionOrConstructorNode, cb: (node: Node) => void) {
|
||||
fnAst.body!.forEachChild(function recur(node) {
|
||||
cb(node);
|
||||
if (!isFunctionLike(node)) node.forEachChild(recur);
|
||||
});
|
||||
}
|
||||
|
||||
function isValidIdentifier(name: string): boolean {
|
||||
const keyword = stringToToken(name);
|
||||
return !(keyword && isNonContextualKeyword(keyword)) && isIdentifierText(name, ScriptTarget.ESNext);
|
||||
}
|
||||
|
||||
type Modifiers = ReadonlyArray<Modifier> | undefined;
|
||||
|
||||
function addComment<T extends Node>(node: T, comment: string | undefined): T {
|
||||
if (comment !== undefined) addSyntheticLeadingComment(node, SyntaxKind.SingleLineCommentTrivia, comment);
|
||||
return node;
|
||||
}
|
||||
|
||||
function anyType(): KeywordTypeNode {
|
||||
return createKeywordTypeNode(SyntaxKind.AnyKeyword);
|
||||
}
|
||||
|
||||
function createNamespace(modifiers: Modifiers, name: string, statements: ReadonlyArray<Statement>): NamespaceDeclaration {
|
||||
return createModuleDeclaration(/*decorators*/ undefined, modifiers, createIdentifier(name), createModuleBlock(statements), NodeFlags.Namespace) as NamespaceDeclaration;
|
||||
}
|
||||
}
|
||||
@@ -185,20 +185,20 @@ namespace ts.codefix {
|
||||
|
||||
const defaultInfo = getDefaultLikeExportInfo(moduleSymbol, checker, compilerOptions);
|
||||
if (defaultInfo && defaultInfo.name === symbolName && skipAlias(defaultInfo.symbol, checker) === exportedSymbol) {
|
||||
result.push({ moduleSymbol, importKind: defaultInfo.kind, exportedSymbolIsTypeOnly: isTypeOnlySymbol(defaultInfo.symbol) });
|
||||
result.push({ moduleSymbol, importKind: defaultInfo.kind, exportedSymbolIsTypeOnly: isTypeOnlySymbol(defaultInfo.symbol, checker) });
|
||||
}
|
||||
|
||||
for (const exported of checker.getExportsOfModule(moduleSymbol)) {
|
||||
if (exported.name === symbolName && skipAlias(exported, checker) === exportedSymbol) {
|
||||
result.push({ moduleSymbol, importKind: ImportKind.Named, exportedSymbolIsTypeOnly: isTypeOnlySymbol(exported) });
|
||||
result.push({ moduleSymbol, importKind: ImportKind.Named, exportedSymbolIsTypeOnly: isTypeOnlySymbol(exported, checker) });
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
function isTypeOnlySymbol(s: Symbol): boolean {
|
||||
return !(s.flags & SymbolFlags.Value);
|
||||
function isTypeOnlySymbol(s: Symbol, checker: TypeChecker): boolean {
|
||||
return !(skipAlias(s, checker).flags & SymbolFlags.Value);
|
||||
}
|
||||
|
||||
function getFixForImport(
|
||||
@@ -398,7 +398,7 @@ namespace ts.codefix {
|
||||
// Maps symbol id to info for modules providing that symbol (original export + re-exports).
|
||||
const originalSymbolToExportInfos = createMultiMap<SymbolExportInfo>();
|
||||
function addSymbol(moduleSymbol: Symbol, exportedSymbol: Symbol, importKind: ImportKind): void {
|
||||
originalSymbolToExportInfos.add(getUniqueSymbolId(exportedSymbol, checker).toString(), { moduleSymbol, importKind, exportedSymbolIsTypeOnly: isTypeOnlySymbol(exportedSymbol) });
|
||||
originalSymbolToExportInfos.add(getUniqueSymbolId(exportedSymbol, checker).toString(), { moduleSymbol, importKind, exportedSymbolIsTypeOnly: isTypeOnlySymbol(exportedSymbol, checker) });
|
||||
}
|
||||
forEachExternalModuleToImportFrom(checker, sourceFile, program.getSourceFiles(), moduleSymbol => {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
@@ -424,7 +424,7 @@ namespace ts.codefix {
|
||||
if (!exported) return undefined;
|
||||
const { symbol, kind } = exported;
|
||||
const info = getDefaultExportInfoWorker(symbol, moduleSymbol, checker, compilerOptions);
|
||||
return info && { symbol, symbolForMeaning: info.symbolForMeaning, name: info.name, kind };
|
||||
return info && { symbol, kind, ...info };
|
||||
}
|
||||
|
||||
function getDefaultLikeExportWorker(moduleSymbol: Symbol, checker: TypeChecker): { readonly symbol: Symbol, readonly kind: ImportKind.Default | ImportKind.Equals } | undefined {
|
||||
|
||||
@@ -25,24 +25,21 @@ namespace ts.codefix {
|
||||
registerCodeFix({
|
||||
errorCodes,
|
||||
getCodeActions(context) {
|
||||
const { sourceFile, program, span: { start }, errorCode, cancellationToken } = context;
|
||||
if (isSourceFileJS(sourceFile)) {
|
||||
return undefined; // TODO: GH#20113
|
||||
}
|
||||
const { sourceFile, program, span: { start }, errorCode, cancellationToken, host } = context;
|
||||
|
||||
const token = getTokenAtPosition(sourceFile, start);
|
||||
let declaration!: Declaration | undefined;
|
||||
const changes = textChanges.ChangeTracker.with(context, changes => { declaration = doChange(changes, sourceFile, token, errorCode, program, cancellationToken, /*markSeenseen*/ returnTrue); });
|
||||
const changes = textChanges.ChangeTracker.with(context, changes => { declaration = doChange(changes, sourceFile, token, errorCode, program, cancellationToken, /*markSeen*/ returnTrue, host); });
|
||||
const name = declaration && getNameOfDeclaration(declaration);
|
||||
return !name || changes.length === 0 ? undefined
|
||||
: [createCodeFixAction(fixId, changes, [getDiagnostic(errorCode, token), name.getText(sourceFile)], fixId, Diagnostics.Infer_all_types_from_usage)];
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions(context) {
|
||||
const { sourceFile, program, cancellationToken } = context;
|
||||
const { sourceFile, program, cancellationToken, host } = context;
|
||||
const markSeen = nodeSeenTracker();
|
||||
return codeFixAll(context, errorCodes, (changes, err) => {
|
||||
doChange(changes, sourceFile, getTokenAtPosition(err.file, err.start), err.code, program, cancellationToken, markSeen);
|
||||
doChange(changes, sourceFile, getTokenAtPosition(err.file, err.start), err.code, program, cancellationToken, markSeen, host);
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -50,7 +47,7 @@ namespace ts.codefix {
|
||||
function getDiagnostic(errorCode: number, token: Node): DiagnosticMessage {
|
||||
switch (errorCode) {
|
||||
case Diagnostics.Parameter_0_implicitly_has_an_1_type.code:
|
||||
return isSetAccessor(getContainingFunction(token)!) ? Diagnostics.Infer_type_of_0_from_usage : Diagnostics.Infer_parameter_types_from_usage; // TODO: GH#18217
|
||||
return isSetAccessorDeclaration(getContainingFunction(token)!) ? Diagnostics.Infer_type_of_0_from_usage : Diagnostics.Infer_parameter_types_from_usage; // TODO: GH#18217
|
||||
case Diagnostics.Rest_parameter_0_implicitly_has_an_any_type.code:
|
||||
return Diagnostics.Infer_parameter_types_from_usage;
|
||||
default:
|
||||
@@ -58,8 +55,8 @@ namespace ts.codefix {
|
||||
}
|
||||
}
|
||||
|
||||
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, token: Node, errorCode: number, program: Program, cancellationToken: CancellationToken, markSeen: NodeSeenTracker): Declaration | undefined {
|
||||
if (!isParameterPropertyModifier(token.kind) && token.kind !== SyntaxKind.Identifier && token.kind !== SyntaxKind.DotDotDotToken) {
|
||||
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, token: Node, errorCode: number, program: Program, cancellationToken: CancellationToken, markSeen: NodeSeenTracker, host: LanguageServiceHost): Declaration | undefined {
|
||||
if (!isParameterPropertyModifier(token.kind) && token.kind !== SyntaxKind.Identifier && token.kind !== SyntaxKind.DotDotDotToken && token.kind !== SyntaxKind.ThisKeyword) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -69,7 +66,15 @@ namespace ts.codefix {
|
||||
case Diagnostics.Member_0_implicitly_has_an_1_type.code:
|
||||
case Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined.code:
|
||||
if ((isVariableDeclaration(parent) && markSeen(parent)) || isPropertyDeclaration(parent) || isPropertySignature(parent)) { // handle bad location
|
||||
annotateVariableDeclaration(changes, sourceFile, parent, program, cancellationToken);
|
||||
annotateVariableDeclaration(changes, sourceFile, parent, program, host, cancellationToken);
|
||||
return parent;
|
||||
}
|
||||
if (isPropertyAccessExpression(parent)) {
|
||||
const type = inferTypeForVariableFromUsage(parent.name, program, cancellationToken);
|
||||
const typeNode = type && getTypeNodeIfAccessible(type, parent, program, host);
|
||||
if (typeNode) {
|
||||
changes.tryInsertJSDocType(sourceFile, parent, typeNode);
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
return undefined;
|
||||
@@ -77,7 +82,7 @@ namespace ts.codefix {
|
||||
case Diagnostics.Variable_0_implicitly_has_an_1_type.code: {
|
||||
const symbol = program.getTypeChecker().getSymbolAtLocation(token);
|
||||
if (symbol && symbol.valueDeclaration && isVariableDeclaration(symbol.valueDeclaration) && markSeen(symbol.valueDeclaration)) {
|
||||
annotateVariableDeclaration(changes, sourceFile, symbol.valueDeclaration, program, cancellationToken);
|
||||
annotateVariableDeclaration(changes, sourceFile, symbol.valueDeclaration, program, host, cancellationToken);
|
||||
return symbol.valueDeclaration;
|
||||
}
|
||||
return undefined;
|
||||
@@ -92,15 +97,15 @@ namespace ts.codefix {
|
||||
switch (errorCode) {
|
||||
// Parameter declarations
|
||||
case Diagnostics.Parameter_0_implicitly_has_an_1_type.code:
|
||||
if (isSetAccessor(containingFunction)) {
|
||||
annotateSetAccessor(changes, sourceFile, containingFunction, program, cancellationToken);
|
||||
if (isSetAccessorDeclaration(containingFunction)) {
|
||||
annotateSetAccessor(changes, sourceFile, containingFunction, program, host, cancellationToken);
|
||||
return containingFunction;
|
||||
}
|
||||
// falls through
|
||||
case Diagnostics.Rest_parameter_0_implicitly_has_an_any_type.code:
|
||||
if (markSeen(containingFunction)) {
|
||||
const param = cast(parent, isParameter);
|
||||
annotateParameters(changes, param, containingFunction, sourceFile, program, cancellationToken);
|
||||
annotateParameters(changes, param, containingFunction, sourceFile, program, host, cancellationToken);
|
||||
return param;
|
||||
}
|
||||
return undefined;
|
||||
@@ -108,16 +113,16 @@ namespace ts.codefix {
|
||||
// Get Accessor declarations
|
||||
case Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation.code:
|
||||
case Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type.code:
|
||||
if (isGetAccessor(containingFunction) && isIdentifier(containingFunction.name)) {
|
||||
annotate(changes, sourceFile, containingFunction, inferTypeForVariableFromUsage(containingFunction.name, program, cancellationToken), program);
|
||||
if (isGetAccessorDeclaration(containingFunction) && isIdentifier(containingFunction.name)) {
|
||||
annotate(changes, sourceFile, containingFunction, inferTypeForVariableFromUsage(containingFunction.name, program, cancellationToken), program, host);
|
||||
return containingFunction;
|
||||
}
|
||||
return undefined;
|
||||
|
||||
// Set Accessor declarations
|
||||
case Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation.code:
|
||||
if (isSetAccessor(containingFunction)) {
|
||||
annotateSetAccessor(changes, sourceFile, containingFunction, program, cancellationToken);
|
||||
if (isSetAccessorDeclaration(containingFunction)) {
|
||||
annotateSetAccessor(changes, sourceFile, containingFunction, program, host, cancellationToken);
|
||||
return containingFunction;
|
||||
}
|
||||
return undefined;
|
||||
@@ -127,9 +132,9 @@ namespace ts.codefix {
|
||||
}
|
||||
}
|
||||
|
||||
function annotateVariableDeclaration(changes: textChanges.ChangeTracker, sourceFile: SourceFile, declaration: VariableDeclaration | PropertyDeclaration | PropertySignature, program: Program, cancellationToken: CancellationToken): void {
|
||||
function annotateVariableDeclaration(changes: textChanges.ChangeTracker, sourceFile: SourceFile, declaration: VariableDeclaration | PropertyDeclaration | PropertySignature, program: Program, host: LanguageServiceHost, cancellationToken: CancellationToken): void {
|
||||
if (isIdentifier(declaration.name)) {
|
||||
annotate(changes, sourceFile, declaration, inferTypeForVariableFromUsage(declaration.name, program, cancellationToken), program);
|
||||
annotate(changes, sourceFile, declaration, inferTypeForVariableFromUsage(declaration.name, program, cancellationToken), program, host);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,40 +150,67 @@ namespace ts.codefix {
|
||||
return false;
|
||||
}
|
||||
|
||||
function annotateParameters(changes: textChanges.ChangeTracker, parameterDeclaration: ParameterDeclaration, containingFunction: FunctionLike, sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken): void {
|
||||
function annotateParameters(changes: textChanges.ChangeTracker, parameterDeclaration: ParameterDeclaration, containingFunction: FunctionLike, sourceFile: SourceFile, program: Program, host: LanguageServiceHost, cancellationToken: CancellationToken): void {
|
||||
if (!isIdentifier(parameterDeclaration.name) || !isApplicableFunctionForInference(containingFunction)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const types = inferTypeForParametersFromUsage(containingFunction, sourceFile, program, cancellationToken) ||
|
||||
containingFunction.parameters.map(p => isIdentifier(p.name) ? inferTypeForVariableFromUsage(p.name, program, cancellationToken) : undefined);
|
||||
// We didn't actually find a set of type inference positions matching each parameter position
|
||||
if (!types || containingFunction.parameters.length !== types.length) {
|
||||
return;
|
||||
}
|
||||
const parameterInferences = inferTypeForParametersFromUsage(containingFunction, sourceFile, program, cancellationToken) ||
|
||||
containingFunction.parameters.map<ParameterInference>(p => ({
|
||||
declaration: p,
|
||||
type: isIdentifier(p.name) ? inferTypeForVariableFromUsage(p.name, program, cancellationToken) : undefined
|
||||
}));
|
||||
Debug.assert(containingFunction.parameters.length === parameterInferences.length);
|
||||
|
||||
zipWith(containingFunction.parameters, types, (parameter, type) => {
|
||||
if (!parameter.type && !parameter.initializer) {
|
||||
annotate(changes, sourceFile, parameter, type, program);
|
||||
if (isInJSFile(containingFunction)) {
|
||||
annotateJSDocParameters(changes, sourceFile, parameterInferences, program, host);
|
||||
}
|
||||
else {
|
||||
for (const { declaration, type } of parameterInferences) {
|
||||
if (declaration && !declaration.type && !declaration.initializer) {
|
||||
annotate(changes, sourceFile, declaration, type, program, host);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function annotateSetAccessor(changes: textChanges.ChangeTracker, sourceFile: SourceFile, setAccessorDeclaration: SetAccessorDeclaration, program: Program, cancellationToken: CancellationToken): void {
|
||||
function annotateSetAccessor(changes: textChanges.ChangeTracker, sourceFile: SourceFile, setAccessorDeclaration: SetAccessorDeclaration, program: Program, host: LanguageServiceHost, cancellationToken: CancellationToken): void {
|
||||
const param = firstOrUndefined(setAccessorDeclaration.parameters);
|
||||
if (param && isIdentifier(setAccessorDeclaration.name) && isIdentifier(param.name)) {
|
||||
const type = inferTypeForVariableFromUsage(setAccessorDeclaration.name, program, cancellationToken) ||
|
||||
inferTypeForVariableFromUsage(param.name, program, cancellationToken);
|
||||
annotate(changes, sourceFile, param, type, program);
|
||||
if (isInJSFile(setAccessorDeclaration)) {
|
||||
annotateJSDocParameters(changes, sourceFile, [{ declaration: param, type }], program, host);
|
||||
}
|
||||
else {
|
||||
annotate(changes, sourceFile, param, type, program, host);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function annotate(changes: textChanges.ChangeTracker, sourceFile: SourceFile, declaration: textChanges.TypeAnnotatable, type: Type | undefined, program: Program): void {
|
||||
const typeNode = type && getTypeNodeIfAccessible(type, declaration, program.getTypeChecker());
|
||||
if (typeNode) changes.tryInsertTypeAnnotation(sourceFile, declaration, typeNode);
|
||||
function annotate(changes: textChanges.ChangeTracker, sourceFile: SourceFile, declaration: textChanges.TypeAnnotatable, type: Type | undefined, program: Program, host: LanguageServiceHost): void {
|
||||
const typeNode = type && getTypeNodeIfAccessible(type, declaration, program, host);
|
||||
if (typeNode) {
|
||||
if (isInJSFile(sourceFile) && declaration.kind !== SyntaxKind.PropertySignature) {
|
||||
changes.tryInsertJSDocType(sourceFile, declaration, typeNode);
|
||||
}
|
||||
else {
|
||||
changes.tryInsertTypeAnnotation(sourceFile, declaration, typeNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getTypeNodeIfAccessible(type: Type, enclosingScope: Node, checker: TypeChecker): TypeNode | undefined {
|
||||
function annotateJSDocParameters(changes: textChanges.ChangeTracker, sourceFile: SourceFile, parameterInferences: ParameterInference[], program: Program, host: LanguageServiceHost): void {
|
||||
const result = mapDefined(parameterInferences, inference => {
|
||||
const param = inference.declaration;
|
||||
const typeNode = inference.type && getTypeNodeIfAccessible(inference.type, param, program, host);
|
||||
return typeNode && !param.initializer && !getJSDocType(param) ? { ...inference, typeNode } : undefined;
|
||||
});
|
||||
changes.tryInsertJSDocParameters(sourceFile, result);
|
||||
}
|
||||
|
||||
function getTypeNodeIfAccessible(type: Type, enclosingScope: Node, program: Program, host: LanguageServiceHost): TypeNode | undefined {
|
||||
const checker = program.getTypeChecker();
|
||||
let typeIsAccessible = true;
|
||||
const notAccessible = () => { typeIsAccessible = false; };
|
||||
const res = checker.typeToTypeNode(type, enclosingScope, /*flags*/ undefined, {
|
||||
@@ -189,6 +221,14 @@ namespace ts.codefix {
|
||||
reportInaccessibleThisError: notAccessible,
|
||||
reportPrivateInBaseOfClassExpression: notAccessible,
|
||||
reportInaccessibleUniqueSymbolError: notAccessible,
|
||||
moduleResolverHost: {
|
||||
readFile: host.readFile,
|
||||
fileExists: host.fileExists,
|
||||
directoryExists: host.directoryExists,
|
||||
getSourceFiles: program.getSourceFiles,
|
||||
getCurrentDirectory: program.getCurrentDirectory,
|
||||
getCommonSourceDirectory: program.getCommonSourceDirectory,
|
||||
}
|
||||
});
|
||||
return typeIsAccessible ? res : undefined;
|
||||
}
|
||||
@@ -196,14 +236,14 @@ namespace ts.codefix {
|
||||
function getReferences(token: PropertyName | Token<SyntaxKind.ConstructorKeyword>, program: Program, cancellationToken: CancellationToken): ReadonlyArray<Identifier> {
|
||||
// Position shouldn't matter since token is not a SourceFile.
|
||||
return mapDefined(FindAllReferences.getReferenceEntriesForNode(-1, token, program, program.getSourceFiles(), cancellationToken), entry =>
|
||||
entry.type === "node" ? tryCast(entry.node, isIdentifier) : undefined);
|
||||
entry.kind !== FindAllReferences.EntryKind.Span ? tryCast(entry.node, isIdentifier) : undefined);
|
||||
}
|
||||
|
||||
function inferTypeForVariableFromUsage(token: Identifier, program: Program, cancellationToken: CancellationToken): Type | undefined {
|
||||
return InferFromReference.inferTypeFromReferences(getReferences(token, program, cancellationToken), program.getTypeChecker(), cancellationToken);
|
||||
}
|
||||
|
||||
function inferTypeForParametersFromUsage(containingFunction: FunctionLikeDeclaration, sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken): (Type | undefined)[] | undefined {
|
||||
function inferTypeForParametersFromUsage(containingFunction: FunctionLikeDeclaration, sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken): ParameterInference[] | undefined {
|
||||
switch (containingFunction.kind) {
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
@@ -219,6 +259,13 @@ namespace ts.codefix {
|
||||
}
|
||||
}
|
||||
|
||||
interface ParameterInference {
|
||||
declaration: ParameterDeclaration;
|
||||
type?: Type;
|
||||
typeNode?: TypeNode;
|
||||
isOptional?: boolean;
|
||||
}
|
||||
|
||||
namespace InferFromReference {
|
||||
interface CallContext {
|
||||
argumentTypes: Type[];
|
||||
@@ -246,7 +293,7 @@ namespace ts.codefix {
|
||||
return getTypeFromUsageContext(usageContext, checker);
|
||||
}
|
||||
|
||||
export function inferTypeForParametersFromReferences(references: ReadonlyArray<Identifier>, declaration: FunctionLikeDeclaration, checker: TypeChecker, cancellationToken: CancellationToken): (Type | undefined)[] | undefined {
|
||||
export function inferTypeForParametersFromReferences(references: ReadonlyArray<Identifier>, declaration: FunctionLikeDeclaration, checker: TypeChecker, cancellationToken: CancellationToken): ParameterInference[] | undefined {
|
||||
if (references.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -265,8 +312,10 @@ namespace ts.codefix {
|
||||
return callContexts && declaration.parameters.map((parameter, parameterIndex) => {
|
||||
const types: Type[] = [];
|
||||
const isRest = isRestParameter(parameter);
|
||||
let isOptional = false;
|
||||
for (const callContext of callContexts) {
|
||||
if (callContext.argumentTypes.length <= parameterIndex) {
|
||||
isOptional = isInJSFile(declaration);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -280,10 +329,14 @@ namespace ts.codefix {
|
||||
}
|
||||
}
|
||||
if (!types.length) {
|
||||
return undefined;
|
||||
return { declaration: parameter };
|
||||
}
|
||||
const type = checker.getWidenedType(checker.getUnionType(types, UnionReduction.Subtype));
|
||||
return isRest ? checker.createArrayType(type) : type;
|
||||
return {
|
||||
type: isRest ? checker.createArrayType(type) : type,
|
||||
isOptional: isOptional && !isRest,
|
||||
declaration: parameter
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+17
-13
@@ -43,7 +43,7 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
const contextToken = findPrecedingToken(position, sourceFile);
|
||||
if (triggerCharacter && (!contextToken || !isValidTrigger(sourceFile, triggerCharacter, contextToken, position))) return undefined;
|
||||
if (triggerCharacter && !isValidTrigger(sourceFile, triggerCharacter, contextToken, position)) return undefined;
|
||||
|
||||
if (isInString(sourceFile, position, contextToken)) {
|
||||
return !contextToken || !isStringLiteralLike(contextToken)
|
||||
@@ -1200,9 +1200,9 @@ namespace ts.Completions {
|
||||
function tryGetJsxCompletionSymbols(): GlobalsSearch {
|
||||
const jsxContainer = tryGetContainingJsxElement(contextToken);
|
||||
// Cursor is inside a JSX self-closing element or opening element
|
||||
const attrsType = jsxContainer && typeChecker.getAllAttributesTypeFromJsxOpeningLikeElement(jsxContainer);
|
||||
const attrsType = jsxContainer && typeChecker.getContextualType(jsxContainer.attributes);
|
||||
if (!attrsType) return GlobalsSearch.Continue;
|
||||
symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), jsxContainer!.attributes.properties);
|
||||
symbols = filterJsxAttributes(getPropertiesForObjectExpression(attrsType, jsxContainer!.attributes, typeChecker), jsxContainer!.attributes.properties);
|
||||
completionKind = CompletionKind.MemberLike;
|
||||
isNewIdentifierLocation = false;
|
||||
return GlobalsSearch.Success;
|
||||
@@ -1397,7 +1397,7 @@ namespace ts.Completions {
|
||||
if (resolvedModuleSymbol !== moduleSymbol &&
|
||||
// Don't add another completion for `export =` of a symbol that's already global.
|
||||
// So in `declare namespace foo {} declare module "foo" { export = foo; }`, there will just be the global completion for `foo`.
|
||||
resolvedModuleSymbol.declarations.some(d => !!d.getSourceFile().externalModuleIndicator)) {
|
||||
some(resolvedModuleSymbol.declarations, d => !!d.getSourceFile().externalModuleIndicator)) {
|
||||
symbols.push(resolvedModuleSymbol);
|
||||
symbolToOriginInfoMap[getSymbolId(resolvedModuleSymbol)] = { kind: SymbolOriginInfoKind.Export, moduleSymbol, isDefaultExport: false };
|
||||
}
|
||||
@@ -1410,7 +1410,7 @@ namespace ts.Completions {
|
||||
// If `symbol.parent !== ...`, this comes from an `export * from "foo"` re-export. Those don't create new symbols.
|
||||
// If `some(...)`, this comes from an `export { foo } from "foo"` re-export, which creates a new symbol (thus isn't caught by the first check).
|
||||
if (typeChecker.getMergedSymbol(symbol.parent!) !== resolvedModuleSymbol
|
||||
|| some(symbol.declarations, d => isExportSpecifier(d) && !!d.parent.parent.moduleSpecifier)) {
|
||||
|| some(symbol.declarations, d => isExportSpecifier(d) && !d.propertyName && !!d.parent.parent.moduleSpecifier)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1713,6 +1713,9 @@ namespace ts.Completions {
|
||||
break;
|
||||
case SyntaxKind.AsteriskToken:
|
||||
return isMethodDeclaration(parent) ? tryCast(parent.parent, isObjectLiteralExpression) : undefined;
|
||||
case SyntaxKind.Identifier:
|
||||
return (contextToken as Identifier).text === "async" && isShorthandPropertyAssignment(contextToken.parent)
|
||||
? contextToken.parent.parent : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1928,7 +1931,6 @@ namespace ts.Completions {
|
||||
// Previous token may have been a keyword that was converted to an identifier.
|
||||
switch (keywordForNode(contextToken)) {
|
||||
case SyntaxKind.AbstractKeyword:
|
||||
case SyntaxKind.AsyncKeyword:
|
||||
case SyntaxKind.ClassKeyword:
|
||||
case SyntaxKind.ConstKeyword:
|
||||
case SyntaxKind.DeclareKeyword:
|
||||
@@ -1943,6 +1945,8 @@ namespace ts.Completions {
|
||||
case SyntaxKind.VarKeyword:
|
||||
case SyntaxKind.YieldKeyword:
|
||||
return true;
|
||||
case SyntaxKind.AsyncKeyword:
|
||||
return isPropertyDeclaration(contextToken.parent);
|
||||
}
|
||||
|
||||
return isDeclarationName(contextToken)
|
||||
@@ -2146,7 +2150,7 @@ namespace ts.Completions {
|
||||
case KeywordCompletionFilters.None:
|
||||
return false;
|
||||
case KeywordCompletionFilters.All:
|
||||
return kind === SyntaxKind.AsyncKeyword || !isContextualKeyword(kind) && !isClassMemberCompletionKeyword(kind) || kind === SyntaxKind.DeclareKeyword || kind === SyntaxKind.ModuleKeyword
|
||||
return kind === SyntaxKind.AsyncKeyword || SyntaxKind.AwaitKeyword || !isContextualKeyword(kind) && !isClassMemberCompletionKeyword(kind) || kind === SyntaxKind.DeclareKeyword || kind === SyntaxKind.ModuleKeyword
|
||||
|| isTypeKeyword(kind) && kind !== SyntaxKind.UndefinedKeyword;
|
||||
case KeywordCompletionFilters.ClassElementKeywords:
|
||||
return isClassMemberCompletionKeyword(kind);
|
||||
@@ -2207,7 +2211,7 @@ namespace ts.Completions {
|
||||
return jsdoc && jsdoc.tags && (rangeContainsPosition(jsdoc, position) ? findLast(jsdoc.tags, tag => tag.pos < position) : undefined);
|
||||
}
|
||||
|
||||
function getPropertiesForObjectExpression(contextualType: Type, obj: ObjectLiteralExpression, checker: TypeChecker): Symbol[] {
|
||||
function getPropertiesForObjectExpression(contextualType: Type, obj: ObjectLiteralExpression | JsxAttributes, checker: TypeChecker): Symbol[] {
|
||||
return contextualType.isUnion()
|
||||
? checker.getAllPossiblePropertiesOfTypes(contextualType.types.filter(memberType =>
|
||||
// If we're providing completions for an object literal, skip primitive, array-like, or callable types since those shouldn't be implemented by object literals.
|
||||
@@ -2272,7 +2276,7 @@ namespace ts.Completions {
|
||||
return !!type.getStringIndexType() || !!type.getNumberIndexType();
|
||||
}
|
||||
|
||||
function isValidTrigger(sourceFile: SourceFile, triggerCharacter: CompletionsTriggerCharacter, contextToken: Node, position: number): boolean {
|
||||
function isValidTrigger(sourceFile: SourceFile, triggerCharacter: CompletionsTriggerCharacter, contextToken: Node | undefined, position: number): boolean {
|
||||
switch (triggerCharacter) {
|
||||
case ".":
|
||||
case "@":
|
||||
@@ -2281,14 +2285,14 @@ namespace ts.Completions {
|
||||
case "'":
|
||||
case "`":
|
||||
// Only automatically bring up completions if this is an opening quote.
|
||||
return isStringLiteralOrTemplate(contextToken) && position === contextToken.getStart(sourceFile) + 1;
|
||||
return !!contextToken && isStringLiteralOrTemplate(contextToken) && position === contextToken.getStart(sourceFile) + 1;
|
||||
case "<":
|
||||
// Opening JSX tag
|
||||
return contextToken.kind === SyntaxKind.LessThanToken && (!isBinaryExpression(contextToken.parent) || binaryExpressionMayBeOpenTag(contextToken.parent));
|
||||
return !!contextToken && contextToken.kind === SyntaxKind.LessThanToken && (!isBinaryExpression(contextToken.parent) || binaryExpressionMayBeOpenTag(contextToken.parent));
|
||||
case "/":
|
||||
return isStringLiteralLike(contextToken)
|
||||
return !!contextToken && (isStringLiteralLike(contextToken)
|
||||
? !!tryGetImportFromModuleSpecifier(contextToken)
|
||||
: contextToken.kind === SyntaxKind.SlashToken && isJsxClosingElement(contextToken.parent);
|
||||
: contextToken.kind === SyntaxKind.SlashToken && isJsxClosingElement(contextToken.parent));
|
||||
default:
|
||||
return Debug.assertNever(triggerCharacter);
|
||||
}
|
||||
|
||||
@@ -13,19 +13,20 @@ namespace ts.FindAllReferences {
|
||||
| { readonly type: DefinitionKind.This; readonly node: Node }
|
||||
| { readonly type: DefinitionKind.String; readonly node: StringLiteral };
|
||||
|
||||
export const enum EntryKind { Span, Node, StringLiteral, SearchedLocalFoundProperty, SearchedPropertyFoundLocal }
|
||||
export type NodeEntryKind = EntryKind.Node | EntryKind.StringLiteral | EntryKind.SearchedLocalFoundProperty | EntryKind.SearchedPropertyFoundLocal;
|
||||
export type Entry = NodeEntry | SpanEntry;
|
||||
export interface NodeEntry {
|
||||
type: "node";
|
||||
node: Node;
|
||||
isInString?: true;
|
||||
readonly kind: NodeEntryKind;
|
||||
readonly node: Node;
|
||||
}
|
||||
export interface SpanEntry {
|
||||
type: "span";
|
||||
fileName: string;
|
||||
textSpan: TextSpan;
|
||||
readonly kind: EntryKind.Span;
|
||||
readonly fileName: string;
|
||||
readonly textSpan: TextSpan;
|
||||
}
|
||||
export function nodeEntry(node: Node, isInString?: true): NodeEntry {
|
||||
return { type: "node", node: (node as NamedDeclaration).name || node, isInString };
|
||||
export function nodeEntry(node: Node, kind: NodeEntryKind = EntryKind.Node): NodeEntry {
|
||||
return { kind, node: (node as NamedDeclaration).name || node };
|
||||
}
|
||||
|
||||
export interface Options {
|
||||
@@ -33,7 +34,7 @@ namespace ts.FindAllReferences {
|
||||
readonly findInComments?: boolean;
|
||||
/**
|
||||
* True if we are renaming the symbol.
|
||||
* If so, we will find fewer references -- if it is referenced by several different names, we sill only find references for the original name.
|
||||
* If so, we will find fewer references -- if it is referenced by several different names, we still only find references for the original name.
|
||||
*/
|
||||
readonly isForRename?: boolean;
|
||||
/** True if we are searching for implementations. We will have a different method of adding references if so. */
|
||||
@@ -84,10 +85,15 @@ namespace ts.FindAllReferences {
|
||||
}
|
||||
}
|
||||
|
||||
export function findReferencedEntries(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray<SourceFile>, node: Node, position: number, options: Options | undefined): ReferenceEntry[] | undefined {
|
||||
return map(flattenEntries(Core.getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, options)), toReferenceEntry);
|
||||
export function findReferenceOrRenameEntries<T>(
|
||||
program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray<SourceFile>, node: Node, position: number, options: Options | undefined,
|
||||
convertEntry: ToReferenceOrRenameEntry<T>,
|
||||
): T[] | undefined {
|
||||
return map(flattenEntries(Core.getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, options)), entry => convertEntry(entry, node));
|
||||
}
|
||||
|
||||
export type ToReferenceOrRenameEntry<T> = (entry: Entry, originalNode: Node) => T;
|
||||
|
||||
export function getReferenceEntriesForNode(position: number, node: Node, program: Program, sourceFiles: ReadonlyArray<SourceFile>, cancellationToken: CancellationToken, options: Options = {}, sourceFilesSet: ReadonlyMap<true> = arrayToSet(sourceFiles, f => f.fileName)): Entry[] | undefined {
|
||||
return flattenEntries(Core.getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, options, sourceFilesSet));
|
||||
}
|
||||
@@ -137,32 +143,70 @@ namespace ts.FindAllReferences {
|
||||
|
||||
function getDefinitionKindAndDisplayParts(symbol: Symbol, checker: TypeChecker, node: Node): { displayParts: SymbolDisplayPart[], kind: ScriptElementKind } {
|
||||
const meaning = Core.getIntersectingMeaningFromDeclarations(node, symbol);
|
||||
const enclosingDeclaration = firstOrUndefined(symbol.declarations) || node;
|
||||
const enclosingDeclaration = symbol.declarations && firstOrUndefined(symbol.declarations) || node;
|
||||
const { displayParts, symbolKind } =
|
||||
SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, enclosingDeclaration.getSourceFile(), enclosingDeclaration, enclosingDeclaration, meaning);
|
||||
return { displayParts, kind: symbolKind };
|
||||
}
|
||||
|
||||
function toReferenceEntry(entry: Entry): ReferenceEntry {
|
||||
if (entry.type === "span") {
|
||||
return { textSpan: entry.textSpan, fileName: entry.fileName, isWriteAccess: false, isDefinition: false };
|
||||
}
|
||||
export function toRenameLocation(entry: Entry, originalNode: Node): RenameLocation {
|
||||
return { ...entryToDocumentSpan(entry), ...getPrefixAndSuffixText(entry, originalNode) };
|
||||
}
|
||||
|
||||
const { node, isInString } = entry;
|
||||
const sourceFile = node.getSourceFile();
|
||||
export function toReferenceEntry(entry: Entry): ReferenceEntry {
|
||||
const { textSpan, fileName } = entryToDocumentSpan(entry);
|
||||
if (entry.kind === EntryKind.Span) {
|
||||
return { textSpan, fileName, isWriteAccess: false, isDefinition: false };
|
||||
}
|
||||
const { kind, node } = entry;
|
||||
return {
|
||||
fileName: sourceFile.fileName,
|
||||
textSpan: getTextSpan(node, sourceFile),
|
||||
textSpan,
|
||||
fileName,
|
||||
isWriteAccess: isWriteAccessForReference(node),
|
||||
isDefinition: node.kind === SyntaxKind.DefaultKeyword
|
||||
|| !!getDeclarationFromName(node)
|
||||
|| isLiteralComputedPropertyDeclarationName(node),
|
||||
isInString,
|
||||
isInString: kind === EntryKind.StringLiteral ? true : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
function entryToDocumentSpan(entry: Entry): DocumentSpan {
|
||||
if (entry.kind === EntryKind.Span) {
|
||||
return { textSpan: entry.textSpan, fileName: entry.fileName };
|
||||
}
|
||||
else {
|
||||
const sourceFile = entry.node.getSourceFile();
|
||||
return { textSpan: getTextSpan(entry.node, sourceFile), fileName: sourceFile.fileName };
|
||||
}
|
||||
}
|
||||
|
||||
function getPrefixAndSuffixText(entry: Entry, originalNode: Node): { readonly prefixText?: string, readonly suffixText?: string } {
|
||||
if (entry.kind !== EntryKind.Span && isIdentifier(originalNode)) {
|
||||
const { node, kind } = entry;
|
||||
const name = originalNode.text;
|
||||
const isShorthandAssignment = isShorthandPropertyAssignment(node.parent);
|
||||
if (isShorthandAssignment || isObjectBindingElementWithoutPropertyName(node.parent)) {
|
||||
if (kind === EntryKind.SearchedLocalFoundProperty) {
|
||||
return { prefixText: name + ": " };
|
||||
}
|
||||
else if (kind === EntryKind.SearchedPropertyFoundLocal) {
|
||||
return { suffixText: ": " + name };
|
||||
}
|
||||
else {
|
||||
return isShorthandAssignment
|
||||
// In `const o = { x }; o.x`, symbolAtLocation at `x` in `{ x }` is the property symbol.
|
||||
? { suffixText: ": " + name }
|
||||
// For a binding element `const { x } = o;`, symbolAtLocation at `x` is the property symbol.
|
||||
: { prefixText: name + ": " };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return emptyOptions;
|
||||
}
|
||||
|
||||
function toImplementationLocation(entry: Entry, checker: TypeChecker): ImplementationLocation {
|
||||
if (entry.type === "node") {
|
||||
if (entry.kind !== EntryKind.Span) {
|
||||
const { node } = entry;
|
||||
const sourceFile = node.getSourceFile();
|
||||
return { textSpan: getTextSpan(node, sourceFile), fileName: sourceFile.fileName, ...implementationKindDisplayParts(node, checker) };
|
||||
@@ -196,18 +240,18 @@ namespace ts.FindAllReferences {
|
||||
}
|
||||
|
||||
export function toHighlightSpan(entry: Entry): { fileName: string, span: HighlightSpan } {
|
||||
if (entry.type === "span") {
|
||||
if (entry.kind === EntryKind.Span) {
|
||||
const { fileName, textSpan } = entry;
|
||||
return { fileName, span: { textSpan, kind: HighlightSpanKind.reference } };
|
||||
}
|
||||
|
||||
const { node, isInString } = entry;
|
||||
const { node, kind } = entry;
|
||||
const sourceFile = node.getSourceFile();
|
||||
const writeAccess = isWriteAccessForReference(node);
|
||||
const span: HighlightSpan = {
|
||||
textSpan: getTextSpan(node, sourceFile),
|
||||
kind: writeAccess ? HighlightSpanKind.writtenReference : HighlightSpanKind.reference,
|
||||
isInString
|
||||
isInString: kind === EntryKind.StringLiteral ? true : undefined,
|
||||
};
|
||||
return { fileName: sourceFile.fileName, span };
|
||||
}
|
||||
@@ -348,11 +392,11 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
}
|
||||
// import("foo") with no qualifier will reference the `export =` of the module, which may be referenced anyway.
|
||||
return { type: "node", node: reference.literal };
|
||||
return nodeEntry(reference.literal);
|
||||
}
|
||||
else {
|
||||
return {
|
||||
type: "span",
|
||||
kind: EntryKind.Span,
|
||||
fileName: reference.referencingFile.fileName,
|
||||
textSpan: createTextSpanFromRange(reference.ref),
|
||||
};
|
||||
@@ -366,7 +410,7 @@ namespace ts.FindAllReferences.Core {
|
||||
break;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
if (sourceFilesSet.has(decl.getSourceFile().fileName)) {
|
||||
references.push({ type: "node", node: (decl as ModuleDeclaration).name });
|
||||
references.push(nodeEntry((decl as ModuleDeclaration).name));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -422,7 +466,7 @@ namespace ts.FindAllReferences.Core {
|
||||
searchForImportsOfExport(node, symbol, { exportingModuleSymbol: Debug.assertDefined(symbol.parent, "Expected export symbol to have a parent"), exportKind: ExportKind.Default }, state);
|
||||
}
|
||||
else {
|
||||
const search = state.createSearch(node, symbol, /*comingFrom*/ undefined, { allSearchSymbols: node ? populateSearchSymbolSet(symbol, node, checker, !!options.implementations) : [symbol] });
|
||||
const search = state.createSearch(node, symbol, /*comingFrom*/ undefined, { allSearchSymbols: node ? populateSearchSymbolSet(symbol, node, checker, !!options.isForRename, !!options.implementations) : [symbol] });
|
||||
|
||||
// Try to get the smallest valid scope that we can limit our search to;
|
||||
// otherwise we'll need to search globally (i.e. include each file).
|
||||
@@ -581,21 +625,21 @@ namespace ts.FindAllReferences.Core {
|
||||
* Callback to add references for a particular searched symbol.
|
||||
* This initializes a reference group, so only call this if you will add at least one reference.
|
||||
*/
|
||||
referenceAdder(searchSymbol: Symbol): (node: Node) => void {
|
||||
referenceAdder(searchSymbol: Symbol): (node: Node, kind?: NodeEntryKind) => void {
|
||||
const symbolId = getSymbolId(searchSymbol);
|
||||
let references = this.symbolIdToReferences[symbolId];
|
||||
if (!references) {
|
||||
references = this.symbolIdToReferences[symbolId] = [];
|
||||
this.result.push({ definition: { type: DefinitionKind.Symbol, symbol: searchSymbol }, references });
|
||||
}
|
||||
return node => references.push(nodeEntry(node));
|
||||
return (node, kind) => references.push(nodeEntry(node, kind));
|
||||
}
|
||||
|
||||
/** Add a reference with no associated definition. */
|
||||
addStringOrCommentReference(fileName: string, textSpan: TextSpan): void {
|
||||
this.result.push({
|
||||
definition: undefined,
|
||||
references: [{ type: "span", fileName, textSpan }]
|
||||
references: [{ kind: EntryKind.Span, fileName, textSpan }]
|
||||
});
|
||||
}
|
||||
|
||||
@@ -707,21 +751,6 @@ namespace ts.FindAllReferences.Core {
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function getObjectBindingElementWithoutPropertyName(symbol: Symbol): BindingElement & { name: Identifier } | undefined {
|
||||
const bindingElement = getDeclarationOfKind<BindingElement>(symbol, SyntaxKind.BindingElement);
|
||||
if (bindingElement &&
|
||||
bindingElement.parent.kind === SyntaxKind.ObjectBindingPattern &&
|
||||
isIdentifier(bindingElement.name) &&
|
||||
!bindingElement.propertyName) {
|
||||
return bindingElement as BindingElement & { name: Identifier };
|
||||
}
|
||||
}
|
||||
|
||||
function getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol: Symbol, checker: TypeChecker): Symbol | undefined {
|
||||
const bindingElement = getObjectBindingElementWithoutPropertyName(symbol);
|
||||
return bindingElement && getPropertySymbolFromBindingElement(checker, bindingElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the smallest scope in which a symbol may have named references.
|
||||
* Note that not every construct has been accounted for. This function can
|
||||
@@ -754,7 +783,7 @@ namespace ts.FindAllReferences.Core {
|
||||
|
||||
// If symbol is of object binding pattern element without property name we would want to
|
||||
// look for property too and that could be anywhere
|
||||
if (getObjectBindingElementWithoutPropertyName(symbol)) {
|
||||
if (declarations.some(isObjectBindingElementWithoutPropertyName)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -1099,13 +1128,14 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
}
|
||||
|
||||
function addReference(referenceLocation: Node, relatedSymbol: Symbol, state: State): void {
|
||||
const addRef = state.referenceAdder(relatedSymbol);
|
||||
function addReference(referenceLocation: Node, relatedSymbol: Symbol | RelatedSymbol, state: State): void {
|
||||
const { kind, symbol } = "kind" in relatedSymbol ? relatedSymbol : { kind: undefined, symbol: relatedSymbol };
|
||||
const addRef = state.referenceAdder(symbol);
|
||||
if (state.options.implementations) {
|
||||
addImplementationReferences(referenceLocation, addRef, state);
|
||||
}
|
||||
else {
|
||||
addRef(referenceLocation);
|
||||
addRef(referenceLocation, kind);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1428,7 +1458,7 @@ namespace ts.FindAllReferences.Core {
|
||||
const references = flatMap(sourceFiles, sourceFile => {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
return mapDefined(getPossibleSymbolReferenceNodes(sourceFile, node.text), ref =>
|
||||
isStringLiteral(ref) && ref.text === node.text ? nodeEntry(ref, /*isInString*/ true) : undefined);
|
||||
isStringLiteral(ref) && ref.text === node.text ? nodeEntry(ref, EntryKind.StringLiteral) : undefined);
|
||||
});
|
||||
|
||||
return [{
|
||||
@@ -1439,35 +1469,21 @@ namespace ts.FindAllReferences.Core {
|
||||
|
||||
// For certain symbol kinds, we need to include other symbols in the search set.
|
||||
// This is not needed when searching for re-exports.
|
||||
function populateSearchSymbolSet(symbol: Symbol, location: Node, checker: TypeChecker, implementations: boolean): Symbol[] {
|
||||
function populateSearchSymbolSet(symbol: Symbol, location: Node, checker: TypeChecker, isForRename: boolean, implementations: boolean): Symbol[] {
|
||||
const result: Symbol[] = [];
|
||||
forEachRelatedSymbol<void>(symbol, location, checker,
|
||||
forEachRelatedSymbol<void>(symbol, location, checker, isForRename,
|
||||
(sym, root, base) => { result.push(base || root || sym); },
|
||||
/*allowBaseTypes*/ () => !implementations);
|
||||
return result;
|
||||
}
|
||||
|
||||
function forEachRelatedSymbol<T>(
|
||||
symbol: Symbol, location: Node, checker: TypeChecker,
|
||||
cbSymbol: (symbol: Symbol, rootSymbol?: Symbol, baseSymbol?: Symbol) => T | undefined,
|
||||
symbol: Symbol, location: Node, checker: TypeChecker, isForRenamePopulateSearchSymbolSet: boolean,
|
||||
cbSymbol: (symbol: Symbol, rootSymbol?: Symbol, baseSymbol?: Symbol, kind?: NodeEntryKind) => T | undefined,
|
||||
allowBaseTypes: (rootSymbol: Symbol) => boolean,
|
||||
): T | undefined {
|
||||
const containingObjectLiteralElement = getContainingObjectLiteralElement(location);
|
||||
if (containingObjectLiteralElement) {
|
||||
// If the location is in a context sensitive location (i.e. in an object literal) try
|
||||
// to get a contextual type for it, and add the property symbol from the contextual
|
||||
// type to the search set
|
||||
const contextualType = checker.getContextualType(containingObjectLiteralElement.parent);
|
||||
const res = contextualType && firstDefined(getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker, contextualType, /*unionSymbolOk*/ true), fromRoot);
|
||||
if (res) return res;
|
||||
|
||||
// If the location is name of property symbol from object literal destructuring pattern
|
||||
// Search the property symbol
|
||||
// for ( { property: p2 } of elems) { }
|
||||
const propertySymbol = getPropertySymbolOfDestructuringAssignment(location, checker);
|
||||
const res1 = propertySymbol && cbSymbol(propertySymbol);
|
||||
if (res1) return res1;
|
||||
|
||||
/* Because in short-hand property assignment, location has two meaning : property name and as value of the property
|
||||
* When we do findAllReference at the position of the short-hand property assignment, we would want to have references to position of
|
||||
* property name and variable declaration of the identifier.
|
||||
@@ -1479,8 +1495,29 @@ namespace ts.FindAllReferences.Core {
|
||||
* so that when matching with potential reference symbol, both symbols from property declaration and variable declaration
|
||||
* will be included correctly.
|
||||
*/
|
||||
const shorthandValueSymbol = checker.getShorthandAssignmentValueSymbol(location.parent);
|
||||
const res2 = shorthandValueSymbol && cbSymbol(shorthandValueSymbol);
|
||||
const shorthandValueSymbol = checker.getShorthandAssignmentValueSymbol(location.parent); // gets the local symbol
|
||||
if (shorthandValueSymbol && isForRenamePopulateSearchSymbolSet) {
|
||||
// When renaming 'x' in `const o = { x }`, just rename the local variable, not the property.
|
||||
return cbSymbol(shorthandValueSymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, EntryKind.SearchedLocalFoundProperty);
|
||||
}
|
||||
|
||||
// If the location is in a context sensitive location (i.e. in an object literal) try
|
||||
// to get a contextual type for it, and add the property symbol from the contextual
|
||||
// type to the search set
|
||||
const contextualType = checker.getContextualType(containingObjectLiteralElement.parent);
|
||||
const res = contextualType && firstDefined(
|
||||
getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker, contextualType, /*unionSymbolOk*/ true),
|
||||
sym => fromRoot(sym, EntryKind.SearchedPropertyFoundLocal));
|
||||
if (res) return res;
|
||||
|
||||
// If the location is name of property symbol from object literal destructuring pattern
|
||||
// Search the property symbol
|
||||
// for ( { property: p2 } of elems) { }
|
||||
const propertySymbol = getPropertySymbolOfDestructuringAssignment(location, checker);
|
||||
const res1 = propertySymbol && cbSymbol(propertySymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, EntryKind.SearchedPropertyFoundLocal);
|
||||
if (res1) return res1;
|
||||
|
||||
const res2 = shorthandValueSymbol && cbSymbol(shorthandValueSymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, EntryKind.SearchedLocalFoundProperty);
|
||||
if (res2) return res2;
|
||||
}
|
||||
|
||||
@@ -1494,12 +1531,14 @@ namespace ts.FindAllReferences.Core {
|
||||
return fromRoot(symbol.flags & SymbolFlags.FunctionScopedVariable ? paramProps[1] : paramProps[0]);
|
||||
}
|
||||
|
||||
// If this is symbol of binding element without propertyName declaration in Object binding pattern
|
||||
// Include the property in the search
|
||||
const bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol, checker);
|
||||
return bindingElementPropertySymbol && fromRoot(bindingElementPropertySymbol);
|
||||
// symbolAtLocation for a binding element is the local symbol. See if the search symbol is the property.
|
||||
// Don't do this when populating search set for a rename -- just rename the local.
|
||||
if (!isForRenamePopulateSearchSymbolSet) {
|
||||
const bindingElementPropertySymbol = isObjectBindingElementWithoutPropertyName(location.parent) ? getPropertySymbolFromBindingElement(checker, location.parent) : undefined;
|
||||
return bindingElementPropertySymbol && fromRoot(bindingElementPropertySymbol, EntryKind.SearchedPropertyFoundLocal);
|
||||
}
|
||||
|
||||
function fromRoot(sym: Symbol): T | undefined {
|
||||
function fromRoot(sym: Symbol, kind?: NodeEntryKind): T | undefined {
|
||||
// If this is a union property:
|
||||
// - In populateSearchSymbolsSet we will add all the symbols from all its source symbols in all unioned types.
|
||||
// - In findRelatedSymbol, we will just use the union symbol if any source symbol is included in the search.
|
||||
@@ -1507,20 +1546,24 @@ namespace ts.FindAllReferences.Core {
|
||||
// - In populateSearchSymbolsSet, add the root the list
|
||||
// - In findRelatedSymbol, return the source symbol if that is in the search. (Do not return the instantiation symbol.)
|
||||
return firstDefined(checker.getRootSymbols(sym), rootSymbol =>
|
||||
cbSymbol(sym, rootSymbol)
|
||||
cbSymbol(sym, rootSymbol, /*baseSymbol*/ undefined, kind)
|
||||
// Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions
|
||||
|| (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface) && allowBaseTypes(rootSymbol)
|
||||
? getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, checker, base => cbSymbol(sym, rootSymbol, base))
|
||||
? getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, checker, base => cbSymbol(sym, rootSymbol, base, kind))
|
||||
: undefined));
|
||||
}
|
||||
}
|
||||
|
||||
function getRelatedSymbol(search: Search, referenceSymbol: Symbol, referenceLocation: Node, state: State): Symbol | undefined {
|
||||
interface RelatedSymbol {
|
||||
readonly symbol: Symbol;
|
||||
readonly kind: NodeEntryKind | undefined;
|
||||
}
|
||||
function getRelatedSymbol(search: Search, referenceSymbol: Symbol, referenceLocation: Node, state: State): RelatedSymbol | undefined {
|
||||
const { checker } = state;
|
||||
return forEachRelatedSymbol(referenceSymbol, referenceLocation, checker,
|
||||
(sym, rootSymbol, baseSymbol) => search.includes(baseSymbol || rootSymbol || sym)
|
||||
return forEachRelatedSymbol(referenceSymbol, referenceLocation, checker, /*isForRenamePopulateSearchSymbolSet*/ false,
|
||||
(sym, rootSymbol, baseSymbol, kind): RelatedSymbol | undefined => search.includes(baseSymbol || rootSymbol || sym)
|
||||
// For a base type, use the symbol for the derived type. For a synthetic (e.g. union) property, use the union symbol.
|
||||
? rootSymbol && !(getCheckFlags(sym) & CheckFlags.Synthetic) ? rootSymbol : sym
|
||||
? { symbol: rootSymbol && !(getCheckFlags(sym) & CheckFlags.Synthetic) ? rootSymbol : sym, kind }
|
||||
: undefined,
|
||||
/*allowBaseTypes*/ rootSymbol =>
|
||||
!(search.parents && !search.parents.some(parent => explicitlyInheritsFrom(rootSymbol.parent!, parent, state.inheritsFromCache, checker))));
|
||||
|
||||
@@ -753,17 +753,17 @@ namespace ts.formatting {
|
||||
|
||||
const listEndToken = getCloseTokenForOpenToken(listStartToken);
|
||||
if (listEndToken !== SyntaxKind.Unknown && formattingScanner.isOnToken()) {
|
||||
let tokenInfo = formattingScanner.readTokenInfo(parent);
|
||||
let tokenInfo: TokenInfo | undefined = formattingScanner.readTokenInfo(parent);
|
||||
if (tokenInfo.token.kind === SyntaxKind.CommaToken && isCallLikeExpression(parent)) {
|
||||
formattingScanner.advance();
|
||||
tokenInfo = formattingScanner.readTokenInfo(parent);
|
||||
tokenInfo = formattingScanner.isOnToken() ? formattingScanner.readTokenInfo(parent) : undefined;
|
||||
}
|
||||
|
||||
// consume the list end token only if it is still belong to the parent
|
||||
// there might be the case when current token matches end token but does not considered as one
|
||||
// function (x: function) <--
|
||||
// without this check close paren will be interpreted as list end token for function expression which is wrong
|
||||
if (tokenInfo.token.kind === listEndToken && rangeContainsRange(parent, tokenInfo.token)) {
|
||||
if (tokenInfo && tokenInfo.token.kind === listEndToken && rangeContainsRange(parent, tokenInfo.token)) {
|
||||
// consume list end token
|
||||
consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation, parent);
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace ts {
|
||||
case "compilerOptions":
|
||||
forEachProperty(property.initializer, (property, propertyName) => {
|
||||
const option = getOptionFromName(propertyName);
|
||||
if (option && (option.isFilePath || option.type === "list" && (option as CommandLineOptionOfListType).element.isFilePath)) {
|
||||
if (option && (option.isFilePath || option.type === "list" && option.element.isFilePath)) {
|
||||
updatePaths(property);
|
||||
}
|
||||
else if (propertyName === "paths") {
|
||||
|
||||
@@ -385,7 +385,7 @@ namespace ts.FindAllReferences {
|
||||
}
|
||||
|
||||
/** Iterates over all statements at the top level or in module declarations. Returns the first truthy result. */
|
||||
function forEachPossibleImportOrExportStatement<T>(sourceFileLike: SourceFileLike, action: (statement: Statement) => T): T | undefined {
|
||||
function forEachPossibleImportOrExportStatement<T>(sourceFileLike: SourceFileLike, action: (statement: Statement) => T) {
|
||||
return forEach(sourceFileLike.kind === SyntaxKind.SourceFile ? sourceFileLike.statements : sourceFileLike.body!.statements, statement => // TODO: GH#18217
|
||||
action(statement) || (isAmbientModuleDeclaration(statement) && forEach(statement.body && statement.body.statements, action)));
|
||||
}
|
||||
|
||||
@@ -281,6 +281,9 @@ namespace ts.NavigationBar {
|
||||
case AssignmentDeclarationKind.ThisProperty:
|
||||
case AssignmentDeclarationKind.Property:
|
||||
case AssignmentDeclarationKind.None:
|
||||
case AssignmentDeclarationKind.ObjectDefinePropertyValue:
|
||||
case AssignmentDeclarationKind.ObjectDefinePropertyExports:
|
||||
case AssignmentDeclarationKind.ObjectDefinePrototypeProperty:
|
||||
break;
|
||||
default:
|
||||
Debug.assertNever(special);
|
||||
@@ -631,28 +634,50 @@ namespace ts.NavigationBar {
|
||||
}
|
||||
|
||||
function getFunctionOrClassName(node: FunctionExpression | FunctionDeclaration | ArrowFunction | ClassLikeDeclaration): string {
|
||||
const { parent } = node;
|
||||
if (node.name && getFullWidth(node.name) > 0) {
|
||||
return declarationNameToString(node.name);
|
||||
}
|
||||
// See if it is a var initializer. If so, use the var name.
|
||||
else if (node.parent.kind === SyntaxKind.VariableDeclaration) {
|
||||
return declarationNameToString((node.parent as VariableDeclaration).name);
|
||||
else if (isVariableDeclaration(parent)) {
|
||||
return declarationNameToString(parent.name);
|
||||
}
|
||||
// See if it is of the form "<expr> = function(){...}". If so, use the text from the left-hand side.
|
||||
else if (node.parent.kind === SyntaxKind.BinaryExpression &&
|
||||
(node.parent as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken) {
|
||||
return nodeText((node.parent as BinaryExpression).left).replace(whiteSpaceRegex, "");
|
||||
else if (isBinaryExpression(parent) && parent.operatorToken.kind === SyntaxKind.EqualsToken) {
|
||||
return nodeText(parent.left).replace(whiteSpaceRegex, "");
|
||||
}
|
||||
// See if it is a property assignment, and if so use the property name
|
||||
else if (node.parent.kind === SyntaxKind.PropertyAssignment && (node.parent as PropertyAssignment).name) {
|
||||
return nodeText((node.parent as PropertyAssignment).name);
|
||||
else if (isPropertyAssignment(parent)) {
|
||||
return nodeText(parent.name);
|
||||
}
|
||||
// Default exports are named "default"
|
||||
else if (getModifierFlags(node) & ModifierFlags.Default) {
|
||||
return "default";
|
||||
}
|
||||
else if (isClassLike(node)) {
|
||||
return "<class>";
|
||||
}
|
||||
else if (isCallExpression(parent)) {
|
||||
const name = getCalledExpressionName(parent.expression);
|
||||
if (name !== undefined) {
|
||||
const args = mapDefined(parent.arguments, a => isStringLiteral(a) ? a.getText(curSourceFile) : undefined).join(", ");
|
||||
return `${name}(${args}) callback`;
|
||||
}
|
||||
}
|
||||
return "<function>";
|
||||
}
|
||||
|
||||
function getCalledExpressionName(expr: Expression): string | undefined {
|
||||
if (isIdentifier(expr)) {
|
||||
return expr.text;
|
||||
}
|
||||
else if (isPropertyAccessExpression(expr)) {
|
||||
const left = getCalledExpressionName(expr.expression);
|
||||
const right = expr.name.text;
|
||||
return left === undefined ? right : `${left}.${right}`;
|
||||
}
|
||||
else {
|
||||
return isClassLike(node) ? "<class>" : "<function>";
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -226,7 +226,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
|
||||
const { file, program, cancellationToken } = context;
|
||||
|
||||
const referenceEntries = mapDefined(FindAllReferences.getReferenceEntriesForNode(originalName.parent.pos, originalName, program, [file], cancellationToken!), entry => // TODO: GH#18217
|
||||
(entry.type === "node" && rangeContainsRange(constructor, entry.node) && isIdentifier(entry.node) && isWriteAccess(entry.node)) ? entry.node : undefined);
|
||||
(entry.kind !== FindAllReferences.EntryKind.Span && rangeContainsRange(constructor, entry.node) && isIdentifier(entry.node) && isWriteAccess(entry.node)) ? entry.node : undefined);
|
||||
|
||||
forEach(referenceEntries, entry => {
|
||||
const parent = entry.parent;
|
||||
|
||||
@@ -158,7 +158,7 @@ namespace ts.refactor {
|
||||
|
||||
const shouldMove = (name: Identifier): boolean => {
|
||||
const symbol = isBindingElement(name.parent)
|
||||
? getPropertySymbolFromBindingElement(checker, name.parent as BindingElement & { name: Identifier })
|
||||
? getPropertySymbolFromBindingElement(checker, name.parent as ObjectBindingElementWithoutPropertyName)
|
||||
: skipAlias(checker.getSymbolAtLocation(name)!, checker); // TODO: GH#18217
|
||||
return !!symbol && movedSymbols.has(symbol);
|
||||
};
|
||||
@@ -612,7 +612,7 @@ namespace ts.refactor {
|
||||
| ImportEqualsDeclaration;
|
||||
type TopLevelDeclarationStatement = NonVariableTopLevelDeclaration | VariableStatement;
|
||||
interface TopLevelVariableDeclaration extends VariableDeclaration { parent: VariableDeclarationList & { parent: VariableStatement; }; }
|
||||
type TopLevelDeclaration = NonVariableTopLevelDeclaration | TopLevelVariableDeclaration;
|
||||
type TopLevelDeclaration = NonVariableTopLevelDeclaration | TopLevelVariableDeclaration | BindingElement;
|
||||
function isTopLevelDeclaration(node: Node): node is TopLevelDeclaration {
|
||||
return isNonVariableTopLevelDeclaration(node) && isSourceFile(node.parent) || isVariableDeclaration(node) && isSourceFile(node.parent.parent.parent);
|
||||
}
|
||||
@@ -653,7 +653,7 @@ namespace ts.refactor {
|
||||
return cb(statement as FunctionDeclaration | ClassDeclaration | EnumDeclaration | ModuleDeclaration | TypeAliasDeclaration | InterfaceDeclaration | ImportEqualsDeclaration);
|
||||
|
||||
case SyntaxKind.VariableStatement:
|
||||
return forEach((statement as VariableStatement).declarationList.declarations as ReadonlyArray<TopLevelVariableDeclaration>, cb);
|
||||
return firstDefined((statement as VariableStatement).declarationList.declarations, decl => forEachTopLevelDeclarationInBindingName(decl.name, cb));
|
||||
|
||||
case SyntaxKind.ExpressionStatement: {
|
||||
const { expression } = statement as ExpressionStatement;
|
||||
@@ -663,13 +663,32 @@ namespace ts.refactor {
|
||||
}
|
||||
}
|
||||
}
|
||||
function forEachTopLevelDeclarationInBindingName<T>(name: BindingName, cb: (node: TopLevelDeclaration) => T): T | undefined {
|
||||
switch (name.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return cb(cast(name.parent, (x): x is TopLevelVariableDeclaration | BindingElement => isVariableDeclaration(x) || isBindingElement(x)));
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
return firstDefined(name.elements, em => isOmittedExpression(em) ? undefined : forEachTopLevelDeclarationInBindingName(em.name, cb));
|
||||
default:
|
||||
return Debug.assertNever(name);
|
||||
}
|
||||
}
|
||||
|
||||
function nameOfTopLevelDeclaration(d: TopLevelDeclaration): Identifier | undefined {
|
||||
return d.kind === SyntaxKind.ExpressionStatement ? d.expression.left.name : tryCast(d.name, isIdentifier);
|
||||
return isExpressionStatement(d) ? d.expression.left.name : tryCast(d.name, isIdentifier);
|
||||
}
|
||||
|
||||
function getTopLevelDeclarationStatement(d: TopLevelDeclaration): TopLevelDeclarationStatement {
|
||||
return isVariableDeclaration(d) ? d.parent.parent : d;
|
||||
switch (d.kind) {
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
return d.parent.parent;
|
||||
case SyntaxKind.BindingElement:
|
||||
return getTopLevelDeclarationStatement(
|
||||
cast(d.parent.parent, (p): p is TopLevelVariableDeclaration | BindingElement => isVariableDeclaration(p) || isBindingElement(p)));
|
||||
default:
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
||||
function addExportToChanges(sourceFile: SourceFile, decl: TopLevelDeclarationStatement, changes: textChanges.ChangeTracker, useEs6Exports: boolean): void {
|
||||
|
||||
+11
-15
@@ -39,47 +39,43 @@ namespace ts.Rename {
|
||||
}
|
||||
|
||||
function getRenameInfoForModule(node: StringLiteralLike, sourceFile: SourceFile, moduleSymbol: Symbol): RenameInfo | undefined {
|
||||
if (!isExternalModuleNameRelative(node.text)) {
|
||||
return getRenameInfoError(Diagnostics.You_cannot_rename_a_module_via_a_global_import);
|
||||
}
|
||||
|
||||
const moduleSourceFile = find(moduleSymbol.declarations, isSourceFile);
|
||||
if (!moduleSourceFile) return undefined;
|
||||
const withoutIndex = node.text.endsWith("/index") || node.text.endsWith("/index.js") ? undefined : tryRemoveSuffix(removeFileExtension(moduleSourceFile.fileName), "/index");
|
||||
const name = withoutIndex === undefined ? moduleSourceFile.fileName : withoutIndex;
|
||||
const kind = withoutIndex === undefined ? ScriptElementKind.moduleElement : ScriptElementKind.directory;
|
||||
const indexAfterLastSlash = node.text.lastIndexOf("/") + 1;
|
||||
// Span should only be the last component of the path. + 1 to account for the quote character.
|
||||
const triggerSpan = createTextSpan(node.getStart(sourceFile) + 1 + indexAfterLastSlash, node.text.length - indexAfterLastSlash);
|
||||
return {
|
||||
canRename: true,
|
||||
fileToRename: name,
|
||||
kind,
|
||||
displayName: name,
|
||||
localizedErrorMessage: undefined,
|
||||
fullDisplayName: name,
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
triggerSpan: createTriggerSpanForNode(node, sourceFile),
|
||||
triggerSpan,
|
||||
};
|
||||
}
|
||||
|
||||
function getRenameInfoSuccess(displayName: string, fullDisplayName: string, kind: ScriptElementKind, kindModifiers: string, node: Node, sourceFile: SourceFile): RenameInfo {
|
||||
function getRenameInfoSuccess(displayName: string, fullDisplayName: string, kind: ScriptElementKind, kindModifiers: string, node: Node, sourceFile: SourceFile): RenameInfoSuccess {
|
||||
return {
|
||||
canRename: true,
|
||||
fileToRename: undefined,
|
||||
kind,
|
||||
displayName,
|
||||
localizedErrorMessage: undefined,
|
||||
fullDisplayName,
|
||||
kindModifiers,
|
||||
triggerSpan: createTriggerSpanForNode(node, sourceFile)
|
||||
};
|
||||
}
|
||||
|
||||
function getRenameInfoError(diagnostic: DiagnosticMessage): RenameInfo {
|
||||
// TODO: GH#18217
|
||||
return {
|
||||
canRename: false,
|
||||
localizedErrorMessage: getLocaleSpecificMessage(diagnostic),
|
||||
displayName: undefined!,
|
||||
fullDisplayName: undefined!,
|
||||
kind: undefined!,
|
||||
kindModifiers: undefined!,
|
||||
triggerSpan: undefined!
|
||||
};
|
||||
function getRenameInfoError(diagnostic: DiagnosticMessage): RenameInfoFailure {
|
||||
return { canRename: false, localizedErrorMessage: getLocaleSpecificMessage(diagnostic) };
|
||||
}
|
||||
|
||||
function createTriggerSpanForNode(node: Node, sourceFile: SourceFile) {
|
||||
|
||||
+37
-21
@@ -541,6 +541,7 @@ namespace ts {
|
||||
public fileName: string;
|
||||
public path: Path;
|
||||
public resolvedPath: Path;
|
||||
public originalFileName: string;
|
||||
public text: string;
|
||||
public scriptSnapshot: IScriptSnapshot;
|
||||
public lineMap: ReadonlyArray<number>;
|
||||
@@ -1218,6 +1219,10 @@ namespace ts {
|
||||
getDirectories: path => {
|
||||
return host.getDirectories ? host.getDirectories(path) : [];
|
||||
},
|
||||
readDirectory(path, extensions, exclude, include, depth) {
|
||||
Debug.assertDefined(host.readDirectory, "'LanguageServiceHost.readDirectory' must be implemented to correctly process 'projectReferences'");
|
||||
return host.readDirectory!(path, extensions, exclude, include, depth);
|
||||
},
|
||||
onReleaseOldSourceFile,
|
||||
hasInvalidatedResolution,
|
||||
hasChangedAutomaticTypeDirectiveNames: host.hasChangedAutomaticTypeDirectiveNames
|
||||
@@ -1227,11 +1232,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (host.resolveModuleNames) {
|
||||
compilerHost.resolveModuleNames = (moduleNames, containingFile, reusedNames) => host.resolveModuleNames!(moduleNames, containingFile, reusedNames);
|
||||
compilerHost.resolveModuleNames = (moduleNames, containingFile, reusedNames, redirectedReference) => host.resolveModuleNames!(moduleNames, containingFile, reusedNames, redirectedReference);
|
||||
}
|
||||
if (host.resolveTypeReferenceDirectives) {
|
||||
compilerHost.resolveTypeReferenceDirectives = (typeReferenceDirectiveNames, containingFile) => {
|
||||
return host.resolveTypeReferenceDirectives!(typeReferenceDirectiveNames, containingFile);
|
||||
compilerHost.resolveTypeReferenceDirectives = (typeReferenceDirectiveNames, containingFile, redirectedReference) => {
|
||||
return host.resolveTypeReferenceDirectives!(typeReferenceDirectiveNames, containingFile, redirectedReference);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1271,7 +1276,7 @@ namespace ts {
|
||||
// not part of the new program.
|
||||
function onReleaseOldSourceFile(oldSourceFile: SourceFile, oldOptions: CompilerOptions) {
|
||||
const oldSettingsKey = documentRegistry.getKeyForCompilationSettings(oldOptions);
|
||||
documentRegistry.releaseDocumentWithKey(oldSourceFile.path, oldSettingsKey);
|
||||
documentRegistry.releaseDocumentWithKey(oldSourceFile.resolvedPath, oldSettingsKey);
|
||||
}
|
||||
|
||||
function getOrCreateSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void, shouldCreateNewSourceFile?: boolean): SourceFile | undefined {
|
||||
@@ -1378,7 +1383,7 @@ namespace ts {
|
||||
// Therefore only get diagnostics for given file.
|
||||
|
||||
const semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile, cancellationToken);
|
||||
if (!program.getCompilerOptions().declaration) {
|
||||
if (!getEmitDeclarations(program.getCompilerOptions())) {
|
||||
return semanticDiagnostics.slice();
|
||||
}
|
||||
|
||||
@@ -1539,20 +1544,20 @@ namespace ts {
|
||||
const node = getTouchingPropertyName(sourceFile, position);
|
||||
if (isIdentifier(node) && isJsxOpeningElement(node.parent) || isJsxClosingElement(node.parent)) {
|
||||
const { openingElement, closingElement } = node.parent.parent;
|
||||
return [openingElement, closingElement].map((node): RenameLocation => ({ fileName: sourceFile.fileName, textSpan: createTextSpanFromNode(node.tagName, sourceFile) }));
|
||||
return [openingElement, closingElement].map((node): RenameLocation =>
|
||||
({ fileName: sourceFile.fileName, textSpan: createTextSpanFromNode(node.tagName, sourceFile) }));
|
||||
}
|
||||
else {
|
||||
const refs = getReferences(node, position, { findInStrings, findInComments, isForRename: true });
|
||||
return refs && refs.map(({ fileName, textSpan }): RenameLocation => ({ fileName, textSpan }));
|
||||
return getReferencesWorker(node, position, { findInStrings, findInComments, isForRename: true }, FindAllReferences.toRenameLocation);
|
||||
}
|
||||
}
|
||||
|
||||
function getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[] | undefined {
|
||||
synchronizeHostData();
|
||||
return getReferences(getTouchingPropertyName(getValidSourceFile(fileName), position), position);
|
||||
return getReferencesWorker(getTouchingPropertyName(getValidSourceFile(fileName), position), position, {}, FindAllReferences.toReferenceEntry);
|
||||
}
|
||||
|
||||
function getReferences(node: Node, position: number, options?: FindAllReferences.Options): ReferenceEntry[] | undefined {
|
||||
function getReferencesWorker<T>(node: Node, position: number, options: FindAllReferences.Options, cb: FindAllReferences.ToReferenceOrRenameEntry<T>): T[] | undefined {
|
||||
synchronizeHostData();
|
||||
|
||||
// Exclude default library when renaming as commonly user don't want to change that file.
|
||||
@@ -1560,7 +1565,7 @@ namespace ts {
|
||||
? program.getSourceFiles().filter(sourceFile => !program.isSourceFileDefaultLibrary(sourceFile))
|
||||
: program.getSourceFiles();
|
||||
|
||||
return FindAllReferences.findReferencedEntries(program, cancellationToken, sourceFiles, node, position, options);
|
||||
return FindAllReferences.findReferenceOrRenameEntries(program, cancellationToken, sourceFiles, node, position, options, cb);
|
||||
}
|
||||
|
||||
function findReferences(fileName: string, position: number): ReferencedSymbol[] | undefined {
|
||||
@@ -1804,25 +1809,36 @@ namespace ts {
|
||||
return ts.getEditsForFileRename(getProgram()!, oldFilePath, newFilePath, host, formatting.getFormatContext(formatOptions), preferences, sourceMapper);
|
||||
}
|
||||
|
||||
function applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
function applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
|
||||
function applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
function applyCodeActionCommand(action: CodeActionCommand, formatSettings?: FormatCodeSettings): Promise<ApplyCodeActionCommandResult>;
|
||||
function applyCodeActionCommand(action: CodeActionCommand[], formatSettings?: FormatCodeSettings): Promise<ApplyCodeActionCommandResult[]>;
|
||||
function applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[], formatSettings?: FormatCodeSettings): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
function applyCodeActionCommand(fileName: Path, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
function applyCodeActionCommand(fileName: Path, action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
|
||||
function applyCodeActionCommand(fileName: Path | CodeActionCommand | CodeActionCommand[], actionOrUndefined?: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]> {
|
||||
const action = typeof fileName === "string" ? actionOrUndefined! : fileName as CodeActionCommand[];
|
||||
return isArray(action) ? Promise.all(action.map(applySingleCodeActionCommand)) : applySingleCodeActionCommand(action);
|
||||
function applyCodeActionCommand(fileName: Path | CodeActionCommand | CodeActionCommand[], actionOrFormatSettingsOrUndefined?: CodeActionCommand | CodeActionCommand[] | FormatCodeSettings): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]> {
|
||||
const action = typeof fileName === "string" ? actionOrFormatSettingsOrUndefined as CodeActionCommand | CodeActionCommand[] : fileName as CodeActionCommand[];
|
||||
const formatSettings = typeof fileName !== "string" ? actionOrFormatSettingsOrUndefined as FormatCodeSettings : undefined;
|
||||
return isArray(action) ? Promise.all(action.map(a => applySingleCodeActionCommand(a, formatSettings))) : applySingleCodeActionCommand(action, formatSettings);
|
||||
}
|
||||
|
||||
function applySingleCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult> {
|
||||
function applySingleCodeActionCommand(action: CodeActionCommand, formatSettings: FormatCodeSettings | undefined): Promise<ApplyCodeActionCommandResult> {
|
||||
const getPath = (path: string): Path => toPath(path, currentDirectory, getCanonicalFileName);
|
||||
switch (action.type) {
|
||||
case "install package":
|
||||
return host.installPackage
|
||||
? host.installPackage({ fileName: toPath(action.file, currentDirectory, getCanonicalFileName), packageName: action.packageName })
|
||||
? host.installPackage({ fileName: getPath(action.file), packageName: action.packageName })
|
||||
: Promise.reject("Host does not implement `installPackage`");
|
||||
case "generate types": {
|
||||
const { fileToGenerateTypesFor, outputFileName } = action;
|
||||
if (!host.inspectValue) return Promise.reject("Host does not implement `installPackage`");
|
||||
const valueInfoPromise = host.inspectValue({ fileNameToRequire: fileToGenerateTypesFor });
|
||||
return valueInfoPromise.then(valueInfo => {
|
||||
const fullOut = getPath(outputFileName);
|
||||
host.writeFile!(fullOut, valueInfoToDeclarationFileText(valueInfo, formatSettings || testFormatSettings)); // TODO: GH#18217
|
||||
return { successMessage: `Wrote types to '${fullOut}'` };
|
||||
});
|
||||
}
|
||||
default:
|
||||
return Debug.fail();
|
||||
// TODO: Debug.assertNever(action); will only work if there is more than one type.
|
||||
return Debug.assertNever(action);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,8 @@ namespace ts.SignatureHelp {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const argumentInfo = getContainingArgumentInfo(startingToken, position, sourceFile, typeChecker);
|
||||
const isManuallyInvoked = !!triggerReason && triggerReason.kind === "invoked";
|
||||
const argumentInfo = getContainingArgumentInfo(startingToken, position, sourceFile, typeChecker, isManuallyInvoked);
|
||||
if (!argumentInfo) return undefined;
|
||||
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
@@ -450,8 +451,8 @@ namespace ts.SignatureHelp {
|
||||
return createTextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart);
|
||||
}
|
||||
|
||||
function getContainingArgumentInfo(node: Node, position: number, sourceFile: SourceFile, checker: TypeChecker): ArgumentListInfo | undefined {
|
||||
for (let n = node; !isBlock(n) && !isSourceFile(n); n = n.parent) {
|
||||
function getContainingArgumentInfo(node: Node, position: number, sourceFile: SourceFile, checker: TypeChecker, isManuallyInvoked: boolean): ArgumentListInfo | undefined {
|
||||
for (let n = node; isManuallyInvoked || (!isBlock(n) && !isSourceFile(n)); n = n.parent) {
|
||||
// If the node is not a subspan of its parent, this is a big problem.
|
||||
// There have been crashes that might be caused by this violation.
|
||||
Debug.assert(rangeContainsRange(n.parent, n), "Not a subspan", () => `Child: ${Debug.showSyntaxKind(n)}, parent: ${Debug.showSyntaxKind(n.parent)}`);
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace ts {
|
||||
switch (statement.kind) {
|
||||
case SyntaxKind.VariableStatement:
|
||||
return (statement as VariableStatement).declarationList.declarations.some(decl =>
|
||||
isRequireCall(propertyAccessLeftHandSide(decl.initializer!), /*checkArgumentIsStringLiteralLike*/ true)); // TODO: GH#18217
|
||||
!!decl.initializer && isRequireCall(propertyAccessLeftHandSide(decl.initializer), /*checkArgumentIsStringLiteralLike*/ true));
|
||||
case SyntaxKind.ExpressionStatement: {
|
||||
const { expression } = statement as ExpressionStatement;
|
||||
if (!isBinaryExpression(expression)) return isRequireCall(expression, /*checkArgumentIsStringLiteralLike*/ true);
|
||||
|
||||
+101
-23
@@ -209,10 +209,16 @@ namespace ts.textChanges {
|
||||
|
||||
export type TypeAnnotatable = SignatureDeclaration | VariableDeclaration | ParameterDeclaration | PropertyDeclaration | PropertySignature;
|
||||
|
||||
interface JSDocParameter {
|
||||
declaration: ParameterDeclaration;
|
||||
typeNode: TypeNode;
|
||||
isOptional?: boolean;
|
||||
}
|
||||
|
||||
export class ChangeTracker {
|
||||
private readonly changes: Change[] = [];
|
||||
private readonly newFiles: { readonly oldFile: SourceFile, readonly fileName: string, readonly statements: ReadonlyArray<Statement> }[] = [];
|
||||
private readonly classesWithNodesInsertedAtStart = createMap<ClassDeclaration>(); // Set<ClassDeclaration> implemented as Map<node id, ClassDeclaration>
|
||||
private readonly newFiles: { readonly oldFile: SourceFile | undefined, readonly fileName: string, readonly statements: ReadonlyArray<Statement> }[] = [];
|
||||
private readonly classesWithNodesInsertedAtStart = createMap<{ readonly node: ClassDeclaration | InterfaceDeclaration | ObjectLiteralExpression, readonly sourceFile: SourceFile }>(); // Set<ClassDeclaration> implemented as Map<node id, ClassDeclaration>
|
||||
private readonly deletedNodes: { readonly sourceFile: SourceFile, readonly node: Node | NodeArray<TypeParameterDeclaration> }[] = [];
|
||||
|
||||
public static fromContext(context: TextChangesContext): ChangeTracker {
|
||||
@@ -295,7 +301,7 @@ namespace ts.textChanges {
|
||||
}
|
||||
|
||||
private insertNodesAt(sourceFile: SourceFile, pos: number, newNodes: ReadonlyArray<Node>, options: ReplaceWithMultipleNodesOptions = {}): void {
|
||||
this.changes.push({ kind: ChangeKind.ReplaceWithMultipleNodes, sourceFile, options, nodes: newNodes, range: { pos, end: pos } });
|
||||
this.replaceRangeWithNodes(sourceFile, createRange(pos), newNodes, options);
|
||||
}
|
||||
|
||||
public insertNodeAtTopOfFile(sourceFile: SourceFile, newNode: Statement, blankLineBetween: boolean): void {
|
||||
@@ -312,7 +318,17 @@ namespace ts.textChanges {
|
||||
|
||||
public insertModifierBefore(sourceFile: SourceFile, modifier: SyntaxKind, before: Node): void {
|
||||
const pos = before.getStart(sourceFile);
|
||||
this.replaceRange(sourceFile, { pos, end: pos }, createToken(modifier), { suffix: " " });
|
||||
this.insertNodeAt(sourceFile, pos, createToken(modifier), { suffix: " " });
|
||||
}
|
||||
|
||||
public insertLastModifierBefore(sourceFile: SourceFile, modifier: SyntaxKind, before: Node): void {
|
||||
if (!before.modifiers) {
|
||||
this.insertModifierBefore(sourceFile, modifier, before);
|
||||
return;
|
||||
}
|
||||
|
||||
const pos = before.modifiers.end;
|
||||
this.insertNodeAt(sourceFile, pos, createToken(modifier), { prefix: " " });
|
||||
}
|
||||
|
||||
public insertCommentBeforeLine(sourceFile: SourceFile, lineNumber: number, position: number, commentText: string): void {
|
||||
@@ -329,6 +345,12 @@ namespace ts.textChanges {
|
||||
this.insertText(sourceFile, token.getStart(sourceFile), text);
|
||||
}
|
||||
|
||||
public insertCommentThenNewline(sourceFile: SourceFile, character: number, position: number, commentText: string): void {
|
||||
const token = getTouchingToken(sourceFile, position);
|
||||
const text = "/**" + commentText + "*/" + this.newLineCharacter + repeatString(" ", character);
|
||||
this.insertText(sourceFile, token.getStart(sourceFile), text);
|
||||
}
|
||||
|
||||
public replaceRangeWithText(sourceFile: SourceFile, range: TextRange, text: string) {
|
||||
this.changes.push({ kind: ChangeKind.Text, sourceFile, range, text });
|
||||
}
|
||||
@@ -337,6 +359,23 @@ namespace ts.textChanges {
|
||||
this.replaceRangeWithText(sourceFile, createRange(pos), text);
|
||||
}
|
||||
|
||||
public tryInsertJSDocParameters(sourceFile: SourceFile, parameters: JSDocParameter[]) {
|
||||
if (parameters.length === 0) {
|
||||
return;
|
||||
}
|
||||
const parent = parameters[0].declaration.parent;
|
||||
const indent = getLineAndCharacterOfPosition(sourceFile, parent.getStart()).character;
|
||||
let commentText = "\n";
|
||||
for (const { declaration, typeNode, isOptional } of parameters) {
|
||||
if (isIdentifier(declaration.name)) {
|
||||
const printed = changesToText.getNonformattedText(typeNode, sourceFile, this.newLineCharacter).text;
|
||||
commentText += this.printJSDocParameter(indent, printed, declaration.name, isOptional);
|
||||
}
|
||||
}
|
||||
commentText += repeatString(" ", indent + 1);
|
||||
this.insertCommentThenNewline(sourceFile, indent, parent.getStart(), commentText);
|
||||
}
|
||||
|
||||
/** Prefer this over replacing a node with another that has a type annotation, as it avoids reformatting the other parts of the node. */
|
||||
public tryInsertTypeAnnotation(sourceFile: SourceFile, node: TypeAnnotatable, type: TypeNode): void {
|
||||
let endNode: Node | undefined;
|
||||
@@ -355,6 +394,27 @@ namespace ts.textChanges {
|
||||
this.insertNodeAt(sourceFile, endNode.end, type, { prefix: ": " });
|
||||
}
|
||||
|
||||
public tryInsertJSDocType(sourceFile: SourceFile, node: Node, type: TypeNode): void {
|
||||
const printed = changesToText.getNonformattedText(type, sourceFile, this.newLineCharacter).text;
|
||||
let commentText;
|
||||
if (isGetAccessorDeclaration(node)) {
|
||||
commentText = ` @return {${printed}} `;
|
||||
}
|
||||
else {
|
||||
commentText = ` @type {${printed}} `;
|
||||
node = node.parent;
|
||||
}
|
||||
this.insertCommentThenNewline(sourceFile, getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)).character, node.getStart(sourceFile), commentText);
|
||||
}
|
||||
|
||||
private printJSDocParameter(indent: number, printed: string, name: Identifier, isOptionalParameter: boolean | undefined) {
|
||||
let printName = unescapeLeadingUnderscores(name.escapedText);
|
||||
if (isOptionalParameter) {
|
||||
printName = `[${printName}]`;
|
||||
}
|
||||
return repeatString(" ", indent) + ` * @param {${printed}} ${printName}\n`;
|
||||
}
|
||||
|
||||
public insertTypeParameters(sourceFile: SourceFile, node: SignatureDeclaration, typeParameters: ReadonlyArray<TypeParameterDeclaration>): void {
|
||||
// If no `(`, is an arrow function `x => x`, so use the pos of the first parameter
|
||||
const start = (findChildOfKind(node, SyntaxKind.OpenParenToken, sourceFile) || first(node.parameters)).getStart(sourceFile);
|
||||
@@ -403,32 +463,40 @@ namespace ts.textChanges {
|
||||
|
||||
public insertNodeAtEndOfScope(sourceFile: SourceFile, scope: Node, newNode: Node): void {
|
||||
const pos = getAdjustedStartPosition(sourceFile, scope.getLastToken()!, {}, Position.Start);
|
||||
this.replaceRange(sourceFile, { pos, end: pos }, newNode, {
|
||||
this.insertNodeAt(sourceFile, pos, newNode, {
|
||||
prefix: isLineBreak(sourceFile.text.charCodeAt(scope.getLastToken()!.pos)) ? this.newLineCharacter : this.newLineCharacter + this.newLineCharacter,
|
||||
suffix: this.newLineCharacter
|
||||
});
|
||||
}
|
||||
|
||||
public insertNodeAtClassStart(sourceFile: SourceFile, cls: ClassLikeDeclaration | InterfaceDeclaration, newElement: ClassElement): void {
|
||||
this.insertNodeAtStartWorker(sourceFile, cls, newElement);
|
||||
}
|
||||
public insertNodeAtObjectStart(sourceFile: SourceFile, obj: ObjectLiteralExpression, newElement: ObjectLiteralElementLike): void {
|
||||
this.insertNodeAtStartWorker(sourceFile, obj, newElement);
|
||||
}
|
||||
|
||||
private insertNodeAtStartWorker(sourceFile: SourceFile, cls: ClassLikeDeclaration | InterfaceDeclaration | ObjectLiteralExpression, newElement: ClassElement | ObjectLiteralElementLike): void {
|
||||
const clsStart = cls.getStart(sourceFile);
|
||||
const indentation = formatting.SmartIndenter.findFirstNonWhitespaceColumn(getLineStartPositionForPosition(clsStart, sourceFile), clsStart, sourceFile, this.formatContext.options)
|
||||
+ this.formatContext.options.indentSize!;
|
||||
this.insertNodeAt(sourceFile, cls.members.pos, newElement, { indentation, ...this.getInsertNodeAtClassStartPrefixSuffix(sourceFile, cls) });
|
||||
this.insertNodeAt(sourceFile, getMembersOrProperties(cls).pos, newElement, { indentation, ...this.getInsertNodeAtStartPrefixSuffix(sourceFile, cls) });
|
||||
}
|
||||
|
||||
private getInsertNodeAtClassStartPrefixSuffix(sourceFile: SourceFile, cls: ClassLikeDeclaration | InterfaceDeclaration): { prefix: string, suffix: string } {
|
||||
if (cls.members.length === 0) {
|
||||
if (addToSeen(this.classesWithNodesInsertedAtStart, getNodeId(cls), cls)) {
|
||||
private getInsertNodeAtStartPrefixSuffix(sourceFile: SourceFile, cls: ClassLikeDeclaration | InterfaceDeclaration | ObjectLiteralExpression): { prefix: string, suffix: string } {
|
||||
const comma = isObjectLiteralExpression(cls) ? "," : "";
|
||||
if (getMembersOrProperties(cls).length === 0) {
|
||||
if (addToSeen(this.classesWithNodesInsertedAtStart, getNodeId(cls), { node: cls, sourceFile })) {
|
||||
// For `class C {\n}`, don't add the trailing "\n"
|
||||
const shouldSuffix = (positionsAreOnSameLine as any)(...getClassBraceEnds(cls, sourceFile), sourceFile); // TODO: GH#4130 remove 'as any'
|
||||
return { prefix: this.newLineCharacter, suffix: shouldSuffix ? this.newLineCharacter : "" };
|
||||
const shouldSuffix = (positionsAreOnSameLine as any)(...getClassOrObjectBraceEnds(cls, sourceFile), sourceFile); // TODO: GH#4130 remove 'as any'
|
||||
return { prefix: this.newLineCharacter, suffix: comma + (shouldSuffix ? this.newLineCharacter : "") };
|
||||
}
|
||||
else {
|
||||
return { prefix: "", suffix: this.newLineCharacter };
|
||||
return { prefix: "", suffix: comma + this.newLineCharacter };
|
||||
}
|
||||
}
|
||||
else {
|
||||
return { prefix: this.newLineCharacter, suffix: "" };
|
||||
return { prefix: this.newLineCharacter, suffix: comma };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -647,9 +715,8 @@ namespace ts.textChanges {
|
||||
}
|
||||
|
||||
private finishClassesWithNodesInsertedAtStart(): void {
|
||||
this.classesWithNodesInsertedAtStart.forEach(cls => {
|
||||
const sourceFile = cls.getSourceFile();
|
||||
const [openBraceEnd, closeBraceEnd] = getClassBraceEnds(cls, sourceFile);
|
||||
this.classesWithNodesInsertedAtStart.forEach(({ node, sourceFile }) => {
|
||||
const [openBraceEnd, closeBraceEnd] = getClassOrObjectBraceEnds(node, sourceFile);
|
||||
// For `class C { }` remove the whitespace inside the braces.
|
||||
if (positionsAreOnSameLine(openBraceEnd, closeBraceEnd, sourceFile) && openBraceEnd !== closeBraceEnd - 1) {
|
||||
this.deleteRange(sourceFile, createRange(openBraceEnd, closeBraceEnd - 1));
|
||||
@@ -698,7 +765,7 @@ namespace ts.textChanges {
|
||||
return changes;
|
||||
}
|
||||
|
||||
public createNewFile(oldFile: SourceFile, fileName: string, statements: ReadonlyArray<Statement>) {
|
||||
public createNewFile(oldFile: SourceFile | undefined, fileName: string, statements: ReadonlyArray<Statement>) {
|
||||
this.newFiles.push({ oldFile, fileName, statements });
|
||||
}
|
||||
}
|
||||
@@ -708,12 +775,19 @@ namespace ts.textChanges {
|
||||
return skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, node, {}, Position.FullStart), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
|
||||
}
|
||||
|
||||
function getClassBraceEnds(cls: ClassLikeDeclaration | InterfaceDeclaration, sourceFile: SourceFile): [number, number] {
|
||||
function getClassOrObjectBraceEnds(cls: ClassLikeDeclaration | InterfaceDeclaration | ObjectLiteralExpression, sourceFile: SourceFile): [number, number] {
|
||||
return [findChildOfKind(cls, SyntaxKind.OpenBraceToken, sourceFile)!.end, findChildOfKind(cls, SyntaxKind.CloseBraceToken, sourceFile)!.end];
|
||||
}
|
||||
function getMembersOrProperties(cls: ClassLikeDeclaration | InterfaceDeclaration | ObjectLiteralExpression): NodeArray<Node> {
|
||||
return isObjectLiteralExpression(cls) ? cls.properties : cls.members;
|
||||
}
|
||||
|
||||
export type ValidateNonFormattedText = (node: Node, text: string) => void;
|
||||
|
||||
export function getNewFileText(statements: ReadonlyArray<Statement>, scriptKind: ScriptKind, newLineCharacter: string, formatContext: formatting.FormatContext): string {
|
||||
return changesToText.newFileChangesWorker(/*oldFile*/ undefined, scriptKind, statements, newLineCharacter, formatContext);
|
||||
}
|
||||
|
||||
namespace changesToText {
|
||||
export function getTextChangesFromChanges(changes: ReadonlyArray<Change>, newLineCharacter: string, formatContext: formatting.FormatContext, validate: ValidateNonFormattedText | undefined): FileTextChanges[] {
|
||||
return group(changes, c => c.sourceFile.path).map(changesInFile => {
|
||||
@@ -732,13 +806,17 @@ namespace ts.textChanges {
|
||||
});
|
||||
}
|
||||
|
||||
export function newFileChanges(oldFile: SourceFile, fileName: string, statements: ReadonlyArray<Statement>, newLineCharacter: string, formatContext: formatting.FormatContext): FileTextChanges {
|
||||
export function newFileChanges(oldFile: SourceFile | undefined, fileName: string, statements: ReadonlyArray<Statement>, newLineCharacter: string, formatContext: formatting.FormatContext): FileTextChanges {
|
||||
const text = newFileChangesWorker(oldFile, getScriptKindFromFileName(fileName), statements, newLineCharacter, formatContext);
|
||||
return { fileName, textChanges: [createTextChange(createTextSpan(0, 0), text)], isNewFile: true };
|
||||
}
|
||||
|
||||
export function newFileChangesWorker(oldFile: SourceFile | undefined, scriptKind: ScriptKind, statements: ReadonlyArray<Statement>, newLineCharacter: string, formatContext: formatting.FormatContext): string {
|
||||
// TODO: this emits the file, parses it back, then formats it that -- may be a less roundabout way to do this
|
||||
const nonFormattedText = statements.map(s => getNonformattedText(s, oldFile, newLineCharacter).text).join(newLineCharacter);
|
||||
const sourceFile = createSourceFile(fileName, nonFormattedText, ScriptTarget.ESNext, /*setParentNodes*/ true);
|
||||
const sourceFile = createSourceFile("any file name", nonFormattedText, ScriptTarget.ESNext, /*setParentNodes*/ true, scriptKind);
|
||||
const changes = formatting.formatDocument(sourceFile, formatContext);
|
||||
const text = applyChanges(nonFormattedText, changes);
|
||||
return { fileName, textChanges: [createTextChange(createTextSpan(0, 0), text)], isNewFile: true };
|
||||
return applyChanges(nonFormattedText, changes);
|
||||
}
|
||||
|
||||
function computeNewText(change: Change, sourceFile: SourceFile, newLineCharacter: string, formatContext: formatting.FormatContext, validate: ValidateNonFormattedText | undefined): string {
|
||||
@@ -778,7 +856,7 @@ namespace ts.textChanges {
|
||||
}
|
||||
|
||||
/** Note: output node may be mutated input node. */
|
||||
function getNonformattedText(node: Node, sourceFile: SourceFile | undefined, newLineCharacter: string): { text: string, node: Node } {
|
||||
export function getNonformattedText(node: Node, sourceFile: SourceFile | undefined, newLineCharacter: string): { text: string, node: Node } {
|
||||
const writer = new Writer(newLineCharacter);
|
||||
const newLine = newLineCharacter === "\n" ? NewLineKind.LineFeed : NewLineKind.CarriageReturnLineFeed;
|
||||
createPrinter({ newLine, neverAsciiEscape: true }, writer).writeNode(EmitHint.Unspecified, node, sourceFile, writer);
|
||||
|
||||
@@ -48,6 +48,7 @@ namespace ts {
|
||||
options.paths = undefined;
|
||||
options.rootDirs = undefined;
|
||||
options.declaration = undefined;
|
||||
options.composite = undefined;
|
||||
options.declarationDir = undefined;
|
||||
options.out = undefined;
|
||||
options.outFile = undefined;
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
"codefixes/inferFromUsage.ts",
|
||||
"codefixes/fixInvalidImportSyntax.ts",
|
||||
"codefixes/fixStrictClassInitialization.ts",
|
||||
"codefixes/generateTypes.ts",
|
||||
"codefixes/requireInTs.ts",
|
||||
"codefixes/useDefaultImport.ts",
|
||||
"codefixes/fixAddModuleReferTypeMissingTypeof.ts",
|
||||
@@ -82,6 +83,6 @@
|
||||
"services.ts",
|
||||
"breakpoints.ts",
|
||||
"transform.ts",
|
||||
"shims.ts"
|
||||
"shims.ts",
|
||||
]
|
||||
}
|
||||
|
||||
+55
-12
@@ -212,9 +212,9 @@ namespace ts {
|
||||
*
|
||||
* If this is implemented, `getResolvedModuleWithFailedLookupLocationsFromCache` should be too.
|
||||
*/
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[];
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[], redirectedReference?: ResolvedProjectReference): ResolvedModule[];
|
||||
getResolvedModuleWithFailedLookupLocationsFromCache?(modulename: string, containingFile: string): ResolvedModuleWithFailedLookupLocations | undefined;
|
||||
resolveTypeReferenceDirectives?(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
resolveTypeReferenceDirectives?(typeDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): ResolvedTypeReferenceDirective[];
|
||||
/* @internal */ hasInvalidatedResolution?: HasInvalidatedResolution;
|
||||
/* @internal */ hasChangedAutomaticTypeDirectiveNames?: boolean;
|
||||
|
||||
@@ -231,6 +231,8 @@ namespace ts {
|
||||
|
||||
isKnownTypesPackageName?(name: string): boolean;
|
||||
installPackage?(options: InstallPackageOptions): Promise<ApplyCodeActionCommandResult>;
|
||||
/* @internal */ inspectValue?(options: InspectValueOptions): Promise<ValueInfo>;
|
||||
writeFile?(fileName: string, content: string): void;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -331,9 +333,9 @@ namespace ts {
|
||||
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray<number>, formatOptions: FormatCodeSettings, preferences: UserPreferences): ReadonlyArray<CodeFixAction>;
|
||||
getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: {}, formatOptions: FormatCodeSettings, preferences: UserPreferences): CombinedCodeActions;
|
||||
applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
|
||||
applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
applyCodeActionCommand(action: CodeActionCommand, formatSettings?: FormatCodeSettings): Promise<ApplyCodeActionCommandResult>;
|
||||
applyCodeActionCommand(action: CodeActionCommand[], formatSettings?: FormatCodeSettings): Promise<ApplyCodeActionCommandResult[]>;
|
||||
applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[], formatSettings?: FormatCodeSettings): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
/** @deprecated `fileName` will be ignored */
|
||||
applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
/** @deprecated `fileName` will be ignored */
|
||||
@@ -526,12 +528,22 @@ namespace ts {
|
||||
|
||||
// Publicly, this type is just `{}`. Internally it is a union of all the actions we use.
|
||||
// See `commands?: {}[]` in protocol.ts
|
||||
export type CodeActionCommand = InstallPackageAction;
|
||||
export type CodeActionCommand = InstallPackageAction | GenerateTypesAction;
|
||||
|
||||
export interface InstallPackageAction {
|
||||
/* @internal */ file: string;
|
||||
/* @internal */ type: "install package";
|
||||
/* @internal */ packageName: string;
|
||||
/* @internal */ readonly type: "install package";
|
||||
/* @internal */ readonly file: string;
|
||||
/* @internal */ readonly packageName: string;
|
||||
}
|
||||
|
||||
export interface GenerateTypesAction extends GenerateTypesOptions {
|
||||
/* @internal */ readonly type: "generate types";
|
||||
}
|
||||
|
||||
export interface GenerateTypesOptions {
|
||||
readonly file: string; // File that was importing fileToGenerateTypesFor; used for formatting options.
|
||||
readonly fileToGenerateTypesFor: string;
|
||||
readonly outputFileName: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -607,6 +619,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
export interface RenameLocation extends DocumentSpan {
|
||||
readonly prefixText?: string;
|
||||
readonly suffixText?: string;
|
||||
}
|
||||
|
||||
export interface ReferenceEntry extends DocumentSpan {
|
||||
@@ -717,6 +731,31 @@ namespace ts {
|
||||
indentMultiLineObjectLiteralBeginningOnBlankLine?: boolean;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export const testFormatSettings: FormatCodeSettings = {
|
||||
baseIndentSize: 0,
|
||||
indentSize: 4,
|
||||
tabSize: 4,
|
||||
newLineCharacter: "\n",
|
||||
convertTabsToSpaces: true,
|
||||
indentStyle: IndentStyle.Smart,
|
||||
insertSpaceAfterCommaDelimiter: true,
|
||||
insertSpaceAfterSemicolonInForStatements: true,
|
||||
insertSpaceBeforeAndAfterBinaryOperators: true,
|
||||
insertSpaceAfterConstructor: false,
|
||||
insertSpaceAfterKeywordsInControlFlowStatements: true,
|
||||
insertSpaceAfterFunctionKeywordForAnonymousFunctions: false,
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true,
|
||||
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false,
|
||||
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false,
|
||||
insertSpaceAfterTypeAssertion: false,
|
||||
placeOpenBraceOnNewLineForFunctions: false,
|
||||
placeOpenBraceOnNewLineForControlBlocks: false,
|
||||
insertSpaceBeforeTypeAnnotation: false
|
||||
};
|
||||
|
||||
export interface DefinitionInfo extends DocumentSpan {
|
||||
kind: ScriptElementKind;
|
||||
name: string;
|
||||
@@ -782,20 +821,24 @@ namespace ts {
|
||||
tags?: JSDocTagInfo[];
|
||||
}
|
||||
|
||||
export interface RenameInfo {
|
||||
canRename: boolean;
|
||||
export type RenameInfo = RenameInfoSuccess | RenameInfoFailure;
|
||||
export interface RenameInfoSuccess {
|
||||
canRename: true;
|
||||
/**
|
||||
* File or directory to rename.
|
||||
* If set, `getEditsForFileRename` should be called instead of `findRenameLocations`.
|
||||
*/
|
||||
fileToRename?: string;
|
||||
localizedErrorMessage?: string;
|
||||
displayName: string;
|
||||
fullDisplayName: string;
|
||||
kind: ScriptElementKind;
|
||||
kindModifiers: string;
|
||||
triggerSpan: TextSpan;
|
||||
}
|
||||
export interface RenameInfoFailure {
|
||||
canRename: false;
|
||||
localizedErrorMessage: string;
|
||||
}
|
||||
|
||||
export interface SignatureHelpParameter {
|
||||
name: string;
|
||||
|
||||
@@ -368,6 +368,9 @@ namespace ts {
|
||||
const kind = getAssignmentDeclarationKind(node as BinaryExpression);
|
||||
const { right } = node as BinaryExpression;
|
||||
switch (kind) {
|
||||
case AssignmentDeclarationKind.ObjectDefinePropertyValue:
|
||||
case AssignmentDeclarationKind.ObjectDefinePropertyExports:
|
||||
case AssignmentDeclarationKind.ObjectDefinePrototypeProperty:
|
||||
case AssignmentDeclarationKind.None:
|
||||
return ScriptElementKind.unknown;
|
||||
case AssignmentDeclarationKind.ExportsProperty:
|
||||
@@ -1325,15 +1328,18 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
export function getPropertySymbolFromBindingElement(checker: TypeChecker, bindingElement: BindingElement & { name: Identifier }) {
|
||||
export type ObjectBindingElementWithoutPropertyName = BindingElement & { name: Identifier };
|
||||
|
||||
export function isObjectBindingElementWithoutPropertyName(bindingElement: Node): bindingElement is ObjectBindingElementWithoutPropertyName {
|
||||
return isBindingElement(bindingElement) &&
|
||||
isObjectBindingPattern(bindingElement.parent) &&
|
||||
isIdentifier(bindingElement.name) &&
|
||||
!bindingElement.propertyName;
|
||||
}
|
||||
|
||||
export function getPropertySymbolFromBindingElement(checker: TypeChecker, bindingElement: ObjectBindingElementWithoutPropertyName): Symbol | undefined {
|
||||
const typeOfPattern = checker.getTypeAtLocation(bindingElement.parent);
|
||||
const propSymbol = typeOfPattern && checker.getPropertyOfType(typeOfPattern, bindingElement.name.text);
|
||||
if (propSymbol && propSymbol.flags & SymbolFlags.Accessor) {
|
||||
// See GH#16922
|
||||
Debug.assert(!!(propSymbol.flags & SymbolFlags.Transient));
|
||||
return (propSymbol as TransientSymbol).target;
|
||||
}
|
||||
return propSymbol;
|
||||
return typeOfPattern && checker.getPropertyOfType(typeOfPattern, bindingElement.name.text);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const del = require("del");
|
||||
const fs: typeof import("fs") = require("fs");
|
||||
const path: typeof import("path") = require("path");
|
||||
const del: typeof import("del") = require("del");
|
||||
|
||||
interface ExecResult {
|
||||
stdout: Buffer;
|
||||
@@ -40,7 +40,7 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
|
||||
const timeout = 600_000; // 10 minutes
|
||||
describe(directoryName, function(this: Mocha.ISuiteCallbackContext) {
|
||||
this.timeout(timeout);
|
||||
const cp = require("child_process");
|
||||
const cp: typeof import("child_process") = require("child_process");
|
||||
|
||||
it("should build successfully", () => {
|
||||
let cwd = path.join(Harness.IO.getWorkspaceRoot(), cls.testDir, directoryName);
|
||||
@@ -49,12 +49,9 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
|
||||
let types: string[] | undefined;
|
||||
if (fs.existsSync(path.join(cwd, "test.json"))) {
|
||||
const submoduleDir = path.join(cwd, directoryName);
|
||||
const reset = cp.spawnSync("git", ["reset", "HEAD", "--hard"], { cwd: submoduleDir, timeout, shell: true, stdio });
|
||||
if (reset.status !== 0) throw new Error(`git reset for ${directoryName} failed: ${reset.stderr.toString()}`);
|
||||
const clean = cp.spawnSync("git", ["clean", "-f"], { cwd: submoduleDir, timeout, shell: true, stdio });
|
||||
if (clean.status !== 0) throw new Error(`git clean for ${directoryName} failed: ${clean.stderr.toString()}`);
|
||||
const update = cp.spawnSync("git", ["submodule", "update", "--remote", "."], { cwd: submoduleDir, timeout, shell: true, stdio });
|
||||
if (update.status !== 0) throw new Error(`git submodule update for ${directoryName} failed: ${update.stderr.toString()}`);
|
||||
exec("git", ["reset", "HEAD", "--hard"], { cwd: submoduleDir });
|
||||
exec("git", ["clean", "-f"], { cwd: submoduleDir });
|
||||
exec("git", ["submodule", "update", "--init", "--remote", "."], { cwd: submoduleDir });
|
||||
|
||||
const config = JSON.parse(fs.readFileSync(path.join(cwd, "test.json"), { encoding: "utf8" })) as UserConfig;
|
||||
ts.Debug.assert(!!config.types, "Bad format from test.json: Types field must be present.");
|
||||
@@ -69,18 +66,23 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
|
||||
if (fs.existsSync(path.join(cwd, "node_modules"))) {
|
||||
del.sync(path.join(cwd, "node_modules"), { force: true });
|
||||
}
|
||||
const install = cp.spawnSync(`npm`, ["i", "--ignore-scripts"], { cwd, timeout: timeout / 2, shell: true, stdio }); // NPM shouldn't take the entire timeout - if it takes a long time, it should be terminated and we should log the failure
|
||||
if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed: ${install.stderr.toString()}`);
|
||||
exec("npm", ["i", "--ignore-scripts"], { cwd, timeout: timeout / 2 }); // NPM shouldn't take the entire timeout - if it takes a long time, it should be terminated and we should log the failure
|
||||
}
|
||||
const args = [path.join(Harness.IO.getWorkspaceRoot(), "built/local/tsc.js")];
|
||||
if (types) {
|
||||
args.push("--types", types.join(","));
|
||||
// Also actually install those types (for, eg, the js projects which need node)
|
||||
const install = cp.spawnSync(`npm`, ["i", ...types.map(t => `@types/${t}`), "--no-save", "--ignore-scripts"], { cwd: originalCwd, timeout: timeout / 2, shell: true, stdio }); // NPM shouldn't take the entire timeout - if it takes a long time, it should be terminated and we should log the failure
|
||||
if (install.status !== 0) throw new Error(`NPM Install types for ${directoryName} failed: ${install.stderr.toString()}`);
|
||||
exec("npm", ["i", ...types.map(t => `@types/${t}`), "--no-save", "--ignore-scripts"], { cwd: originalCwd, timeout: timeout / 2 }); // NPM shouldn't take the entire timeout - if it takes a long time, it should be terminated and we should log the failure
|
||||
}
|
||||
args.push("--noEmit");
|
||||
Harness.Baseline.runBaseline(`${cls.kind()}/${directoryName}.log`, cls.report(cp.spawnSync(`node`, args, { cwd, timeout, shell: true }), cwd));
|
||||
|
||||
function exec(command: string, args: string[], options: { cwd: string, timeout?: number }): void {
|
||||
const res = cp.spawnSync(command, args, { timeout, shell: true, stdio, ...options });
|
||||
if (res.status !== 0) {
|
||||
throw new Error(`${command} ${args.join(" ")} for ${directoryName} failed: ${res.stderr && res.stderr.toString()}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -138,7 +138,6 @@ function handleTestConfig() {
|
||||
case "compiler":
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Regressions));
|
||||
runners.push(new project.ProjectRunner());
|
||||
break;
|
||||
case "conformance":
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace ts.projectSystem {
|
||||
typingsInstaller: typingsInstaller || server.nullTypingsInstaller,
|
||||
byteLength: Utils.byteLength,
|
||||
hrtime: process.hrtime,
|
||||
logger: nullLogger,
|
||||
logger: createHasErrorMessageLogger().logger,
|
||||
canUseEvents: false
|
||||
};
|
||||
return new server.Session(opts);
|
||||
|
||||
@@ -96,6 +96,11 @@ namespace ts {
|
||||
include: null,
|
||||
files: ["../main.ts"]
|
||||
}),
|
||||
"dev/configs/fifth.json": JSON.stringify({
|
||||
extends: "./fourth",
|
||||
include: ["../tests/utils.ts"],
|
||||
files: []
|
||||
}),
|
||||
"dev/extends.json": JSON.stringify({ extends: 42 }),
|
||||
"dev/extends2.json": JSON.stringify({ extends: "configs/base" }),
|
||||
"dev/main.ts": "",
|
||||
@@ -244,6 +249,29 @@ namespace ts {
|
||||
}, [
|
||||
combinePaths(basePath, "main.ts")
|
||||
]);
|
||||
|
||||
testSuccess("can overwrite top-level files using extended []", "configs/fifth.json", {
|
||||
allowJs: true,
|
||||
noImplicitAny: true,
|
||||
strictNullChecks: true,
|
||||
module: ModuleKind.System
|
||||
}, [
|
||||
combinePaths(basePath, "tests/utils.ts")
|
||||
]);
|
||||
|
||||
it("adds extendedSourceFiles only once", () => {
|
||||
const sourceFile = readJsonConfigFile("configs/fourth.json", (path) => host.readFile(path));
|
||||
const dir = combinePaths(basePath, "configs");
|
||||
const expected = [
|
||||
combinePaths(dir, "third.json"),
|
||||
combinePaths(dir, "second.json"),
|
||||
combinePaths(dir, "base.json"),
|
||||
];
|
||||
parseJsonSourceFileConfigFileContent(sourceFile, host, dir, {}, "fourth.json");
|
||||
assert.deepEqual(sourceFile.extendedSourceFiles, expected);
|
||||
parseJsonSourceFileConfigFileContent(sourceFile, host, dir, {}, "fourth.json");
|
||||
assert.deepEqual(sourceFile.extendedSourceFiles, expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,33 +1,50 @@
|
||||
namespace ts {
|
||||
describe("convertCompilerOptionsFromJson", () => {
|
||||
function assertCompilerOptions(json: any, configFileName: string, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) {
|
||||
const formatDiagnosticHost: FormatDiagnosticsHost = {
|
||||
getCurrentDirectory: () => "/apath/",
|
||||
getCanonicalFileName: createGetCanonicalFileName(/*useCaseSensitiveFileNames*/ true),
|
||||
getNewLine: () => "\n"
|
||||
};
|
||||
|
||||
interface ExpectedResultWithParsingSuccess {
|
||||
compilerOptions: CompilerOptions;
|
||||
errors: ReadonlyArray<Diagnostic>;
|
||||
}
|
||||
|
||||
interface ExpectedResultWithParsingFailure {
|
||||
compilerOptions: CompilerOptions;
|
||||
hasParseErrors: true;
|
||||
}
|
||||
|
||||
type ExpectedResult = ExpectedResultWithParsingSuccess | ExpectedResultWithParsingFailure;
|
||||
|
||||
function isExpectedResultWithParsingFailure(expectedResult: ExpectedResult): expectedResult is ExpectedResultWithParsingFailure {
|
||||
return !!(expectedResult as ExpectedResultWithParsingFailure).hasParseErrors;
|
||||
}
|
||||
|
||||
function assertCompilerOptions(json: any, configFileName: string, expectedResult: ExpectedResultWithParsingSuccess) {
|
||||
assertCompilerOptionsWithJson(json, configFileName, expectedResult);
|
||||
assertCompilerOptionsWithJsonNode(json, configFileName, expectedResult);
|
||||
}
|
||||
|
||||
function assertCompilerOptionsWithJson(json: any, configFileName: string, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) {
|
||||
const { options: actualCompilerOptions, errors: actualErrors} = convertCompilerOptionsFromJson(json.compilerOptions, "/apath/", configFileName);
|
||||
function assertCompilerOptionsWithJson(json: any, configFileName: string, expectedResult: ExpectedResultWithParsingSuccess) {
|
||||
const { options: actualCompilerOptions, errors: actualErrors } = convertCompilerOptionsFromJson(json.compilerOptions, "/apath/", configFileName);
|
||||
|
||||
const parsedCompilerOptions = JSON.stringify(actualCompilerOptions);
|
||||
const expectedCompilerOptions = JSON.stringify({ ...expectedResult.compilerOptions, configFilePath: configFileName });
|
||||
assert.equal(parsedCompilerOptions, expectedCompilerOptions);
|
||||
|
||||
const expectedErrors = expectedResult.errors;
|
||||
assert.isTrue(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`);
|
||||
for (let i = 0; i < actualErrors.length; i++) {
|
||||
const actualError = actualErrors[i];
|
||||
const expectedError = expectedErrors[i];
|
||||
assert.equal(actualError.code, expectedError.code);
|
||||
assert.equal(actualError.category, expectedError.category);
|
||||
assert.equal(actualError.messageText, expectedError.messageText);
|
||||
}
|
||||
verifyErrors(actualErrors, expectedResult.errors, /*ignoreLocation*/ true);
|
||||
}
|
||||
|
||||
function assertCompilerOptionsWithJsonNode(json: any, configFileName: string, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) {
|
||||
const fileText = JSON.stringify(json);
|
||||
function assertCompilerOptionsWithJsonNode(json: any, configFileName: string, expectedResult: ExpectedResultWithParsingSuccess) {
|
||||
assertCompilerOptionsWithJsonText(JSON.stringify(json), configFileName, expectedResult);
|
||||
}
|
||||
|
||||
function assertCompilerOptionsWithJsonText(fileText: string, configFileName: string, expectedResult: ExpectedResult) {
|
||||
const result = parseJsonText(configFileName, fileText);
|
||||
assert(!result.parseDiagnostics.length);
|
||||
assert(!!result.endOfFileToken);
|
||||
assert.equal(!!result.parseDiagnostics.length, isExpectedResultWithParsingFailure(expectedResult));
|
||||
const host: ParseConfigHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: "/apath/" }));
|
||||
const { options: actualCompilerOptions, errors: actualParseErrors } = parseJsonSourceFileConfigFileContent(result, host, "/apath/", /*existingOptions*/ undefined, configFileName);
|
||||
expectedResult.compilerOptions.configFilePath = configFileName;
|
||||
@@ -37,17 +54,32 @@ namespace ts {
|
||||
assert.equal(parsedCompilerOptions, expectedCompilerOptions);
|
||||
assert.equal(actualCompilerOptions.configFile, result);
|
||||
|
||||
const actualErrors = filter(actualParseErrors, error => error.code !== Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code);
|
||||
const expectedErrors = expectedResult.errors;
|
||||
assert.isTrue(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`);
|
||||
if (!isExpectedResultWithParsingFailure(expectedResult)) {
|
||||
verifyErrors(actualParseErrors.filter(error => error.code !== Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code), expectedResult.errors);
|
||||
}
|
||||
}
|
||||
|
||||
function verifyErrors(actualErrors: Diagnostic[], expectedErrors: ReadonlyArray<Diagnostic>, ignoreLocation?: boolean) {
|
||||
assert.isTrue(expectedErrors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedErrors.map(getDiagnosticString), undefined, " ")}. Actual error: ${JSON.stringify(actualErrors.map(getDiagnosticString), undefined, " ")}.`);
|
||||
for (let i = 0; i < actualErrors.length; i++) {
|
||||
const actualError = actualErrors[i];
|
||||
const expectedError = expectedErrors[i];
|
||||
|
||||
assert.equal(actualError.code, expectedError.code, `Expected error-code: ${JSON.stringify(expectedError.code)}. Actual error-code: ${JSON.stringify(actualError.code)}.`);
|
||||
assert.equal(actualError.category, expectedError.category, `Expected error-category: ${JSON.stringify(expectedError.category)}. Actual error-category: ${JSON.stringify(actualError.category)}.`);
|
||||
assert(actualError.file);
|
||||
assert(actualError.start);
|
||||
assert(actualError.length);
|
||||
if (!ignoreLocation) {
|
||||
assert(actualError.file);
|
||||
assert(actualError.start);
|
||||
assert(actualError.length);
|
||||
}
|
||||
}
|
||||
|
||||
function getDiagnosticString(diagnostic: Diagnostic) {
|
||||
if (ignoreLocation) {
|
||||
const { file, ...rest } = diagnostic;
|
||||
diagnostic = { file: undefined, ...rest };
|
||||
}
|
||||
return formatDiagnostic(diagnostic, formatDiagnosticHost);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -539,5 +571,36 @@ namespace ts {
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it("Convert tsconfig options when there are multiple invalid strings", () => {
|
||||
assertCompilerOptionsWithJsonText(`{
|
||||
"compilerOptions": {
|
||||
"target": "<%- options.useTsWithBabel ? 'esnext' : 'es5' %>",
|
||||
"module": "esnext",
|
||||
<%_ if (options.classComponent) { _%>
|
||||
"experimentalDecorators": true,
|
||||
<%_ } _%>
|
||||
"sourceMap": true,
|
||||
"types": [
|
||||
"webpack-env"<% if (hasMocha || hasJest) { %>,<% } %>
|
||||
<%_ if (hasMocha) { _%>
|
||||
"mocha",
|
||||
"chai"
|
||||
<%_ } else if (hasJest) { _%>
|
||||
"jest"
|
||||
<%_ } _%>
|
||||
]
|
||||
}
|
||||
}
|
||||
`, "tsconfig.json",
|
||||
{
|
||||
compilerOptions: {
|
||||
target: undefined,
|
||||
module: ModuleKind.ESNext
|
||||
},
|
||||
hasParseErrors: true
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -292,7 +292,7 @@ interface Array<T> {}`
|
||||
cancellationToken: { throwIfCancellationRequested: noop, isCancellationRequested: returnFalse },
|
||||
preferences: emptyOptions,
|
||||
host: notImplementedHost,
|
||||
formatContext: formatting.getFormatContext(testFormatOptions)
|
||||
formatContext: formatting.getFormatContext(testFormatSettings)
|
||||
};
|
||||
|
||||
const diagnostics = languageService.getSuggestionDiagnostics(f.path);
|
||||
@@ -416,6 +416,20 @@ function [#|f|](): Promise<void> {
|
||||
return fetch('https://typescriptlang.org').then( () => console.log("done") );
|
||||
}`
|
||||
);
|
||||
_testConvertToAsyncFunction("convertToAsyncFunction_IgnoreArgs3", `
|
||||
function [#|f|](): Promise<void> {
|
||||
return fetch('https://typescriptlang.org').then( () => console.log("almost done") ).then( () => console.log("done") );
|
||||
}`
|
||||
);
|
||||
_testConvertToAsyncFunction("convertToAsyncFunction_IgnoreArgs4", `
|
||||
function [#|f|]() {
|
||||
return fetch('https://typescriptlang.org').then(res);
|
||||
}
|
||||
function res(){
|
||||
console.log("done");
|
||||
}`
|
||||
);
|
||||
|
||||
_testConvertToAsyncFunction("convertToAsyncFunction_Method", `
|
||||
class Parser {
|
||||
[#|f|]():Promise<void> {
|
||||
@@ -473,6 +487,12 @@ function [#|f|]():Promise<void | Response> {
|
||||
function [#|f|]() {
|
||||
return fetch('https://typescriptlang.org').then(undefined, rejection => console.log("rejected:", rejection));
|
||||
}
|
||||
`
|
||||
);
|
||||
_testConvertToAsyncFunction("convertToAsyncFunction_NoCatchHandler", `
|
||||
function [#|f|]() {
|
||||
return fetch('https://typescriptlang.org').then(x => x.statusText).catch(undefined);
|
||||
}
|
||||
`
|
||||
);
|
||||
_testConvertToAsyncFunctionFailed("convertToAsyncFunction_NoSuggestion", `
|
||||
@@ -817,7 +837,7 @@ function [#|f|]() {
|
||||
);
|
||||
_testConvertToAsyncFunction("convertToAsyncFunction_Scope1", `
|
||||
function [#|f|]() {
|
||||
var var1:Promise<Response>, var2;
|
||||
var var1: Response, var2;
|
||||
return fetch('https://typescriptlang.org').then( _ =>
|
||||
Promise.resolve().then( res => {
|
||||
var2 = "test";
|
||||
@@ -1183,6 +1203,70 @@ function [#|f|]() {
|
||||
}
|
||||
`);
|
||||
|
||||
_testConvertToAsyncFunction("convertToAsyncFunction_runEffectfulContinuation", `
|
||||
function [#|f|]() {
|
||||
return fetch('https://typescriptlang.org').then(res).then(_ => console.log("done"));
|
||||
}
|
||||
function res(result) {
|
||||
return Promise.resolve().then(x => console.log(result));
|
||||
}
|
||||
`);
|
||||
|
||||
_testConvertToAsyncFunction("convertToAsyncFunction_callbackReturnsPromise", `
|
||||
function [#|f|]() {
|
||||
return fetch('https://typescriptlang.org').then(s => Promise.resolve(s.statusText.length)).then(x => console.log(x + 5));
|
||||
}
|
||||
`);
|
||||
|
||||
_testConvertToAsyncFunction("convertToAsyncFunction_callbackReturnsPromiseInBlock", `
|
||||
function [#|f|]() {
|
||||
return fetch('https://typescriptlang.org').then(s => { return Promise.resolve(s.statusText.length) }).then(x => x + 5);
|
||||
}
|
||||
`);
|
||||
|
||||
_testConvertToAsyncFunction("convertToAsyncFunction_callbackReturnsFixablePromise", `
|
||||
function [#|f|]() {
|
||||
return fetch('https://typescriptlang.org').then(s => Promise.resolve(s.statusText).then(st => st.length)).then(x => console.log(x + 5));
|
||||
}
|
||||
`);
|
||||
|
||||
_testConvertToAsyncFunction("convertToAsyncFunction_callbackReturnsPromiseLastInChain", `
|
||||
function [#|f|]() {
|
||||
return fetch('https://typescriptlang.org').then(s => Promise.resolve(s.statusText.length));
|
||||
}
|
||||
`);
|
||||
|
||||
_testConvertToAsyncFunction("convertToAsyncFunction_callbackReturnsRejectedPromiseInTryBlock", `
|
||||
function [#|f|]() {
|
||||
return Promise.resolve(1)
|
||||
.then(x => Promise.reject(x))
|
||||
.catch(err => console.log(err));
|
||||
}
|
||||
`);
|
||||
|
||||
_testConvertToAsyncFunction("convertToAsyncFunction_nestedPromises", `
|
||||
function [#|f|]() {
|
||||
return fetch('https://typescriptlang.org').then(x => Promise.resolve(3).then(y => Promise.resolve(x.statusText.length + y)));
|
||||
}
|
||||
`);
|
||||
_testConvertToAsyncFunction("convertToAsyncFunction_noArgs", `
|
||||
function delay(millis: number): Promise<void> {
|
||||
throw "no"
|
||||
}
|
||||
|
||||
function [#|main2|]() {
|
||||
console.log("Please wait. Loading.");
|
||||
return delay(500)
|
||||
.then(() => { console.log("."); return delay(500); })
|
||||
.then(() => { console.log("."); return delay(500); })
|
||||
.then(() => { console.log("."); return delay(500); })
|
||||
}
|
||||
`);
|
||||
_testConvertToAsyncFunction("convertToAsyncFunction_exportModifier", `
|
||||
export function [#|foo|]() {
|
||||
return fetch('https://typescriptlang.org').then(s => console.log(s));
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
function _testConvertToAsyncFunction(caption: string, text: string) {
|
||||
@@ -1192,4 +1276,4 @@ function [#|f|]() {
|
||||
function _testConvertToAsyncFunctionFailed(caption: string, text: string) {
|
||||
testConvertToAsyncFunction(caption, text, "convertToAsyncFunction", /*includeLib*/ true, /*expectFailure*/ true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user