mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into shebang-comments
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.2.0-dev.201xxxxx
|
||||
**TypeScript Version:** 3.3.0-dev.201xxxxx
|
||||
|
||||
<!-- Search terms you tried before logging this (so others can find this issue more easily) -->
|
||||
**Search Terms:**
|
||||
|
||||
+1
-5
@@ -16,11 +16,7 @@ matrix:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- release-2.7
|
||||
- release-2.8
|
||||
- release-2.9
|
||||
- release-3.0
|
||||
- release-3.1
|
||||
- /^release-.*/
|
||||
|
||||
install:
|
||||
- npm uninstall typescript --no-save
|
||||
|
||||
+14
-7
@@ -82,19 +82,26 @@ Your pull request should:
|
||||
* To avoid line ending issues, set `autocrlf = input` and `whitespace = cr-at-eol` in your git configuration
|
||||
|
||||
## Contributing `lib.d.ts` fixes
|
||||
|
||||
The library sources are in: [src/lib](https://github.com/Microsoft/TypeScript/tree/master/src/lib)
|
||||
|
||||
Library files in `built/local/` are updated by running
|
||||
```Shell
|
||||
There are three relevant locations to be aware of when it comes to TypeScript's library declaration files:
|
||||
|
||||
* `src/lib`: the location of the sources themselves.
|
||||
* `lib`: the location of the last-known-good (LKG) versions of the files which are updated periodically.
|
||||
* `built/local`: the build output location, including where `src/lib` files will be copied to.
|
||||
|
||||
Any changes should be made to [src/lib](https://github.com/Microsoft/TypeScript/tree/master/src/lib). **Most** of these files can be updated by hand, with the exception of any generated files (see below).
|
||||
|
||||
Library files in `built/local/` are updated automatically by running the standard build task:
|
||||
|
||||
```sh
|
||||
jake
|
||||
```
|
||||
|
||||
The files in `lib/` are used to bootstrap compilation and usually do not need to be updated.
|
||||
The files in `lib/` are used to bootstrap compilation and usually **should not** be updated unless publishing a new version or updating the LKG.
|
||||
|
||||
#### `src/lib/dom.generated.d.ts` and `src/lib/webworker.generated.d.ts`
|
||||
### Modifying generated library files
|
||||
|
||||
These two files represent the DOM typings and are auto-generated. To make any modifications to them, please submit a PR to https://github.com/Microsoft/TSJS-lib-generator
|
||||
The files `src/lib/dom.generated.d.ts` and `src/lib/webworker.generated.d.ts` both represent type declarations for the DOM and are auto-generated. To make any modifications to them, you will have to direct changes to https://github.com/Microsoft/TSJS-lib-generator
|
||||
|
||||
## Running the Tests
|
||||
|
||||
|
||||
+2
-1
@@ -117,7 +117,8 @@ const generatedLCGFile = "built/local/enu/diagnosticMessages.generated.json.lcg"
|
||||
* 2. 'src\compiler\diagnosticMessages.generated.json' => 'built\local\ENU\diagnosticMessages.generated.json.lcg'
|
||||
* generate the lcg file (source of messages to localize) from the diagnosticMessages.generated.json
|
||||
*/
|
||||
const localizationTargets = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"]
|
||||
const localizationTargets = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-br", "ru", "tr", "zh-cn", "zh-tw"]
|
||||
.map(f => f.toLowerCase())
|
||||
.map(f => `built/local/${f}/diagnosticMessages.generated.json`)
|
||||
.concat(generatedLCGFile);
|
||||
|
||||
|
||||
-15
@@ -24,8 +24,6 @@ else if (process.env.PATH !== undefined) {
|
||||
|
||||
const host = process.env.TYPESCRIPT_HOST || process.env.host || "node";
|
||||
|
||||
const locales = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"];
|
||||
|
||||
const defaultTestTimeout = 40000;
|
||||
|
||||
let useDebugMode = true;
|
||||
@@ -709,19 +707,6 @@ const Travis = {
|
||||
}
|
||||
};
|
||||
|
||||
function buildLocalizedTargets() {
|
||||
/**
|
||||
* The localization target produces the two following transformations:
|
||||
* 1. 'src\loc\lcl\<locale>\diagnosticMessages.generated.json.lcl' => 'built\local\<locale>\diagnosticMessages.generated.json'
|
||||
* convert localized resources into a .json file the compiler can understand
|
||||
* 2. 'src\compiler\diagnosticMessages.generated.json' => 'built\local\ENU\diagnosticMessages.generated.json.lcg'
|
||||
* generate the lcg file (source of messages to localize) from the diagnosticMessages.generated.json
|
||||
*/
|
||||
const localizationTargets = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-br", "ru", "tr", "zh-cn", "zh-tw"]
|
||||
.map(f => path.join(Paths.builtLocal,f))
|
||||
.concat(path.dirname(Paths.generatedLCGFile));
|
||||
}
|
||||
|
||||
function toNs(diff) {
|
||||
return diff[0] * 1e9 + diff[1];
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ There are many ways to [contribute](https://github.com/Microsoft/TypeScript/blob
|
||||
* [Submit bugs](https://github.com/Microsoft/TypeScript/issues) and help us verify fixes as they are checked in.
|
||||
* Review the [source code changes](https://github.com/Microsoft/TypeScript/pulls).
|
||||
* Engage with other TypeScript users and developers on [StackOverflow](https://stackoverflow.com/questions/tagged/typescript).
|
||||
* Join the [#typescript](https://twitter.com/#!/search/realtime/%23typescript) discussion on Twitter.
|
||||
* Join the [#typescript](https://twitter.com/search?q=%23TypeScript) discussion on Twitter.
|
||||
* [Contribute bug fixes](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md).
|
||||
* Read the language specification ([docx](https://github.com/Microsoft/TypeScript/blob/master/doc/TypeScript%20Language%20Specification.docx?raw=true),
|
||||
[pdf](https://github.com/Microsoft/TypeScript/blob/master/doc/TypeScript%20Language%20Specification.pdf?raw=true), [md](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md)).
|
||||
|
||||
@@ -51,6 +51,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_class_can_only_implement_an_object_type_or_intersection_of_object_types_with_statically_known_memb_2422" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A class can only implement an object type or intersection of object types with statically known members.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_class_declaration_without_the_default_modifier_must_have_a_name_1211" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A class declaration without the 'default' modifier must have a name.]]></Val>
|
||||
@@ -63,12 +69,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_class_may_only_implement_another_class_or_interface_2422" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A class may only implement another class or interface.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_class_member_cannot_have_the_0_keyword_1248" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A class member cannot have the '{0}' keyword.]]></Val>
|
||||
@@ -693,6 +693,18 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Add_missing_new_operator_to_all_calls_95072" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add missing 'new' operator to all calls]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Add_missing_new_operator_to_call_95071" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add missing 'new' operator to call]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Add_missing_super_call_90001" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add missing 'super()' call]]></Val>
|
||||
@@ -705,12 +717,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Add_names_to_all_parameters_without_names_95073" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add names to all parameters without names]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Add_or_remove_braces_in_an_arrow_function_95058" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add or remove braces in an arrow function]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Add_parameter_name_90034" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add parameter name]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add qualifier to all unresolved variables matching a member name]]></Val>
|
||||
@@ -741,6 +765,18 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Add_unknown_conversion_for_non_overlapping_types_95069" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add 'unknown' conversion for non-overlapping types]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Add_unknown_to_all_conversions_of_non_overlapping_types_95070" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add 'unknown' to all conversions of non-overlapping types]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript__5068" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.]]></Val>
|
||||
@@ -873,9 +909,9 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type_2356" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type_2356" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[An arithmetic operand must be of type 'any', 'number' or an enum type.]]></Val>
|
||||
<Val><![CDATA[An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -1065,9 +1101,9 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";An_interface_may_only_extend_a_class_or_another_interface_2312" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";An_interface_can_only_extend_an_object_type_or_intersection_of_object_types_with_statically_known_me_2312" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[An interface may only extend a class or another interface.]]></Val>
|
||||
<Val><![CDATA[An interface can only extend an object type or intersection of object types with statically known members.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -1107,6 +1143,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";An_outer_value_of_this_is_shadowed_by_this_container_2738" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[An outer value of 'this' is shadowed by this container.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";An_overload_signature_cannot_be_declared_as_a_generator_1222" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[An overload signature cannot be declared as a generator.]]></Val>
|
||||
@@ -1191,9 +1233,9 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Base_constructor_return_type_0_is_not_a_class_or_interface_type_2509" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Base_constructor_return_type_0_is_not_an_object_type_or_intersection_of_object_types_with_statically_2509" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Base constructor return type '{0}' is not a class or interface type.]]></Val>
|
||||
<Val><![CDATA[Base constructor return type '{0}' is not an object type or intersection of object types with statically known members.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -1215,6 +1257,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";BigInt_literals_are_not_available_when_targeting_lower_than_ESNext_2737" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[BigInt literals are not available when targeting lower than ESNext.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Binary_digit_expected_1177" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Binary digit expected.]]></Val>
|
||||
@@ -1293,9 +1341,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property_2540" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Cannot_assign_to_0_because_it_is_a_constant_2588" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Cannot assign to '{0}' because it is a constant or a read-only property.]]></Val>
|
||||
<Val><![CDATA[Cannot assign to '{0}' because it is a constant.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Cannot_assign_to_0_because_it_is_a_read_only_property_2540" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Cannot assign to '{0}' because it is a read-only property.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -1433,19 +1487,19 @@
|
||||
</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>
|
||||
<Val><![CDATA[Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_types_Slashjquery_2581" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_types_Slashjquery_an_2581" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i @types/jquery`.]]></Val>
|
||||
<Val><![CDATA[Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i @types/jquery` and then add `jquery` to the types field in your tsconfig.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_types_Slashnode_2580" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_types_Slashnode_and_th_2580" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i @types/node`.]]></Val>
|
||||
<Val><![CDATA[Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -2049,6 +2103,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Did_you_mean_for_0_to_be_constrained_to_type_new_args_Colon_any_1_2735" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Did you mean for '{0}' to be constrained to type 'new (...args: any[]5D;) => {1}'?]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Did_you_mean_to_call_this_expression_6212" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Did you mean to call this expression?]]></Val>
|
||||
@@ -2763,12 +2823,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Found_0_errors_6217" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Found {0} errors.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Found_0_errors_Watching_for_file_changes_6194" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Found {0} errors. Watching for file changes.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Found_1_error_6216" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Found 1 error.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Found_1_error_Watching_for_file_changes_6193" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Found 1 error. Watching for file changes.]]></Val>
|
||||
@@ -2847,6 +2919,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Function_type_which_lacks_return_type_annotation_implicitly_has_an_0_return_type_7014" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Function type, which lacks return-type annotation, implicitly has an '{0}' return type.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Generate_get_and_set_accessors_95046" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Generate 'get' and 'set' accessors]]></Val>
|
||||
@@ -3573,6 +3651,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Member_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage_7045" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Member '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Merge_conflict_marker_encountered_1185" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Merge conflict marker encountered.]]></Val>
|
||||
@@ -3939,6 +4023,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Operator_0_cannot_be_applied_to_type_1_2736" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Operator '{0}' cannot be applied to type '{1}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Operator_0_cannot_be_applied_to_types_1_and_2_2365" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Operator '{0}' cannot be applied to types '{1}' and '{2}'.]]></Val>
|
||||
@@ -4095,6 +4185,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage_7044" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Parameter_0_is_not_in_the_same_position_as_parameter_1_1227" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter '{0}' is not in the same position as parameter '{1}'.]]></Val>
|
||||
@@ -4233,6 +4329,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1_7051" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter has a name but no type. Did you mean '{0}: {1}'?]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2_4036" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter type of public setter '{0}' from exported class has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
@@ -4299,6 +4401,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Print_the_final_configuration_instead_of_building_1350" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Print the final configuration instead of building.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Print_this_message_6017" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Print this message.]]></Val>
|
||||
@@ -4413,6 +4521,18 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Property_0_implicitly_has_type_any_but_a_better_type_for_its_get_accessor_may_be_inferred_from_usage_7048" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Property '{0}' implicitly has type 'any', but a better type for its get accessor may be inferred from usage.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Property_0_implicitly_has_type_any_but_a_better_type_for_its_set_accessor_may_be_inferred_from_usage_7049" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Property '{0}' implicitly has type 'any', but a better type for its set accessor may be inferred from usage.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2_2416" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Property '{0}' in type '{1}' is not assignable to the same property in base type '{2}'.]]></Val>
|
||||
@@ -4455,6 +4575,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Property_0_is_missing_in_type_1_but_required_in_type_2_2741" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Property '{0}' is missing in type '{1}' but required in type '{2}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Property_0_is_optional_in_type_1_but_required_in_type_2_2327" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Property '{0}' is optional in type '{1}' but required in type '{2}'.]]></Val>
|
||||
@@ -4869,6 +4995,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage_7047" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Rest parameter '{0}' implicitly has an 'any[]5D;' type, but a better type may be inferred from usage.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Rest_signatures_are_incompatible_2572" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Rest signatures are incompatible.]]></Val>
|
||||
@@ -5445,6 +5577,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";The_inferred_type_of_0_cannot_be_named_without_a_reference_to_1_This_is_likely_not_portable_A_type_a_2742" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[The inferred type of '{0}' cannot be named without a reference to '{1}'. This is likely not portable. A type annotation is necessary.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary_2527" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[The inferred type of '{0}' references an inaccessible '{1}' type. A type annotation is necessary.]]></Val>
|
||||
@@ -5487,9 +5625,9 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type_2362" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type_2362" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.]]></Val>
|
||||
<Val><![CDATA[The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -5577,9 +5715,9 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type_2363" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type_2363" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.]]></Val>
|
||||
<Val><![CDATA[The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -5781,6 +5919,18 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_missing_the_following_properties_from_type_1_Colon_2_2739" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is missing the following properties from type '{1}': {2}]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more_2740" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is missing the following properties from type '{1}': {2}, and {3} more.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_a_constructor_function_type_2507" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not a constructor function type.]]></Val>
|
||||
@@ -6249,6 +6399,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Using_compiler_options_of_project_reference_redirect_0_6215" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Using compiler options of project reference redirect '{0}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";VERSION_6036" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[VERSION]]></Val>
|
||||
@@ -6273,6 +6429,18 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Variable_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage_7043" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Variable '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Variable_0_implicitly_has_type_1_in_some_locations_but_a_better_type_may_be_inferred_from_usage_7046" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Variable '{0}' implicitly has type '{1}' in some locations, but a better type may be inferred from usage.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined_7034" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Variable '{0}' implicitly has type '{1}' in some locations where its type cannot be determined.]]></Val>
|
||||
@@ -6357,6 +6525,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_implicitly_has_an_1_return_type_but_a_better_type_may_be_inferred_from_usage_7050" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' implicitly has an '{1}' return type, but a better type may be inferred from usage.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_reference_7023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.]]></Val>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"A_0_modifier_cannot_be_used_with_an_interface_declaration_1045": "'{0}' 한정자는 인터페이스 선언에서 사용할 수 없습니다.",
|
||||
"A_0_parameter_must_be_the_first_parameter_2680": "'{0}' 매개 변수는 첫 번째 매개 변수여야 합니다.",
|
||||
"A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature_2463": "바인딩 패턴 매개 변수는 구현 서명에서 선택 사항이 될 수 없습니다.",
|
||||
"A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement_1105": "'break' 문은 이 문을 둘러싼 반복 문 또는 switch 문 내에서만 사용할 수 있습니다.",
|
||||
"A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement_1105": "'break' 문은 이 문을 둘러싼 반복문 또는 switch 문 내에서만 사용할 수 있습니다.",
|
||||
"A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement_1116": "'break' 문은 이 문을 둘러싼 문의 레이블로만 이동할 수 있습니다.",
|
||||
"A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments_2500": "클래스는 선택적 형식 인수가 포함된 식별자/정규화된 이름만 구현할 수 있습니다.",
|
||||
"A_class_declaration_without_the_default_modifier_must_have_a_name_1211": "'default' 한정자를 사용하지 않는 클래스 선언에는 이름이 있어야 합니다.",
|
||||
@@ -23,8 +23,8 @@
|
||||
"A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_1254": "앰비언트 컨텍스트의 'const' 이니셜라이저는 문자열 또는 숫자 리터럴이어야 합니다.",
|
||||
"A_constructor_cannot_contain_a_super_call_when_its_class_extends_null_17005": "생성자는 해당 클래스가 'null'을 확장하는 경우 'super' 호출을 포함할 수 없습니다.",
|
||||
"A_constructor_cannot_have_a_this_parameter_2681": "생성자에는 'this' 매개 변수를 사용할 수 없습니다.",
|
||||
"A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement_1104": "'continue' 문은 이 문을 둘러싼 반복 문 내에서만 사용할 수 있습니다.",
|
||||
"A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement_1115": "'continue' 문은 이 문을 둘러싼 반복 문의 레이블로만 이동할 수 있습니다.",
|
||||
"A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement_1104": "'continue' 문은 이 문을 둘러싼 반복문 내에서만 사용할 수 있습니다.",
|
||||
"A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement_1115": "'continue' 문은 이 문을 둘러싼 반복문의 레이블로만 이동할 수 있습니다.",
|
||||
"A_declare_modifier_cannot_be_used_in_an_already_ambient_context_1038": "'declare' 한정자는 이미 존재하는 앰비언트 컨텍스트에서 사용할 수 없습니다.",
|
||||
"A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file_1046": "'declare' 한정자는 .d.ts 파일의 최상위 선언에 필요합니다.",
|
||||
"A_decorator_can_only_decorate_a_method_implementation_not_an_overload_1249": "데코레이터는 오버로드가 아니라 메서드 구현만 데코레이팅할 수 있습니다.",
|
||||
|
||||
Vendored
+517
-299
File diff suppressed because it is too large
Load Diff
Vendored
+2
-1
@@ -29,7 +29,8 @@ interface Map<K, V> {
|
||||
}
|
||||
|
||||
interface MapConstructor {
|
||||
new <K = any, V = any>(entries?: ReadonlyArray<[K, V]> | null): Map<K, V>;
|
||||
new(): Map<any, any>;
|
||||
new<K, V>(entries?: ReadonlyArray<[K, V]> | null): Map<K, V>;
|
||||
readonly prototype: Map<any, any>;
|
||||
}
|
||||
declare var Map: MapConstructor;
|
||||
|
||||
Vendored
+1
-1
@@ -155,7 +155,7 @@ interface MapConstructor {
|
||||
interface WeakMap<K extends object, V> { }
|
||||
|
||||
interface WeakMapConstructor {
|
||||
new <K extends object = object, V = any>(iterable: Iterable<[K, V]>): WeakMap<K, V>;
|
||||
new <K extends object, V>(iterable: Iterable<[K, V]>): WeakMap<K, V>;
|
||||
}
|
||||
|
||||
interface Set<T> {
|
||||
|
||||
Vendored
+11
-11
@@ -83,7 +83,7 @@ interface SymbolConstructor {
|
||||
}
|
||||
|
||||
interface Symbol {
|
||||
readonly [Symbol.toStringTag]: "Symbol";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface Array<T> {
|
||||
@@ -127,23 +127,23 @@ interface Date {
|
||||
}
|
||||
|
||||
interface Map<K, V> {
|
||||
readonly [Symbol.toStringTag]: "Map";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface WeakMap<K extends object, V> {
|
||||
readonly [Symbol.toStringTag]: "WeakMap";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface Set<T> {
|
||||
readonly [Symbol.toStringTag]: "Set";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface WeakSet<T extends object> {
|
||||
readonly [Symbol.toStringTag]: "WeakSet";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface JSON {
|
||||
readonly [Symbol.toStringTag]: "JSON";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface Function {
|
||||
@@ -158,15 +158,15 @@ interface Function {
|
||||
}
|
||||
|
||||
interface GeneratorFunction {
|
||||
readonly [Symbol.toStringTag]: "GeneratorFunction";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface Math {
|
||||
readonly [Symbol.toStringTag]: "Math";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface Promise<T> {
|
||||
readonly [Symbol.toStringTag]: "Promise";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface PromiseConstructor {
|
||||
@@ -261,11 +261,11 @@ interface String {
|
||||
}
|
||||
|
||||
interface ArrayBuffer {
|
||||
readonly [Symbol.toStringTag]: "ArrayBuffer";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface DataView {
|
||||
readonly [Symbol.toStringTag]: "DataView";
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface Int8Array {
|
||||
|
||||
Vendored
+629
@@ -0,0 +1,629 @@
|
||||
/*! *****************************************************************************
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of the
|
||||
License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
||||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
||||
MERCHANTABLITY OR NON-INFRINGEMENT.
|
||||
|
||||
See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
interface BigInt {
|
||||
/**
|
||||
* Returns a string representation of an object.
|
||||
* @param radix Specifies a radix for converting numeric values to strings.
|
||||
*/
|
||||
toString(radix?: number): string;
|
||||
|
||||
/** Returns a string representation appropriate to the host environment's current locale. */
|
||||
toLocaleString(): string;
|
||||
|
||||
/** Returns the primitive value of the specified object. */
|
||||
valueOf(): bigint;
|
||||
|
||||
readonly [Symbol.toStringTag]: "BigInt";
|
||||
}
|
||||
|
||||
interface BigIntConstructor {
|
||||
(value?: any): bigint;
|
||||
readonly prototype: BigInt;
|
||||
|
||||
/**
|
||||
* Interprets the low bits of a BigInt as a 2's-complement signed integer.
|
||||
* All higher bits are discarded.
|
||||
* @param bits The number of low bits to use
|
||||
* @param int The BigInt whose bits to extract
|
||||
*/
|
||||
asIntN(bits: number, int: bigint): bigint;
|
||||
/**
|
||||
* Interprets the low bits of a BigInt as an unsigned integer.
|
||||
* All higher bits are discarded.
|
||||
* @param bits The number of low bits to use
|
||||
* @param int The BigInt whose bits to extract
|
||||
*/
|
||||
asUintN(bits: number, int: bigint): bigint;
|
||||
}
|
||||
|
||||
declare const BigInt: BigIntConstructor;
|
||||
|
||||
/**
|
||||
* A typed array of 64-bit signed integer values. The contents are initialized to 0. If the
|
||||
* requested number of bytes could not be allocated, an exception is raised.
|
||||
*/
|
||||
interface BigInt64Array {
|
||||
/** The size in bytes of each element in the array. */
|
||||
readonly BYTES_PER_ELEMENT: number;
|
||||
|
||||
/** The ArrayBuffer instance referenced by the array. */
|
||||
readonly buffer: ArrayBufferLike;
|
||||
|
||||
/** The length in bytes of the array. */
|
||||
readonly byteLength: number;
|
||||
|
||||
/** The offset in bytes of the array. */
|
||||
readonly byteOffset: number;
|
||||
|
||||
/**
|
||||
* Returns the this object after copying a section of the array identified by start and end
|
||||
* to the same array starting at position target
|
||||
* @param target If target is negative, it is treated as length+target where length is the
|
||||
* length of the array.
|
||||
* @param start If start is negative, it is treated as length+start. If end is negative, it
|
||||
* is treated as length+end.
|
||||
* @param end If not specified, length of the this object is used as its default value.
|
||||
*/
|
||||
copyWithin(target: number, start: number, end?: number): this;
|
||||
|
||||
/** Yields index, value pairs for every entry in the array. */
|
||||
entries(): IterableIterator<[number, bigint]>;
|
||||
|
||||
/**
|
||||
* Determines whether all the members of an array satisfy the specified test.
|
||||
* @param callbackfn A function that accepts up to three arguments. The every method calls
|
||||
* the callbackfn function for each element in the array until the callbackfn returns false,
|
||||
* or until the end of the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
every(callbackfn: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): boolean;
|
||||
|
||||
/**
|
||||
* Returns the this object after filling the section identified by start and end with value
|
||||
* @param value value to fill array section with
|
||||
* @param start index to start filling the array at. If start is negative, it is treated as
|
||||
* length+start where length is the length of the array.
|
||||
* @param end index to stop filling the array at. If end is negative, it is treated as
|
||||
* length+end.
|
||||
*/
|
||||
fill(value: bigint, start?: number, end?: number): this;
|
||||
|
||||
/**
|
||||
* Returns the elements of an array that meet the condition specified in a callback function.
|
||||
* @param callbackfn A function that accepts up to three arguments. The filter method calls
|
||||
* the callbackfn function one time for each element in the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
filter(callbackfn: (value: bigint, index: number, array: BigInt64Array) => any, thisArg?: any): BigInt64Array;
|
||||
|
||||
/**
|
||||
* Returns the value of the first element in the array where predicate is true, and undefined
|
||||
* otherwise.
|
||||
* @param predicate find calls predicate once for each element of the array, in ascending
|
||||
* order, until it finds one where predicate returns true. If such an element is found, find
|
||||
* immediately returns that element value. Otherwise, find returns undefined.
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
find(predicate: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): bigint | undefined;
|
||||
|
||||
/**
|
||||
* Returns the index of the first element in the array where predicate is true, and -1
|
||||
* otherwise.
|
||||
* @param predicate find calls predicate once for each element of the array, in ascending
|
||||
* order, until it finds one where predicate returns true. If such an element is found,
|
||||
* findIndex immediately returns that element index. Otherwise, findIndex returns -1.
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
findIndex(predicate: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): number;
|
||||
|
||||
/**
|
||||
* Performs the specified action for each element in an array.
|
||||
* @param callbackfn A function that accepts up to three arguments. forEach calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
forEach(callbackfn: (value: bigint, index: number, array: BigInt64Array) => void, thisArg?: any): void;
|
||||
|
||||
/**
|
||||
* Determines whether an array includes a certain element, returning true or false as appropriate.
|
||||
* @param searchElement The element to search for.
|
||||
* @param fromIndex The position in this array at which to begin searching for searchElement.
|
||||
*/
|
||||
includes(searchElement: bigint, fromIndex?: number): boolean;
|
||||
|
||||
/**
|
||||
* Returns the index of the first occurrence of a value in an array.
|
||||
* @param searchElement The value to locate in the array.
|
||||
* @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
|
||||
* search starts at index 0.
|
||||
*/
|
||||
indexOf(searchElement: bigint, fromIndex?: number): number;
|
||||
|
||||
/**
|
||||
* Adds all the elements of an array separated by the specified separator string.
|
||||
* @param separator A string used to separate one element of an array from the next in the
|
||||
* resulting String. If omitted, the array elements are separated with a comma.
|
||||
*/
|
||||
join(separator?: string): string;
|
||||
|
||||
/** Yields each index in the array. */
|
||||
keys(): IterableIterator<number>;
|
||||
|
||||
/**
|
||||
* Returns the index of the last occurrence of a value in an array.
|
||||
* @param searchElement The value to locate in the array.
|
||||
* @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
|
||||
* search starts at index 0.
|
||||
*/
|
||||
lastIndexOf(searchElement: bigint, fromIndex?: number): number;
|
||||
|
||||
/** The length of the array. */
|
||||
readonly length: number;
|
||||
|
||||
/**
|
||||
* Calls a defined callback function on each element of an array, and returns an array that
|
||||
* contains the results.
|
||||
* @param callbackfn A function that accepts up to three arguments. The map method calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
map(callbackfn: (value: bigint, index: number, array: BigInt64Array) => bigint, thisArg?: any): BigInt64Array;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array. The return value of
|
||||
* the callback function is the accumulated result, and is provided as an argument in the next
|
||||
* call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduce method calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an argument
|
||||
* instead of an array value.
|
||||
*/
|
||||
reduce(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigInt64Array) => bigint): bigint;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array. The return value of
|
||||
* the callback function is the accumulated result, and is provided as an argument in the next
|
||||
* call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduce method calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an argument
|
||||
* instead of an array value.
|
||||
*/
|
||||
reduce<U>(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigInt64Array) => U, initialValue: U): U;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array, in descending order.
|
||||
* The return value of the callback function is the accumulated result, and is provided as an
|
||||
* argument in the next call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduceRight method calls
|
||||
* the callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an
|
||||
* argument instead of an array value.
|
||||
*/
|
||||
reduceRight(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigInt64Array) => bigint): bigint;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array, in descending order.
|
||||
* The return value of the callback function is the accumulated result, and is provided as an
|
||||
* argument in the next call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduceRight method calls
|
||||
* the callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an argument
|
||||
* instead of an array value.
|
||||
*/
|
||||
reduceRight<U>(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigInt64Array) => U, initialValue: U): U;
|
||||
|
||||
/** Reverses the elements in the array. */
|
||||
reverse(): this;
|
||||
|
||||
/**
|
||||
* Sets a value or an array of values.
|
||||
* @param array A typed or untyped array of values to set.
|
||||
* @param offset The index in the current array at which the values are to be written.
|
||||
*/
|
||||
set(array: ArrayLike<bigint>, offset?: number): void;
|
||||
|
||||
/**
|
||||
* Returns a section of an array.
|
||||
* @param start The beginning of the specified portion of the array.
|
||||
* @param end The end of the specified portion of the array.
|
||||
*/
|
||||
slice(start?: number, end?: number): BigInt64Array;
|
||||
|
||||
/**
|
||||
* Determines whether the specified callback function returns true for any element of an array.
|
||||
* @param callbackfn A function that accepts up to three arguments. The some method calls the
|
||||
* callbackfn function for each element in the array until the callbackfn returns true, or until
|
||||
* the end of the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
some(callbackfn: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): boolean;
|
||||
|
||||
/**
|
||||
* Sorts the array.
|
||||
* @param compareFn The function used to determine the order of the elements. If omitted, the elements are sorted in ascending order.
|
||||
*/
|
||||
sort(compareFn?: (a: bigint, b: bigint) => number | bigint): this;
|
||||
|
||||
/**
|
||||
* Gets a new BigInt64Array view of the ArrayBuffer store for this array, referencing the elements
|
||||
* at begin, inclusive, up to end, exclusive.
|
||||
* @param begin The index of the beginning of the array.
|
||||
* @param end The index of the end of the array.
|
||||
*/
|
||||
subarray(begin: number, end?: number): BigInt64Array;
|
||||
|
||||
/** Converts the array to a string by using the current locale. */
|
||||
toLocaleString(): string;
|
||||
|
||||
/** Returns a string representation of the array. */
|
||||
toString(): string;
|
||||
|
||||
/** Yields each value in the array. */
|
||||
values(): IterableIterator<bigint>;
|
||||
|
||||
[Symbol.iterator](): IterableIterator<bigint>;
|
||||
|
||||
readonly [Symbol.toStringTag]: "BigInt64Array";
|
||||
|
||||
[index: number]: bigint;
|
||||
}
|
||||
|
||||
interface BigInt64ArrayConstructor {
|
||||
readonly prototype: BigInt64Array;
|
||||
new(length?: number): BigInt64Array;
|
||||
new(array: Iterable<bigint>): BigInt64Array;
|
||||
new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): BigInt64Array;
|
||||
|
||||
/** The size in bytes of each element in the array. */
|
||||
readonly BYTES_PER_ELEMENT: number;
|
||||
|
||||
/**
|
||||
* Returns a new array from a set of elements.
|
||||
* @param items A set of elements to include in the new array object.
|
||||
*/
|
||||
of(...items: bigint[]): BigInt64Array;
|
||||
|
||||
/**
|
||||
* Creates an array from an array-like or iterable object.
|
||||
* @param arrayLike An array-like or iterable object to convert to an array.
|
||||
* @param mapfn A mapping function to call on every element of the array.
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from(arrayLike: ArrayLike<bigint>): BigInt64Array;
|
||||
from<U>(arrayLike: ArrayLike<U>, mapfn: (v: U, k: number) => bigint, thisArg?: any): BigInt64Array;
|
||||
}
|
||||
|
||||
declare const BigInt64Array: BigInt64ArrayConstructor;
|
||||
|
||||
/**
|
||||
* A typed array of 64-bit unsigned integer values. The contents are initialized to 0. If the
|
||||
* requested number of bytes could not be allocated, an exception is raised.
|
||||
*/
|
||||
interface BigUint64Array {
|
||||
/** The size in bytes of each element in the array. */
|
||||
readonly BYTES_PER_ELEMENT: number;
|
||||
|
||||
/** The ArrayBuffer instance referenced by the array. */
|
||||
readonly buffer: ArrayBufferLike;
|
||||
|
||||
/** The length in bytes of the array. */
|
||||
readonly byteLength: number;
|
||||
|
||||
/** The offset in bytes of the array. */
|
||||
readonly byteOffset: number;
|
||||
|
||||
/**
|
||||
* Returns the this object after copying a section of the array identified by start and end
|
||||
* to the same array starting at position target
|
||||
* @param target If target is negative, it is treated as length+target where length is the
|
||||
* length of the array.
|
||||
* @param start If start is negative, it is treated as length+start. If end is negative, it
|
||||
* is treated as length+end.
|
||||
* @param end If not specified, length of the this object is used as its default value.
|
||||
*/
|
||||
copyWithin(target: number, start: number, end?: number): this;
|
||||
|
||||
/** Yields index, value pairs for every entry in the array. */
|
||||
entries(): IterableIterator<[number, bigint]>;
|
||||
|
||||
/**
|
||||
* Determines whether all the members of an array satisfy the specified test.
|
||||
* @param callbackfn A function that accepts up to three arguments. The every method calls
|
||||
* the callbackfn function for each element in the array until the callbackfn returns false,
|
||||
* or until the end of the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
every(callbackfn: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): boolean;
|
||||
|
||||
/**
|
||||
* Returns the this object after filling the section identified by start and end with value
|
||||
* @param value value to fill array section with
|
||||
* @param start index to start filling the array at. If start is negative, it is treated as
|
||||
* length+start where length is the length of the array.
|
||||
* @param end index to stop filling the array at. If end is negative, it is treated as
|
||||
* length+end.
|
||||
*/
|
||||
fill(value: bigint, start?: number, end?: number): this;
|
||||
|
||||
/**
|
||||
* Returns the elements of an array that meet the condition specified in a callback function.
|
||||
* @param callbackfn A function that accepts up to three arguments. The filter method calls
|
||||
* the callbackfn function one time for each element in the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
filter(callbackfn: (value: bigint, index: number, array: BigUint64Array) => any, thisArg?: any): BigUint64Array;
|
||||
|
||||
/**
|
||||
* Returns the value of the first element in the array where predicate is true, and undefined
|
||||
* otherwise.
|
||||
* @param predicate find calls predicate once for each element of the array, in ascending
|
||||
* order, until it finds one where predicate returns true. If such an element is found, find
|
||||
* immediately returns that element value. Otherwise, find returns undefined.
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
find(predicate: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): bigint | undefined;
|
||||
|
||||
/**
|
||||
* Returns the index of the first element in the array where predicate is true, and -1
|
||||
* otherwise.
|
||||
* @param predicate find calls predicate once for each element of the array, in ascending
|
||||
* order, until it finds one where predicate returns true. If such an element is found,
|
||||
* findIndex immediately returns that element index. Otherwise, findIndex returns -1.
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
findIndex(predicate: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): number;
|
||||
|
||||
/**
|
||||
* Performs the specified action for each element in an array.
|
||||
* @param callbackfn A function that accepts up to three arguments. forEach calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
forEach(callbackfn: (value: bigint, index: number, array: BigUint64Array) => void, thisArg?: any): void;
|
||||
|
||||
/**
|
||||
* Determines whether an array includes a certain element, returning true or false as appropriate.
|
||||
* @param searchElement The element to search for.
|
||||
* @param fromIndex The position in this array at which to begin searching for searchElement.
|
||||
*/
|
||||
includes(searchElement: bigint, fromIndex?: number): boolean;
|
||||
|
||||
/**
|
||||
* Returns the index of the first occurrence of a value in an array.
|
||||
* @param searchElement The value to locate in the array.
|
||||
* @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
|
||||
* search starts at index 0.
|
||||
*/
|
||||
indexOf(searchElement: bigint, fromIndex?: number): number;
|
||||
|
||||
/**
|
||||
* Adds all the elements of an array separated by the specified separator string.
|
||||
* @param separator A string used to separate one element of an array from the next in the
|
||||
* resulting String. If omitted, the array elements are separated with a comma.
|
||||
*/
|
||||
join(separator?: string): string;
|
||||
|
||||
/** Yields each index in the array. */
|
||||
keys(): IterableIterator<number>;
|
||||
|
||||
/**
|
||||
* Returns the index of the last occurrence of a value in an array.
|
||||
* @param searchElement The value to locate in the array.
|
||||
* @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
|
||||
* search starts at index 0.
|
||||
*/
|
||||
lastIndexOf(searchElement: bigint, fromIndex?: number): number;
|
||||
|
||||
/** The length of the array. */
|
||||
readonly length: number;
|
||||
|
||||
/**
|
||||
* Calls a defined callback function on each element of an array, and returns an array that
|
||||
* contains the results.
|
||||
* @param callbackfn A function that accepts up to three arguments. The map method calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
map(callbackfn: (value: bigint, index: number, array: BigUint64Array) => bigint, thisArg?: any): BigUint64Array;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array. The return value of
|
||||
* the callback function is the accumulated result, and is provided as an argument in the next
|
||||
* call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduce method calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an argument
|
||||
* instead of an array value.
|
||||
*/
|
||||
reduce(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigUint64Array) => bigint): bigint;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array. The return value of
|
||||
* the callback function is the accumulated result, and is provided as an argument in the next
|
||||
* call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduce method calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an argument
|
||||
* instead of an array value.
|
||||
*/
|
||||
reduce<U>(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigUint64Array) => U, initialValue: U): U;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array, in descending order.
|
||||
* The return value of the callback function is the accumulated result, and is provided as an
|
||||
* argument in the next call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduceRight method calls
|
||||
* the callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an
|
||||
* argument instead of an array value.
|
||||
*/
|
||||
reduceRight(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigUint64Array) => bigint): bigint;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array, in descending order.
|
||||
* The return value of the callback function is the accumulated result, and is provided as an
|
||||
* argument in the next call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduceRight method calls
|
||||
* the callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an argument
|
||||
* instead of an array value.
|
||||
*/
|
||||
reduceRight<U>(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigUint64Array) => U, initialValue: U): U;
|
||||
|
||||
/** Reverses the elements in the array. */
|
||||
reverse(): this;
|
||||
|
||||
/**
|
||||
* Sets a value or an array of values.
|
||||
* @param array A typed or untyped array of values to set.
|
||||
* @param offset The index in the current array at which the values are to be written.
|
||||
*/
|
||||
set(array: ArrayLike<bigint>, offset?: number): void;
|
||||
|
||||
/**
|
||||
* Returns a section of an array.
|
||||
* @param start The beginning of the specified portion of the array.
|
||||
* @param end The end of the specified portion of the array.
|
||||
*/
|
||||
slice(start?: number, end?: number): BigUint64Array;
|
||||
|
||||
/**
|
||||
* Determines whether the specified callback function returns true for any element of an array.
|
||||
* @param callbackfn A function that accepts up to three arguments. The some method calls the
|
||||
* callbackfn function for each element in the array until the callbackfn returns true, or until
|
||||
* the end of the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
some(callbackfn: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): boolean;
|
||||
|
||||
/**
|
||||
* Sorts the array.
|
||||
* @param compareFn The function used to determine the order of the elements. If omitted, the elements are sorted in ascending order.
|
||||
*/
|
||||
sort(compareFn?: (a: bigint, b: bigint) => number | bigint): this;
|
||||
|
||||
/**
|
||||
* Gets a new BigUint64Array view of the ArrayBuffer store for this array, referencing the elements
|
||||
* at begin, inclusive, up to end, exclusive.
|
||||
* @param begin The index of the beginning of the array.
|
||||
* @param end The index of the end of the array.
|
||||
*/
|
||||
subarray(begin: number, end?: number): BigUint64Array;
|
||||
|
||||
/** Converts the array to a string by using the current locale. */
|
||||
toLocaleString(): string;
|
||||
|
||||
/** Returns a string representation of the array. */
|
||||
toString(): string;
|
||||
|
||||
/** Yields each value in the array. */
|
||||
values(): IterableIterator<bigint>;
|
||||
|
||||
[Symbol.iterator](): IterableIterator<bigint>;
|
||||
|
||||
readonly [Symbol.toStringTag]: "BigUint64Array";
|
||||
|
||||
[index: number]: bigint;
|
||||
}
|
||||
|
||||
interface BigUint64ArrayConstructor {
|
||||
readonly prototype: BigUint64Array;
|
||||
new(length?: number): BigUint64Array;
|
||||
new(array: Iterable<bigint>): BigUint64Array;
|
||||
new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): BigUint64Array;
|
||||
|
||||
/** The size in bytes of each element in the array. */
|
||||
readonly BYTES_PER_ELEMENT: number;
|
||||
|
||||
/**
|
||||
* Returns a new array from a set of elements.
|
||||
* @param items A set of elements to include in the new array object.
|
||||
*/
|
||||
of(...items: bigint[]): BigUint64Array;
|
||||
|
||||
/**
|
||||
* Creates an array from an array-like or iterable object.
|
||||
* @param arrayLike An array-like or iterable object to convert to an array.
|
||||
* @param mapfn A mapping function to call on every element of the array.
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from(arrayLike: ArrayLike<bigint>): BigUint64Array;
|
||||
from<U>(arrayLike: ArrayLike<U>, mapfn: (v: U, k: number) => bigint, thisArg?: any): BigUint64Array;
|
||||
}
|
||||
|
||||
declare const BigUint64Array: BigUint64ArrayConstructor;
|
||||
|
||||
interface DataView {
|
||||
/**
|
||||
* Gets the BigInt64 value at the specified byte offset from the start of the view. There is
|
||||
* no alignment constraint; multi-byte values may be fetched from any offset.
|
||||
* @param byteOffset The place in the buffer at which the value should be retrieved.
|
||||
*/
|
||||
getBigInt64(byteOffset: number, littleEndian?: boolean): bigint;
|
||||
|
||||
/**
|
||||
* Gets the BigUint64 value at the specified byte offset from the start of the view. There is
|
||||
* no alignment constraint; multi-byte values may be fetched from any offset.
|
||||
* @param byteOffset The place in the buffer at which the value should be retrieved.
|
||||
*/
|
||||
getBigUint64(byteOffset: number, littleEndian?: boolean): bigint;
|
||||
|
||||
/**
|
||||
* Stores a BigInt64 value at the specified byte offset from the start of the view.
|
||||
* @param byteOffset The place in the buffer at which the value should be set.
|
||||
* @param value The value to set.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be written,
|
||||
* otherwise a little-endian value should be written.
|
||||
*/
|
||||
setBigInt64(byteOffset: number, value: bigint, littleEndian?: boolean): void;
|
||||
|
||||
/**
|
||||
* Stores a BigUint64 value at the specified byte offset from the start of the view.
|
||||
* @param byteOffset The place in the buffer at which the value should be set.
|
||||
* @param value The value to set.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be written,
|
||||
* otherwise a little-endian value should be written.
|
||||
*/
|
||||
setBigUint64(byteOffset: number, value: bigint, littleEndian?: boolean): void;
|
||||
}
|
||||
Vendored
+1
@@ -21,5 +21,6 @@ and limitations under the License.
|
||||
/// <reference lib="es2018" />
|
||||
/// <reference lib="esnext.asynciterable" />
|
||||
/// <reference lib="esnext.array" />
|
||||
/// <reference lib="esnext.bigint" />
|
||||
/// <reference lib="esnext.symbol" />
|
||||
/// <reference lib="esnext.intl" />
|
||||
|
||||
Vendored
+1296
-13
File diff suppressed because it is too large
Load Diff
Vendored
+16
-2
@@ -61,7 +61,8 @@ declare namespace ts.server.protocol {
|
||||
GetApplicableRefactors = "getApplicableRefactors",
|
||||
GetEditsForRefactor = "getEditsForRefactor",
|
||||
OrganizeImports = "organizeImports",
|
||||
GetEditsForFileRename = "getEditsForFileRename"
|
||||
GetEditsForFileRename = "getEditsForFileRename",
|
||||
ConfigurePlugin = "configurePlugin"
|
||||
}
|
||||
/**
|
||||
* A TypeScript Server message
|
||||
@@ -136,6 +137,10 @@ declare namespace ts.server.protocol {
|
||||
* Contains message body if success === true.
|
||||
*/
|
||||
body?: any;
|
||||
/**
|
||||
* Contains extra information that plugin can include to be passed on
|
||||
*/
|
||||
metadata?: unknown;
|
||||
}
|
||||
/**
|
||||
* Arguments for FileRequest messages.
|
||||
@@ -781,7 +786,7 @@ declare namespace ts.server.protocol {
|
||||
/**
|
||||
* The file locations referencing the symbol.
|
||||
*/
|
||||
refs: ReferencesResponseItem[];
|
||||
refs: ReadonlyArray<ReferencesResponseItem>;
|
||||
/**
|
||||
* The name of the symbol.
|
||||
*/
|
||||
@@ -1010,6 +1015,14 @@ declare namespace ts.server.protocol {
|
||||
*/
|
||||
interface ConfigureResponse extends Response {
|
||||
}
|
||||
interface ConfigurePluginRequestArguments {
|
||||
pluginName: string;
|
||||
configuration: any;
|
||||
}
|
||||
interface ConfigurePluginRequest extends Request {
|
||||
command: CommandTypes.ConfigurePlugin;
|
||||
arguments: ConfigurePluginRequestArguments;
|
||||
}
|
||||
/**
|
||||
* Information found in an "open" request.
|
||||
*/
|
||||
@@ -1847,6 +1860,7 @@ declare namespace ts.server.protocol {
|
||||
*/
|
||||
interface DiagnosticEvent extends Event {
|
||||
body?: DiagnosticEventBody;
|
||||
event: DiagnosticEventKind;
|
||||
}
|
||||
interface ConfigFileDiagnosticEventBody {
|
||||
/**
|
||||
|
||||
+10765
-9382
File diff suppressed because it is too large
Load Diff
+16062
-14239
File diff suppressed because it is too large
Load Diff
Vendored
+558
-502
File diff suppressed because it is too large
Load Diff
+16036
-14259
File diff suppressed because it is too large
Load Diff
Vendored
+520
-490
File diff suppressed because it is too large
Load Diff
+15714
-14025
File diff suppressed because it is too large
Load Diff
Vendored
+520
-490
File diff suppressed because it is too large
Load Diff
+15714
-14025
File diff suppressed because it is too large
Load Diff
+11660
-10330
File diff suppressed because it is too large
Load Diff
@@ -406,11 +406,11 @@
|
||||
"Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions_2521": "運算式會解析成變數宣告 '{0}',而編譯器會使用此宣告支援非同步函式。",
|
||||
"Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta__2544": "運算式將解析成變數宣告 '_newTarget',而供編譯器用來擷取 'new.target' 中繼屬性參考。",
|
||||
"Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference_2400": "運算式會解析成變數宣告 '_this',而編譯器會使用此宣告來擷取 'this' 參考 。",
|
||||
"Extract_constant_95006": "解壓縮常數",
|
||||
"Extract_function_95005": "解壓縮函式",
|
||||
"Extract_to_0_in_1_95004": "解壓縮至 {1} 中的 {0}",
|
||||
"Extract_to_0_in_1_scope_95008": "解壓縮至 {1} 範圍中的 {0}",
|
||||
"Extract_to_0_in_enclosing_scope_95007": "解壓縮至封閉式範圍中的 {0}",
|
||||
"Extract_constant_95006": "擷取常數",
|
||||
"Extract_function_95005": "擷取函式",
|
||||
"Extract_to_0_in_1_95004": "擷取至 {1} 中的 {0}",
|
||||
"Extract_to_0_in_1_scope_95008": "擷取至 {1} 範圍中的 {0}",
|
||||
"Extract_to_0_in_enclosing_scope_95007": "擷取至封閉式範圍中的 {0}",
|
||||
"FILE_6035": "檔案",
|
||||
"FILE_OR_DIRECTORY_6040": "檔案或目錄",
|
||||
"Failed_to_parse_file_0_Colon_1_5014": "無法剖析檔案 '{0}': {1}。",
|
||||
@@ -584,7 +584,7 @@
|
||||
"Module_name_0_was_successfully_resolved_to_1_6089": "======== 模組名稱 '{0}' 已成功解析為 '{1}'。========",
|
||||
"Module_resolution_kind_is_not_specified_using_0_6088": "未指定模組解析種類,將使用 '{0}'。",
|
||||
"Module_resolution_using_rootDirs_has_failed_6111": "使用 'rootDirs' 解析模組失敗。",
|
||||
"Move_to_a_new_file_95049": "移至新行",
|
||||
"Move_to_a_new_file_95049": "移至新檔",
|
||||
"Multiple_consecutive_numeric_separators_are_not_permitted_6189": "不允許多個連續的數字分隔符號。",
|
||||
"Multiple_constructor_implementations_are_not_allowed_2392": "不允許多個建構函式實作。",
|
||||
"NEWLINE_6061": "新行",
|
||||
|
||||
+2
-1
@@ -2,7 +2,7 @@
|
||||
"name": "typescript",
|
||||
"author": "Microsoft Corp.",
|
||||
"homepage": "https://www.typescriptlang.org/",
|
||||
"version": "3.2.0",
|
||||
"version": "3.3.0",
|
||||
"license": "Apache-2.0",
|
||||
"description": "TypeScript is a language for application scale JavaScript development",
|
||||
"keywords": [
|
||||
@@ -82,6 +82,7 @@
|
||||
"mocha": "latest",
|
||||
"mocha-fivemat-progress-reporter": "latest",
|
||||
"plugin-error": "latest",
|
||||
"pretty-hrtime": "^1.0.3",
|
||||
"prex": "^0.4.3",
|
||||
"q": "latest",
|
||||
"remove-internal": "^2.9.2",
|
||||
|
||||
@@ -683,11 +683,17 @@ function ensureCompileTask(projectGraph, options) {
|
||||
}
|
||||
});
|
||||
}
|
||||
const js = (projectGraphConfig.resolvedOptions.js ? projectGraphConfig.resolvedOptions.js(stream.js) : stream.js)
|
||||
|
||||
const additionalJsOutputs = projectGraphConfig.resolvedOptions.js ? projectGraphConfig.resolvedOptions.js(stream.js)
|
||||
.pipe(gulpif(sourceMap || inlineSourceMap, sourcemaps.write(sourceMapPath, sourceMapOptions))) : undefined;
|
||||
const additionalDtsOutputs = projectGraphConfig.resolvedOptions.dts ? projectGraphConfig.resolvedOptions.dts(stream.dts)
|
||||
.pipe(gulpif(declarationMap, sourcemaps.write(sourceMapPath, sourceMapOptions))) : undefined;
|
||||
|
||||
const js = stream.js
|
||||
.pipe(gulpif(sourceMap || inlineSourceMap, sourcemaps.write(sourceMapPath, sourceMapOptions)));
|
||||
const dts = (projectGraphConfig.resolvedOptions.dts ? projectGraphConfig.resolvedOptions.dts(stream.dts) : stream.dts)
|
||||
const dts = stream.dts
|
||||
.pipe(gulpif(declarationMap, sourcemaps.write(sourceMapPath, sourceMapOptions)));
|
||||
return merge2([js, dts])
|
||||
return merge2([js, dts, additionalJsOutputs, additionalDtsOutputs].filter(x => !!x))
|
||||
.pipe(gulp.dest(destPath));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ function main(): void {
|
||||
console.error("Unexpected XML file structure. Expected to find result.LCX.$.TgtCul.");
|
||||
process.exit(1);
|
||||
}
|
||||
const outputDirectoryName = getPreferedLocaleName(result.LCX.$.TgtCul);
|
||||
const outputDirectoryName = getPreferedLocaleName(result.LCX.$.TgtCul).toLowerCase();
|
||||
if (!outputDirectoryName) {
|
||||
console.error(`Invalid output locale name for '${result.LCX.$.TgtCul}'.`);
|
||||
process.exit(1);
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace ts {
|
||||
|
||||
let symbolCount = 0;
|
||||
|
||||
let Symbol: { new (flags: SymbolFlags, name: __String): Symbol }; // tslint:disable-line variable-name
|
||||
let Symbol: new (flags: SymbolFlags, name: __String) => Symbol; // tslint:disable-line variable-name
|
||||
let classifiableNames: UnderscoreEscapedMap<true>;
|
||||
|
||||
const unreachableFlow: FlowNode = { flags: FlowFlags.Unreachable };
|
||||
@@ -233,6 +233,11 @@ namespace ts {
|
||||
symbol.members = createSymbolTable();
|
||||
}
|
||||
|
||||
// On merge of const enum module with class or function, reset const enum only flag (namespaces will already recalculate)
|
||||
if (symbol.constEnumOnlyModule && (symbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.RegularEnum))) {
|
||||
symbol.constEnumOnlyModule = false;
|
||||
}
|
||||
|
||||
if (symbolFlags & SymbolFlags.Value) {
|
||||
setValueDeclaration(symbol, node);
|
||||
}
|
||||
@@ -1379,6 +1384,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindJSDocTypeAlias(node: JSDocTypedefTag | JSDocCallbackTag) {
|
||||
node.tagName.parent = node;
|
||||
if (node.fullName) {
|
||||
setParentPointers(node, node.fullName);
|
||||
}
|
||||
@@ -2607,7 +2613,7 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
const node = symbol.valueDeclaration;
|
||||
if (isCallExpression(node)) {
|
||||
if (node && isCallExpression(node)) {
|
||||
return !!getAssignedExpandoInitializer(node);
|
||||
}
|
||||
let init = !node ? undefined :
|
||||
|
||||
+937
-501
File diff suppressed because it is too large
Load Diff
@@ -119,6 +119,18 @@ namespace ts {
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Enable_tracing_of_the_name_resolution_process
|
||||
},
|
||||
{
|
||||
name: "diagnostics",
|
||||
type: "boolean",
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Show_diagnostic_information
|
||||
},
|
||||
{
|
||||
name: "extendedDiagnostics",
|
||||
type: "boolean",
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Show_verbose_diagnostic_information
|
||||
},
|
||||
];
|
||||
|
||||
/* @internal */
|
||||
@@ -584,12 +596,6 @@ namespace ts {
|
||||
category: Diagnostics.Experimental_Options,
|
||||
description: Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators
|
||||
},
|
||||
{
|
||||
name: "experimentalBigInt",
|
||||
type: "boolean",
|
||||
category: Diagnostics.Experimental_Options,
|
||||
description: Diagnostics.Enables_experimental_support_for_ESNext_BigInt_literals
|
||||
},
|
||||
|
||||
// Advanced
|
||||
{
|
||||
@@ -598,18 +604,6 @@ namespace ts {
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h
|
||||
},
|
||||
{
|
||||
name: "diagnostics",
|
||||
type: "boolean",
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Show_diagnostic_information
|
||||
},
|
||||
{
|
||||
name: "extendedDiagnostics",
|
||||
type: "boolean",
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Show_verbose_diagnostic_information
|
||||
},
|
||||
{
|
||||
name: "resolveJsonModule",
|
||||
type: "boolean",
|
||||
@@ -1679,13 +1673,13 @@ namespace ts {
|
||||
const files = map(
|
||||
filter(
|
||||
configParseResult.fileNames,
|
||||
!configParseResult.configFileSpecs ? _ => false : matchesSpecs(
|
||||
(!configParseResult.configFileSpecs || !configParseResult.configFileSpecs.validatedIncludeSpecs) ? _ => true : matchesSpecs(
|
||||
configFileName,
|
||||
configParseResult.configFileSpecs.validatedIncludeSpecs,
|
||||
configParseResult.configFileSpecs.validatedExcludeSpecs
|
||||
)
|
||||
),
|
||||
f => getRelativePathFromFile(getNormalizedAbsolutePath(configFileName, host.getCurrentDirectory()), f, getCanonicalFileName)
|
||||
f => getRelativePathFromFile(getNormalizedAbsolutePath(configFileName, host.getCurrentDirectory()), getNormalizedAbsolutePath(f, host.getCurrentDirectory()), getCanonicalFileName)
|
||||
);
|
||||
const optionMap = serializeCompilerOptions(configParseResult.options, { configFilePath: getNormalizedAbsolutePath(configFileName, host.getCurrentDirectory()), useCaseSensitiveFileNames: host.useCaseSensitiveFileNames });
|
||||
const config = {
|
||||
@@ -1699,6 +1693,8 @@ namespace ts {
|
||||
listFiles: undefined,
|
||||
listEmittedFiles: undefined,
|
||||
project: undefined,
|
||||
build: undefined,
|
||||
version: undefined,
|
||||
},
|
||||
references: map(configParseResult.projectReferences, r => ({ ...r, path: r.originalPath, originalPath: undefined })),
|
||||
files: length(files) ? files : undefined,
|
||||
@@ -1719,24 +1715,24 @@ namespace ts {
|
||||
}
|
||||
|
||||
function matchesSpecs(path: string, includeSpecs: ReadonlyArray<string> | undefined, excludeSpecs: ReadonlyArray<string> | undefined): (path: string) => boolean {
|
||||
if (!includeSpecs) return _ => false;
|
||||
if (!includeSpecs) return _ => true;
|
||||
const patterns = getFileMatcherPatterns(path, excludeSpecs, includeSpecs, sys.useCaseSensitiveFileNames, sys.getCurrentDirectory());
|
||||
const excludeRe = patterns.excludePattern && getRegexFromPattern(patterns.excludePattern, sys.useCaseSensitiveFileNames);
|
||||
const includeRe = patterns.includeFilePattern && getRegexFromPattern(patterns.includeFilePattern, sys.useCaseSensitiveFileNames);
|
||||
if (includeRe) {
|
||||
if (excludeRe) {
|
||||
return path => includeRe.test(path) && !excludeRe.test(path);
|
||||
return path => !(includeRe.test(path) && !excludeRe.test(path));
|
||||
}
|
||||
return path => includeRe.test(path);
|
||||
return path => !includeRe.test(path);
|
||||
}
|
||||
if (excludeRe) {
|
||||
return path => !excludeRe.test(path);
|
||||
return path => excludeRe.test(path);
|
||||
}
|
||||
return _ => false;
|
||||
return _ => true;
|
||||
}
|
||||
|
||||
function getCustomTypeMapOfCommandLineOption(optionDefinition: CommandLineOption): Map<string | number> | undefined {
|
||||
if (optionDefinition.type === "string" || optionDefinition.type === "number" || optionDefinition.type === "boolean") {
|
||||
if (optionDefinition.type === "string" || optionDefinition.type === "number" || optionDefinition.type === "boolean" || optionDefinition.type === "object") {
|
||||
// this is of a type CommandLineOptionOfPrimitiveType
|
||||
return undefined;
|
||||
}
|
||||
@@ -1899,7 +1895,7 @@ namespace ts {
|
||||
}
|
||||
result.push(`}`);
|
||||
|
||||
return result.join(newLine);
|
||||
return result.join(newLine) + newLine;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-7
@@ -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.2";
|
||||
export const versionMajorMinor = "3.3";
|
||||
/** The version of the TypeScript compiler release */
|
||||
export const version = `${versionMajorMinor}.0-dev`;
|
||||
}
|
||||
@@ -112,13 +112,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
// The global Map object. This may not be available, so we must test for it.
|
||||
declare const Map: { new <T>(): Map<T> } | undefined;
|
||||
declare const Map: (new <T>() => Map<T>) | undefined;
|
||||
// Internet Explorer's Map doesn't support iteration, so don't use it.
|
||||
// tslint:disable-next-line no-in-operator variable-name
|
||||
export const MapCtr = typeof Map !== "undefined" && "entries" in Map.prototype ? Map : shimMap();
|
||||
|
||||
// Keep the class inside a function so it doesn't get compiled if it's not used.
|
||||
function shimMap(): { new <T>(): Map<T> } {
|
||||
function shimMap(): new <T>() => Map<T> {
|
||||
|
||||
class MapIterator<T, U extends (string | T | [string, T])> {
|
||||
private data: MapLike<T>;
|
||||
@@ -1268,9 +1268,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** Shims `Array.from`. */
|
||||
export function arrayFrom<T, U>(iterator: Iterator<T>, map: (t: T) => U): U[];
|
||||
export function arrayFrom<T>(iterator: Iterator<T>): T[];
|
||||
export function arrayFrom(iterator: Iterator<any>, map?: (t: any) => any): any[] {
|
||||
export function arrayFrom<T, U>(iterator: Iterator<T> | IterableIterator<T>, map: (t: T) => U): U[];
|
||||
export function arrayFrom<T>(iterator: Iterator<T> | IterableIterator<T>): T[];
|
||||
export function arrayFrom(iterator: Iterator<any> | IterableIterator<any>, map?: (t: any) => any): any[] {
|
||||
const result: any[] = [];
|
||||
for (let { value, done } = iterator.next(); !done; { value, done } = iterator.next()) {
|
||||
result.push(map ? map(value) : value);
|
||||
@@ -2165,6 +2165,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function fill<T>(length: number, cb: (index: number) => T): T[] {
|
||||
return new Array(length).fill(0).map((_, i) => cb(i));
|
||||
const result = Array<T>(length);
|
||||
for (let i = 0; i < length; i++) {
|
||||
result[i] = cb(i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1011,10 +1011,18 @@
|
||||
"category": "Message",
|
||||
"code": 1350
|
||||
},
|
||||
"Experimental support for BigInt is a feature that is subject to change in a future release. Set the 'experimentalBigInt' option to remove this warning.": {
|
||||
"An identifier or keyword cannot immediately follow a numeric literal.": {
|
||||
"category": "Error",
|
||||
"code": 1351
|
||||
},
|
||||
"A bigint literal cannot use exponential notation.": {
|
||||
"category": "Error",
|
||||
"code": 1352
|
||||
},
|
||||
"A bigint literal must be an integer.": {
|
||||
"category": "Error",
|
||||
"code": 1353
|
||||
},
|
||||
|
||||
"Duplicate identifier '{0}'.": {
|
||||
"category": "Error",
|
||||
@@ -1064,7 +1072,7 @@
|
||||
"category": "Error",
|
||||
"code": 2311
|
||||
},
|
||||
"An interface may only extend a class or another interface.": {
|
||||
"An interface can only extend an object type or intersection of object types with statically known members.": {
|
||||
"category": "Error",
|
||||
"code": 2312
|
||||
},
|
||||
@@ -1492,7 +1500,7 @@
|
||||
"category": "Error",
|
||||
"code": 2420
|
||||
},
|
||||
"A class may only implement another class or interface.": {
|
||||
"A class can only implement an object type or intersection of object types with statically known members.": {
|
||||
"category": "Error",
|
||||
"code": 2422
|
||||
},
|
||||
@@ -1636,14 +1644,6 @@
|
||||
"category": "Error",
|
||||
"code": 2458
|
||||
},
|
||||
"Type '{0}' has no property '{1}' and no string index signature.": {
|
||||
"category": "Error",
|
||||
"code": 2459
|
||||
},
|
||||
"Type '{0}' has no property '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 2460
|
||||
},
|
||||
"Type '{0}' is not an array type.": {
|
||||
"category": "Error",
|
||||
"code": 2461
|
||||
@@ -1696,7 +1696,7 @@
|
||||
"category": "Error",
|
||||
"code": 2473
|
||||
},
|
||||
"In 'const' enum declarations member initializer must be constant expression.": {
|
||||
"const enum member initializers can only contain literal values and other computed enum values.": {
|
||||
"category": "Error",
|
||||
"code": 2474
|
||||
},
|
||||
@@ -1760,7 +1760,7 @@
|
||||
"category": "Error",
|
||||
"code": 2492
|
||||
},
|
||||
"Tuple type '{0}' with length '{1}' cannot be assigned to tuple with length '{2}'.": {
|
||||
"Tuple type '{0}' of length '{1}' has no element at index '{2}'.": {
|
||||
"category": "Error",
|
||||
"code": 2493
|
||||
},
|
||||
@@ -1824,7 +1824,7 @@
|
||||
"category": "Error",
|
||||
"code": 2508
|
||||
},
|
||||
"Base constructor return type '{0}' is not a class or interface type.": {
|
||||
"Base constructor return type '{0}' is not an object type or intersection of object types with statically known members.": {
|
||||
"category": "Error",
|
||||
"code": 2509
|
||||
},
|
||||
@@ -1948,7 +1948,7 @@
|
||||
"category": "Error",
|
||||
"code": 2539
|
||||
},
|
||||
"Cannot assign to '{0}' because it is a constant or a read-only property.": {
|
||||
"Cannot assign to '{0}' because it is a read-only property.": {
|
||||
"category": "Error",
|
||||
"code": 2540
|
||||
},
|
||||
@@ -2128,6 +2128,10 @@
|
||||
"category": "Error",
|
||||
"code": 2587
|
||||
},
|
||||
"Cannot assign to '{0}' because it is a constant.": {
|
||||
"category": "Error",
|
||||
"code": 2588
|
||||
},
|
||||
"JSX element attributes type '{0}' may not be a union type.": {
|
||||
"category": "Error",
|
||||
"code": 2600
|
||||
@@ -2505,7 +2509,7 @@
|
||||
"category": "Error",
|
||||
"code": 2736
|
||||
},
|
||||
"BigInt literals are not available when targetting lower than ESNext.": {
|
||||
"BigInt literals are not available when targeting lower than ESNext.": {
|
||||
"category": "Error",
|
||||
"code": 2737
|
||||
},
|
||||
@@ -2513,6 +2517,30 @@
|
||||
"category": "Message",
|
||||
"code": 2738
|
||||
},
|
||||
"Type '{0}' is missing the following properties from type '{1}': {2}": {
|
||||
"category": "Error",
|
||||
"code": 2739
|
||||
},
|
||||
"Type '{0}' is missing the following properties from type '{1}': {2}, and {3} more.": {
|
||||
"category": "Error",
|
||||
"code": 2740
|
||||
},
|
||||
"Property '{0}' is missing in type '{1}' but required in type '{2}'.": {
|
||||
"category": "Error",
|
||||
"code": 2741
|
||||
},
|
||||
"The inferred type of '{0}' cannot be named without a reference to '{1}'. This is likely not portable. A type annotation is necessary.": {
|
||||
"category": "Error",
|
||||
"code": 2742
|
||||
},
|
||||
"No overload expects {0} type arguments, but overloads do exist that expect either {1} or {2} type arguments.": {
|
||||
"category": "Error",
|
||||
"code": 2743
|
||||
},
|
||||
"Type parameter defaults can only reference previously declared type parameters.": {
|
||||
"category": "Error",
|
||||
"code": 2744
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
@@ -3921,10 +3949,6 @@
|
||||
"category": "Error",
|
||||
"code": 6370
|
||||
},
|
||||
"Enables experimental support for ESNext BigInt literals.": {
|
||||
"category": "Message",
|
||||
"code": 6371
|
||||
},
|
||||
|
||||
"The expected type comes from property '{0}' which is declared here on type '{1}'": {
|
||||
"category": "Message",
|
||||
@@ -3967,6 +3991,10 @@
|
||||
"category": "Error",
|
||||
"code": 7013
|
||||
},
|
||||
"Function type, which lacks return-type annotation, implicitly has an '{0}' return type.": {
|
||||
"category": "Error",
|
||||
"code": 7014
|
||||
},
|
||||
"Element implicitly has an 'any' type because index expression is not of type 'number'.": {
|
||||
"category": "Error",
|
||||
"code": 7015
|
||||
@@ -4109,6 +4137,10 @@
|
||||
"category": "Suggestion",
|
||||
"code": 7050
|
||||
},
|
||||
"Parameter has a name but no type. Did you mean '{0}: {1}'?": {
|
||||
"category": "Error",
|
||||
"code": 7051
|
||||
},
|
||||
|
||||
"You cannot rename this element.": {
|
||||
"category": "Error",
|
||||
@@ -4492,6 +4524,10 @@
|
||||
"category": "Message",
|
||||
"code": 90033
|
||||
},
|
||||
"Add parameter name": {
|
||||
"category": "Message",
|
||||
"code": 90034
|
||||
},
|
||||
"Convert function to an ES2015 class": {
|
||||
"category": "Message",
|
||||
"code": 95001
|
||||
@@ -4732,7 +4768,6 @@
|
||||
"category": "Message",
|
||||
"code": 95062
|
||||
},
|
||||
|
||||
"Add missing enum member '{0}'": {
|
||||
"category": "Message",
|
||||
"code": 95063
|
||||
@@ -4764,5 +4799,17 @@
|
||||
"Add 'unknown' to all conversions of non-overlapping types": {
|
||||
"category": "Message",
|
||||
"code": 95070
|
||||
},
|
||||
"Add missing 'new' operator to call": {
|
||||
"category": "Message",
|
||||
"code": 95071
|
||||
},
|
||||
"Add missing 'new' operator to all calls": {
|
||||
"category": "Message",
|
||||
"code": 95072
|
||||
},
|
||||
"Add names to all parameters without names": {
|
||||
"category": "Message",
|
||||
"code": 95073
|
||||
}
|
||||
}
|
||||
|
||||
+18
-9
@@ -1651,11 +1651,17 @@ namespace ts {
|
||||
function emitPropertyAccessExpression(node: PropertyAccessExpression) {
|
||||
let indentBeforeDot = false;
|
||||
let indentAfterDot = false;
|
||||
const dotRangeFirstCommentStart = skipTrivia(
|
||||
currentSourceFile!.text,
|
||||
node.expression.end,
|
||||
/*stopAfterLineBreak*/ false,
|
||||
/*stopAtComments*/ true
|
||||
);
|
||||
const dotRangeStart = skipTrivia(currentSourceFile!.text, dotRangeFirstCommentStart);
|
||||
const dotRangeEnd = dotRangeStart + 1;
|
||||
if (!(getEmitFlags(node) & EmitFlags.NoIndentation)) {
|
||||
const dotRangeStart = node.expression.end;
|
||||
const dotRangeEnd = skipTrivia(currentSourceFile!.text, node.expression.end) + 1;
|
||||
const dotToken = createToken(SyntaxKind.DotToken);
|
||||
dotToken.pos = dotRangeStart;
|
||||
dotToken.pos = node.expression.end;
|
||||
dotToken.end = dotRangeEnd;
|
||||
indentBeforeDot = needsIndentation(node, node.expression, dotToken);
|
||||
indentAfterDot = needsIndentation(node, dotToken, node.name);
|
||||
@@ -1664,7 +1670,8 @@ namespace ts {
|
||||
emitExpression(node.expression);
|
||||
increaseIndentIf(indentBeforeDot, /*writeSpaceIfNotIndenting*/ false);
|
||||
|
||||
const shouldEmitDotDot = !indentBeforeDot && needsDotDotForPropertyAccess(node.expression);
|
||||
const dotHasCommentTrivia = dotRangeFirstCommentStart !== dotRangeStart;
|
||||
const shouldEmitDotDot = !indentBeforeDot && needsDotDotForPropertyAccess(node.expression, dotHasCommentTrivia);
|
||||
if (shouldEmitDotDot) {
|
||||
writePunctuation(".");
|
||||
}
|
||||
@@ -1677,13 +1684,15 @@ namespace ts {
|
||||
|
||||
// 1..toString is a valid property access, emit a dot after the literal
|
||||
// Also emit a dot if expression is a integer const enum value - it will appear in generated code as numeric literal
|
||||
function needsDotDotForPropertyAccess(expression: Expression) {
|
||||
function needsDotDotForPropertyAccess(expression: Expression, dotHasTrivia: boolean) {
|
||||
expression = skipPartiallyEmittedExpressions(expression);
|
||||
if (isNumericLiteral(expression)) {
|
||||
// check if numeric literal is a decimal literal that was originally written with a dot
|
||||
const text = getLiteralTextOfNode(<LiteralExpression>expression, /*neverAsciiEscape*/ true);
|
||||
return !expression.numericLiteralFlags
|
||||
&& !stringContains(text, tokenToString(SyntaxKind.DotToken)!);
|
||||
// If he number will be printed verbatim and it doesn't already contain a dot, add one
|
||||
// if the expression doesn't have any comments that will be emitted.
|
||||
return !expression.numericLiteralFlags && !stringContains(text, tokenToString(SyntaxKind.DotToken)!) &&
|
||||
(!dotHasTrivia || printerOptions.removeComments);
|
||||
}
|
||||
else if (isPropertyAccessExpression(expression) || isElementAccessExpression(expression)) {
|
||||
// check if constant enum value is integer
|
||||
@@ -1858,7 +1867,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function emitSpreadExpression(node: SpreadElement) {
|
||||
writePunctuation("...");
|
||||
emitTokenWithComment(SyntaxKind.DotDotDotToken, node.pos, writePunctuation, node);
|
||||
emitExpression(node.expression);
|
||||
}
|
||||
|
||||
@@ -2715,7 +2724,7 @@ namespace ts {
|
||||
|
||||
function emitSpreadAssignment(node: SpreadAssignment) {
|
||||
if (node.expression) {
|
||||
writePunctuation("...");
|
||||
emitTokenWithComment(SyntaxKind.DotDotDotToken, node.pos, writePunctuation, node);
|
||||
emitExpression(node.expression);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,18 +40,18 @@ namespace ts {
|
||||
|
||||
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 seen: unknown[] = [];
|
||||
const nameStack: string[] = [];
|
||||
return (obj, name, cbOk, cbFail) => {
|
||||
if (seen.has(obj) || nameStack.length > 4) {
|
||||
return cbFail(seen.has(obj), nameStack);
|
||||
if (seen.indexOf(obj) !== -1 || nameStack.length > 4) {
|
||||
return cbFail(seen.indexOf(obj) !== -1, nameStack);
|
||||
}
|
||||
|
||||
seen.add(obj);
|
||||
seen.push(obj);
|
||||
nameStack.push(name);
|
||||
const res = cbOk();
|
||||
nameStack.pop();
|
||||
seen.delete(obj);
|
||||
seen.pop();
|
||||
return res;
|
||||
};
|
||||
}
|
||||
@@ -104,8 +104,8 @@ namespace ts {
|
||||
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));
|
||||
const ignoredProperties: ReadonlyArray<string> = ["arguments", "caller", "constructor", "eval", "super_"];
|
||||
const reservedFunctionProperties: ReadonlyArray<string> = Object.getOwnPropertyNames(noop);
|
||||
interface ObjectEntry { readonly key: string; readonly value: unknown; }
|
||||
function getEntriesOfObject(obj: object): ReadonlyArray<ObjectEntry> {
|
||||
const seen = createMap<true>();
|
||||
@@ -114,8 +114,8 @@ namespace ts {
|
||||
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)) &&
|
||||
ignoredProperties.indexOf(key) === -1 &&
|
||||
(typeof obj !== "function" || reservedFunctionProperties.indexOf(key) === -1) &&
|
||||
// Don't add property from a higher prototype if it already exists in a lower one
|
||||
addToSeen(seen, key)) {
|
||||
const value = safeGetPropertyOfObject(chain, key);
|
||||
@@ -148,7 +148,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function isJsPrivate(name: string): boolean {
|
||||
return name.startsWith("_");
|
||||
return startsWith(name, "_");
|
||||
}
|
||||
|
||||
function tryRequire(fileNameToRequire: string): unknown {
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace ts.moduleSpecifiers {
|
||||
return isPathRelativeToParent(nonRelative) || countPathComponents(relativePath) < countPathComponents(nonRelative) ? relativePath : nonRelative;
|
||||
}
|
||||
|
||||
function countPathComponents(path: string): number {
|
||||
export function countPathComponents(path: string): number {
|
||||
let count = 0;
|
||||
for (let i = startsWith(path, "./") ? 2 : 0; i < path.length; i++) {
|
||||
if (path.charCodeAt(i) === CharacterCodes.slash) count++;
|
||||
@@ -203,7 +203,7 @@ namespace ts.moduleSpecifiers {
|
||||
return; // Don't want to a package to globally import from itself
|
||||
}
|
||||
|
||||
const target = targets.find(t => compareStrings(t.slice(0, resolved.length + 1), resolved + "/") === Comparison.EqualTo);
|
||||
const target = find(targets, t => compareStrings(t.slice(0, resolved.length + 1), resolved + "/") === Comparison.EqualTo);
|
||||
if (target === undefined) return;
|
||||
|
||||
const relative = getRelativePathFromDirectory(resolved, target, getCanonicalFileName);
|
||||
|
||||
+60
-62
@@ -462,52 +462,46 @@ namespace ts {
|
||||
return visitNodes(cbNode, cbNodes, (<JSDoc>node).tags);
|
||||
case SyntaxKind.JSDocParameterTag:
|
||||
case SyntaxKind.JSDocPropertyTag:
|
||||
if ((node as JSDocPropertyLikeTag).isNameFirst) {
|
||||
return visitNode(cbNode, (<JSDocPropertyLikeTag>node).name) ||
|
||||
visitNode(cbNode, (<JSDocPropertyLikeTag>node).typeExpression);
|
||||
}
|
||||
else {
|
||||
return visitNode(cbNode, (<JSDocPropertyLikeTag>node).typeExpression) ||
|
||||
visitNode(cbNode, (<JSDocPropertyLikeTag>node).name);
|
||||
}
|
||||
case SyntaxKind.JSDocReturnTag:
|
||||
return visitNode(cbNode, (<JSDocReturnTag>node).typeExpression);
|
||||
case SyntaxKind.JSDocTypeTag:
|
||||
return visitNode(cbNode, (<JSDocTypeTag>node).typeExpression);
|
||||
return visitNode(cbNode, (node as JSDocTag).tagName) ||
|
||||
((node as JSDocPropertyLikeTag).isNameFirst
|
||||
? visitNode(cbNode, (<JSDocPropertyLikeTag>node).name) ||
|
||||
visitNode(cbNode, (<JSDocPropertyLikeTag>node).typeExpression)
|
||||
: visitNode(cbNode, (<JSDocPropertyLikeTag>node).typeExpression) ||
|
||||
visitNode(cbNode, (<JSDocPropertyLikeTag>node).name));
|
||||
case SyntaxKind.JSDocAugmentsTag:
|
||||
return visitNode(cbNode, (<JSDocAugmentsTag>node).class);
|
||||
return visitNode(cbNode, (node as JSDocTag).tagName) ||
|
||||
visitNode(cbNode, (<JSDocAugmentsTag>node).class);
|
||||
case SyntaxKind.JSDocTemplateTag:
|
||||
return visitNode(cbNode, (<JSDocTemplateTag>node).constraint) || visitNodes(cbNode, cbNodes, (<JSDocTemplateTag>node).typeParameters);
|
||||
return visitNode(cbNode, (node as JSDocTag).tagName) ||
|
||||
visitNode(cbNode, (<JSDocTemplateTag>node).constraint) ||
|
||||
visitNodes(cbNode, cbNodes, (<JSDocTemplateTag>node).typeParameters);
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
if ((node as JSDocTypedefTag).typeExpression &&
|
||||
(node as JSDocTypedefTag).typeExpression!.kind === SyntaxKind.JSDocTypeExpression) {
|
||||
return visitNode(cbNode, (<JSDocTypedefTag>node).typeExpression) ||
|
||||
visitNode(cbNode, (<JSDocTypedefTag>node).fullName);
|
||||
}
|
||||
else {
|
||||
return visitNode(cbNode, (<JSDocTypedefTag>node).fullName) ||
|
||||
visitNode(cbNode, (<JSDocTypedefTag>node).typeExpression);
|
||||
}
|
||||
return visitNode(cbNode, (node as JSDocTag).tagName) ||
|
||||
((node as JSDocTypedefTag).typeExpression &&
|
||||
(node as JSDocTypedefTag).typeExpression!.kind === SyntaxKind.JSDocTypeExpression
|
||||
? visitNode(cbNode, (<JSDocTypedefTag>node).typeExpression) ||
|
||||
visitNode(cbNode, (<JSDocTypedefTag>node).fullName)
|
||||
: visitNode(cbNode, (<JSDocTypedefTag>node).fullName) ||
|
||||
visitNode(cbNode, (<JSDocTypedefTag>node).typeExpression));
|
||||
case SyntaxKind.JSDocCallbackTag:
|
||||
return visitNode(cbNode, (node as JSDocCallbackTag).fullName) ||
|
||||
return visitNode(cbNode, (node as JSDocTag).tagName) ||
|
||||
visitNode(cbNode, (node as JSDocCallbackTag).fullName) ||
|
||||
visitNode(cbNode, (node as JSDocCallbackTag).typeExpression);
|
||||
case SyntaxKind.JSDocReturnTag:
|
||||
case SyntaxKind.JSDocTypeTag:
|
||||
case SyntaxKind.JSDocThisTag:
|
||||
return visitNode(cbNode, (node as JSDocThisTag).typeExpression);
|
||||
case SyntaxKind.JSDocEnumTag:
|
||||
return visitNode(cbNode, (node as JSDocEnumTag).typeExpression);
|
||||
return visitNode(cbNode, (node as JSDocTag).tagName) ||
|
||||
visitNode(cbNode, (node as JSDocReturnTag | JSDocTypeTag | JSDocThisTag | JSDocEnumTag).typeExpression);
|
||||
case SyntaxKind.JSDocSignature:
|
||||
return visitNodes(cbNode, cbNodes, node.decorators) ||
|
||||
visitNodes(cbNode, cbNodes, node.modifiers) ||
|
||||
forEach((<JSDocSignature>node).typeParameters, cbNode) ||
|
||||
return forEach((<JSDocSignature>node).typeParameters, cbNode) ||
|
||||
forEach((<JSDocSignature>node).parameters, cbNode) ||
|
||||
visitNode(cbNode, (<JSDocSignature>node).type);
|
||||
case SyntaxKind.JSDocTypeLiteral:
|
||||
if ((node as JSDocTypeLiteral).jsDocPropertyTags) {
|
||||
for (const tag of (node as JSDocTypeLiteral).jsDocPropertyTags!) {
|
||||
visitNode(cbNode, tag);
|
||||
}
|
||||
}
|
||||
return;
|
||||
return forEach((node as JSDocTypeLiteral).jsDocPropertyTags, cbNode);
|
||||
case SyntaxKind.JSDocTag:
|
||||
case SyntaxKind.JSDocClassTag:
|
||||
return visitNode(cbNode, (node as JSDocTag).tagName);
|
||||
case SyntaxKind.PartiallyEmittedExpression:
|
||||
return visitNode(cbNode, (<PartiallyEmittedExpression>node).expression);
|
||||
}
|
||||
@@ -1723,6 +1717,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function currentNode(parsingContext: ParsingContext): Node | undefined {
|
||||
// If we don't have a cursor or the parsing context isn't reusable, there's nothing to reuse.
|
||||
//
|
||||
// If there is an outstanding parse error that we've encountered, but not attached to
|
||||
// some node, then we cannot get a node from the old source tree. This is because we
|
||||
// want to mark the next node we encounter as being unusable.
|
||||
@@ -1730,30 +1726,17 @@ namespace ts {
|
||||
// Note: This may be too conservative. Perhaps we could reuse the node and set the bit
|
||||
// on it (or its leftmost child) as having the error. For now though, being conservative
|
||||
// is nice and likely won't ever affect perf.
|
||||
if (parseErrorBeforeNextFinishedNode) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (!syntaxCursor) {
|
||||
// if we don't have a cursor, we could never return a node from the old tree.
|
||||
if (!syntaxCursor || !isReusableParsingContext(parsingContext) || parseErrorBeforeNextFinishedNode) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const node = syntaxCursor.currentNode(scanner.getStartPos());
|
||||
|
||||
// Can't reuse a missing node.
|
||||
if (nodeIsMissing(node)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Can't reuse a node that intersected the change range.
|
||||
if (node.intersectsChange) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Can't reuse a node that contains a parse error. This is necessary so that we
|
||||
// produce the same set of errors again.
|
||||
if (containsParseError(node)) {
|
||||
if (nodeIsMissing(node) || node.intersectsChange || containsParseError(node)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -1794,6 +1777,23 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
function isReusableParsingContext(parsingContext: ParsingContext): boolean {
|
||||
switch (parsingContext) {
|
||||
case ParsingContext.ClassMembers:
|
||||
case ParsingContext.SwitchClauses:
|
||||
case ParsingContext.SourceElements:
|
||||
case ParsingContext.BlockStatements:
|
||||
case ParsingContext.SwitchClauseStatements:
|
||||
case ParsingContext.EnumMembers:
|
||||
case ParsingContext.TypeMembers:
|
||||
case ParsingContext.VariableDeclarations:
|
||||
case ParsingContext.JSDocParameters:
|
||||
case ParsingContext.Parameters:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function canReuseNode(node: Node, parsingContext: ParsingContext): boolean {
|
||||
switch (parsingContext) {
|
||||
case ParsingContext.ClassMembers:
|
||||
@@ -1820,25 +1820,23 @@ namespace ts {
|
||||
case ParsingContext.Parameters:
|
||||
return isReusableParameter(node);
|
||||
|
||||
case ParsingContext.RestProperties:
|
||||
return false;
|
||||
|
||||
// Any other lists we do not care about reusing nodes in. But feel free to add if
|
||||
// you can do so safely. Danger areas involve nodes that may involve speculative
|
||||
// parsing. If speculative parsing is involved with the node, then the range the
|
||||
// parser reached while looking ahead might be in the edited range (see the example
|
||||
// in canReuseVariableDeclaratorNode for a good case of this).
|
||||
case ParsingContext.HeritageClauses:
|
||||
|
||||
// case ParsingContext.HeritageClauses:
|
||||
// This would probably be safe to reuse. There is no speculative parsing with
|
||||
// heritage clauses.
|
||||
|
||||
case ParsingContext.TypeParameters:
|
||||
// case ParsingContext.TypeParameters:
|
||||
// This would probably be safe to reuse. There is no speculative parsing with
|
||||
// type parameters. Note that that's because type *parameters* only occur in
|
||||
// unambiguous *type* contexts. While type *arguments* occur in very ambiguous
|
||||
// *expression* contexts.
|
||||
|
||||
case ParsingContext.TupleElementTypes:
|
||||
// case ParsingContext.TupleElementTypes:
|
||||
// This would probably be safe to reuse. There is no speculative parsing with
|
||||
// tuple types.
|
||||
|
||||
@@ -1847,28 +1845,28 @@ namespace ts {
|
||||
// produced from speculative parsing a < as a type argument list), we only have
|
||||
// the types because speculative parsing succeeded. Thus, the lookahead never
|
||||
// went past the end of the list and rewound.
|
||||
case ParsingContext.TypeArguments:
|
||||
// case ParsingContext.TypeArguments:
|
||||
|
||||
// Note: these are almost certainly not safe to ever reuse. Expressions commonly
|
||||
// need a large amount of lookahead, and we should not reuse them as they may
|
||||
// have actually intersected the edit.
|
||||
case ParsingContext.ArgumentExpressions:
|
||||
// case ParsingContext.ArgumentExpressions:
|
||||
|
||||
// This is not safe to reuse for the same reason as the 'AssignmentExpression'
|
||||
// cases. i.e. a property assignment may end with an expression, and thus might
|
||||
// have lookahead far beyond it's old node.
|
||||
case ParsingContext.ObjectLiteralMembers:
|
||||
// case ParsingContext.ObjectLiteralMembers:
|
||||
|
||||
// This is probably not safe to reuse. There can be speculative parsing with
|
||||
// type names in a heritage clause. There can be generic names in the type
|
||||
// name list, and there can be left hand side expressions (which can have type
|
||||
// arguments.)
|
||||
case ParsingContext.HeritageClauseElement:
|
||||
// case ParsingContext.HeritageClauseElement:
|
||||
|
||||
// Perhaps safe to reuse, but it's unlikely we'd see more than a dozen attributes
|
||||
// on any given element. Same for children.
|
||||
case ParsingContext.JsxAttributes:
|
||||
case ParsingContext.JsxChildren:
|
||||
// case ParsingContext.JsxAttributes:
|
||||
// case ParsingContext.JsxChildren:
|
||||
|
||||
}
|
||||
|
||||
|
||||
+148
-22
@@ -73,7 +73,6 @@ namespace ts {
|
||||
// TODO(shkamat): update this after reworking ts build API
|
||||
export function createCompilerHostWorker(options: CompilerOptions, setParentNodes?: boolean, system = sys): CompilerHost {
|
||||
const existingDirectories = createMap<boolean>();
|
||||
|
||||
function getCanonicalFileName(fileName: string): string {
|
||||
// if underlying system can distinguish between two files whose names differs only in cases then file name already in canonical form.
|
||||
// otherwise use toLowerCase as a canonical form.
|
||||
@@ -84,7 +83,7 @@ namespace ts {
|
||||
let text: string | undefined;
|
||||
try {
|
||||
performance.mark("beforeIORead");
|
||||
text = system.readFile(fileName, options.charset);
|
||||
text = compilerHost.readFile(fileName);
|
||||
performance.mark("afterIORead");
|
||||
performance.measure("I/O Read", "beforeIORead", "afterIORead");
|
||||
}
|
||||
@@ -113,7 +112,12 @@ namespace ts {
|
||||
if (directoryPath.length > getRootLength(directoryPath) && !directoryExists(directoryPath)) {
|
||||
const parentDirectory = getDirectoryPath(directoryPath);
|
||||
ensureDirectoriesExist(parentDirectory);
|
||||
system.createDirectory(directoryPath);
|
||||
if (compilerHost.createDirectory) {
|
||||
compilerHost.createDirectory(directoryPath);
|
||||
}
|
||||
else {
|
||||
system.createDirectory(directoryPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,8 +181,7 @@ namespace ts {
|
||||
|
||||
const newLine = getNewLineCharacter(options, () => system.newLine);
|
||||
const realpath = system.realpath && ((path: string) => system.realpath!(path));
|
||||
|
||||
return {
|
||||
const compilerHost: CompilerHost = {
|
||||
getSourceFile,
|
||||
getDefaultLibLocation,
|
||||
getDefaultLibFileName: options => combinePaths(getDefaultLibLocation(), getDefaultLibFileName(options)),
|
||||
@@ -194,7 +197,117 @@ namespace ts {
|
||||
getEnvironmentVariable: name => system.getEnvironmentVariable ? system.getEnvironmentVariable(name) : "",
|
||||
getDirectories: (path: string) => system.getDirectories(path),
|
||||
realpath,
|
||||
readDirectory: (path, extensions, include, exclude, depth) => system.readDirectory(path, extensions, include, exclude, depth)
|
||||
readDirectory: (path, extensions, include, exclude, depth) => system.readDirectory(path, extensions, include, exclude, depth),
|
||||
createDirectory: d => system.createDirectory(d)
|
||||
};
|
||||
return compilerHost;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function changeCompilerHostToUseCache(
|
||||
host: CompilerHost,
|
||||
toPath: (fileName: string) => Path,
|
||||
useCacheForSourceFile: boolean
|
||||
) {
|
||||
const originalReadFile = host.readFile;
|
||||
const originalFileExists = host.fileExists;
|
||||
const originalDirectoryExists = host.directoryExists;
|
||||
const originalCreateDirectory = host.createDirectory;
|
||||
const originalWriteFile = host.writeFile;
|
||||
const originalGetSourceFile = host.getSourceFile;
|
||||
const readFileCache = createMap<string | false>();
|
||||
const fileExistsCache = createMap<boolean>();
|
||||
const directoryExistsCache = createMap<boolean>();
|
||||
const sourceFileCache = createMap<SourceFile>();
|
||||
|
||||
const readFileWithCache = (fileName: string): string | undefined => {
|
||||
const key = toPath(fileName);
|
||||
const value = readFileCache.get(key);
|
||||
if (value !== undefined) return value || undefined;
|
||||
return setReadFileCache(key, fileName);
|
||||
};
|
||||
const setReadFileCache = (key: Path, fileName: string) => {
|
||||
const newValue = originalReadFile.call(host, fileName);
|
||||
readFileCache.set(key, newValue || false);
|
||||
return newValue;
|
||||
};
|
||||
host.readFile = fileName => {
|
||||
const key = toPath(fileName);
|
||||
const value = readFileCache.get(key);
|
||||
if (value !== undefined) return value; // could be .d.ts from output
|
||||
if (!fileExtensionIs(fileName, Extension.Json)) {
|
||||
return originalReadFile.call(host, fileName);
|
||||
}
|
||||
|
||||
return setReadFileCache(key, fileName);
|
||||
};
|
||||
|
||||
if (useCacheForSourceFile) {
|
||||
host.getSourceFile = (fileName, languageVersion, onError, shouldCreateNewSourceFile) => {
|
||||
const key = toPath(fileName);
|
||||
const value = sourceFileCache.get(key);
|
||||
if (value) return value;
|
||||
|
||||
const sourceFile = originalGetSourceFile.call(host, fileName, languageVersion, onError, shouldCreateNewSourceFile);
|
||||
if (sourceFile && (isDeclarationFileName(fileName) || fileExtensionIs(fileName, Extension.Json))) {
|
||||
sourceFileCache.set(key, sourceFile);
|
||||
}
|
||||
return sourceFile;
|
||||
};
|
||||
}
|
||||
|
||||
// fileExists for any kind of extension
|
||||
host.fileExists = fileName => {
|
||||
const key = toPath(fileName);
|
||||
const value = fileExistsCache.get(key);
|
||||
if (value !== undefined) return value;
|
||||
const newValue = originalFileExists.call(host, fileName);
|
||||
fileExistsCache.set(key, !!newValue);
|
||||
return newValue;
|
||||
};
|
||||
host.writeFile = (fileName, data, writeByteOrderMark, onError, sourceFiles) => {
|
||||
const key = toPath(fileName);
|
||||
fileExistsCache.delete(key);
|
||||
|
||||
const value = readFileCache.get(key);
|
||||
if (value && value !== data) {
|
||||
readFileCache.delete(key);
|
||||
sourceFileCache.delete(key);
|
||||
}
|
||||
else if (useCacheForSourceFile) {
|
||||
const sourceFile = sourceFileCache.get(key);
|
||||
if (sourceFile && sourceFile.text !== data) {
|
||||
sourceFileCache.delete(key);
|
||||
}
|
||||
}
|
||||
originalWriteFile.call(host, fileName, data, writeByteOrderMark, onError, sourceFiles);
|
||||
};
|
||||
|
||||
// directoryExists
|
||||
if (originalDirectoryExists && originalCreateDirectory) {
|
||||
host.directoryExists = directory => {
|
||||
const key = toPath(directory);
|
||||
const value = directoryExistsCache.get(key);
|
||||
if (value !== undefined) return value;
|
||||
const newValue = originalDirectoryExists.call(host, directory);
|
||||
directoryExistsCache.set(key, !!newValue);
|
||||
return newValue;
|
||||
};
|
||||
host.createDirectory = directory => {
|
||||
const key = toPath(directory);
|
||||
directoryExistsCache.delete(key);
|
||||
originalCreateDirectory.call(host, directory);
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
originalReadFile,
|
||||
originalFileExists,
|
||||
originalDirectoryExists,
|
||||
originalCreateDirectory,
|
||||
originalWriteFile,
|
||||
originalGetSourceFile,
|
||||
readFileWithCache
|
||||
};
|
||||
}
|
||||
|
||||
@@ -674,7 +787,13 @@ namespace ts {
|
||||
// Key is a file name. Value is the (non-empty, or undefined) list of files that redirect to it.
|
||||
let redirectTargetsMap = createMultiMap<string>();
|
||||
|
||||
const filesByName = createMap<SourceFile | undefined>();
|
||||
/**
|
||||
* map with
|
||||
* - SourceFile if present
|
||||
* - false if sourceFile missing for source of project reference redirect
|
||||
* - undefined otherwise
|
||||
*/
|
||||
const filesByName = createMap<SourceFile | false | undefined>();
|
||||
let missingFilePaths: ReadonlyArray<Path> | undefined;
|
||||
// stores 'filename -> file association' ignoring case
|
||||
// used to track cases when two file names differ only in casing
|
||||
@@ -683,6 +802,7 @@ namespace ts {
|
||||
// A parallel array to projectReferences storing the results of reading in the referenced tsconfig files
|
||||
let resolvedProjectReferences: ReadonlyArray<ResolvedProjectReference | undefined> | undefined;
|
||||
let projectReferenceRedirects: Map<ResolvedProjectReference | false> | undefined;
|
||||
let mapFromFileToProjectReferenceRedirects: Map<Path> | undefined;
|
||||
|
||||
const shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options);
|
||||
const structuralIsReused = tryReuseStructureFromOldProgram();
|
||||
@@ -740,7 +860,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
missingFilePaths = arrayFrom(filesByName.keys(), p => <Path>p).filter(p => !filesByName.get(p));
|
||||
missingFilePaths = arrayFrom(mapDefinedIterator(filesByName.entries(), ([path, file]) => file === undefined ? path as Path : undefined));
|
||||
files = stableSort(processingDefaultLibFiles, compareDefaultLibFiles).concat(processingOtherFiles);
|
||||
processingDefaultLibFiles = undefined;
|
||||
processingOtherFiles = undefined;
|
||||
@@ -1453,7 +1573,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getSourceFileByPath(path: Path): SourceFile | undefined {
|
||||
return filesByName.get(path);
|
||||
return filesByName.get(path) || undefined;
|
||||
}
|
||||
|
||||
function getDiagnosticsHelper<T extends Diagnostic>(
|
||||
@@ -1990,7 +2110,7 @@ namespace ts {
|
||||
|
||||
/** This should have similar behavior to 'processSourceFile' without diagnostics or mutation. */
|
||||
function getSourceFileFromReference(referencingFile: SourceFile, ref: FileReference): SourceFile | undefined {
|
||||
return getSourceFileFromReferenceWorker(resolveTripleslashReference(ref.fileName, referencingFile.fileName), fileName => filesByName.get(toPath(fileName)));
|
||||
return getSourceFileFromReferenceWorker(resolveTripleslashReference(ref.fileName, referencingFile.fileName), fileName => filesByName.get(toPath(fileName)) || undefined);
|
||||
}
|
||||
|
||||
function getSourceFileFromReferenceWorker(
|
||||
@@ -2121,7 +2241,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
return file;
|
||||
return file || undefined;
|
||||
}
|
||||
|
||||
let redirectedPath: Path | undefined;
|
||||
@@ -2213,9 +2333,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
function addFileToFilesByName(file: SourceFile | undefined, path: Path, redirectedPath: Path | undefined) {
|
||||
filesByName.set(path, file);
|
||||
if (redirectedPath) {
|
||||
filesByName.set(redirectedPath, file);
|
||||
filesByName.set(path, file || false);
|
||||
}
|
||||
else {
|
||||
filesByName.set(path, file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2231,7 +2354,6 @@ namespace ts {
|
||||
if (!referencedProject) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const out = referencedProject.commandLine.options.outFile || referencedProject.commandLine.options.out;
|
||||
return out ?
|
||||
changeExtension(out, Extension.Dts) :
|
||||
@@ -2242,16 +2364,20 @@ namespace ts {
|
||||
* 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 (mapFromFileToProjectReferenceRedirects === undefined) {
|
||||
mapFromFileToProjectReferenceRedirects = createMap();
|
||||
forEachResolvedProjectReference((referencedProject, referenceProjectPath) => {
|
||||
// not input file from the referenced project, ignore
|
||||
if (referencedProject &&
|
||||
toPath(options.configFilePath!) !== referenceProjectPath) {
|
||||
referencedProject.commandLine.fileNames.forEach(f =>
|
||||
mapFromFileToProjectReferenceRedirects!.set(toPath(f), referenceProjectPath));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return referencedProject;
|
||||
});
|
||||
const referencedProjectPath = mapFromFileToProjectReferenceRedirects.get(toPath(fileName));
|
||||
return referencedProjectPath && getResolvedProjectReferenceByPath(referencedProjectPath);
|
||||
}
|
||||
|
||||
function forEachResolvedProjectReference<T>(
|
||||
|
||||
+47
-4
@@ -337,17 +337,35 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: number, character: number): number {
|
||||
return computePositionOfLineAndCharacter(getLineStarts(sourceFile), line, character, sourceFile.text);
|
||||
export function getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: number, character: number): number;
|
||||
/* @internal */
|
||||
// tslint:disable-next-line:unified-signatures
|
||||
export function getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: number, character: number, allowEdits?: true): number;
|
||||
export function getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: number, character: number, allowEdits?: true): number {
|
||||
return sourceFile.getPositionOfLineAndCharacter ?
|
||||
sourceFile.getPositionOfLineAndCharacter(line, character, allowEdits) :
|
||||
computePositionOfLineAndCharacter(getLineStarts(sourceFile), line, character, sourceFile.text, allowEdits);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function computePositionOfLineAndCharacter(lineStarts: ReadonlyArray<number>, line: number, character: number, debugText?: string): number {
|
||||
export function computePositionOfLineAndCharacter(lineStarts: ReadonlyArray<number>, line: number, character: number, debugText?: string, allowEdits?: true): number {
|
||||
if (line < 0 || line >= lineStarts.length) {
|
||||
Debug.fail(`Bad line number. Line: ${line}, lineStarts.length: ${lineStarts.length} , line map is correct? ${debugText !== undefined ? arraysEqual(lineStarts, computeLineStarts(debugText)) : "unknown"}`);
|
||||
if (allowEdits) {
|
||||
// Clamp line to nearest allowable value
|
||||
line = line < 0 ? 0 : line >= lineStarts.length ? lineStarts.length - 1 : line;
|
||||
}
|
||||
else {
|
||||
Debug.fail(`Bad line number. Line: ${line}, lineStarts.length: ${lineStarts.length} , line map is correct? ${debugText !== undefined ? arraysEqual(lineStarts, computeLineStarts(debugText)) : "unknown"}`);
|
||||
}
|
||||
}
|
||||
|
||||
const res = lineStarts[line] + character;
|
||||
if (allowEdits) {
|
||||
// Clamp to nearest allowable values to allow the underlying to be edited without crashing (accuracy is lost, instead)
|
||||
// TODO: Somehow track edits between file as it was during the creation of sourcemap we have and the current file and
|
||||
// apply them to the computed position to improve accuracy
|
||||
return res > lineStarts[line + 1] ? lineStarts[line + 1] : typeof debugText === "string" && res > debugText.length ? debugText.length : res;
|
||||
}
|
||||
if (line < lineStarts.length - 1) {
|
||||
Debug.assert(res < lineStarts[line + 1]);
|
||||
}
|
||||
@@ -967,7 +985,9 @@ namespace ts {
|
||||
else {
|
||||
result = text.substring(start, end); // No need to use all the fragments; no _ removal needed
|
||||
}
|
||||
|
||||
if (decimalFragment !== undefined || tokenFlags & TokenFlags.Scientific) {
|
||||
checkForIdentifierStartAfterNumericLiteral(start, decimalFragment === undefined && !!(tokenFlags & TokenFlags.Scientific));
|
||||
return {
|
||||
type: SyntaxKind.NumericLiteral,
|
||||
value: "" + +result // if value is not an integer, it can be safely coerced to a number
|
||||
@@ -976,10 +996,33 @@ namespace ts {
|
||||
else {
|
||||
tokenValue = result;
|
||||
const type = checkBigIntSuffix(); // if value is an integer, check whether it is a bigint
|
||||
checkForIdentifierStartAfterNumericLiteral(start);
|
||||
return { type, value: tokenValue };
|
||||
}
|
||||
}
|
||||
|
||||
function checkForIdentifierStartAfterNumericLiteral(numericStart: number, isScientific?: boolean) {
|
||||
if (!isIdentifierStart(text.charCodeAt(pos), languageVersion)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const identifierStart = pos;
|
||||
const { length } = scanIdentifierParts();
|
||||
|
||||
if (length === 1 && text[identifierStart] === "n") {
|
||||
if (isScientific) {
|
||||
error(Diagnostics.A_bigint_literal_cannot_use_exponential_notation, numericStart, identifierStart - numericStart + 1);
|
||||
}
|
||||
else {
|
||||
error(Diagnostics.A_bigint_literal_must_be_an_integer, numericStart, identifierStart - numericStart + 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
error(Diagnostics.An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal, identifierStart, length);
|
||||
pos = identifierStart;
|
||||
}
|
||||
}
|
||||
|
||||
function scanOctalDigits(): number {
|
||||
const start = pos;
|
||||
while (isOctalDigit(text.charCodeAt(pos))) {
|
||||
|
||||
+24
-14
@@ -266,14 +266,24 @@ namespace ts {
|
||||
const sourceMapCommentRegExp = /^\/\/[@#] source[M]appingURL=(.+)\s*$/;
|
||||
const whitespaceOrMapCommentRegExp = /^\s*(\/\/[@#] .*)?$/;
|
||||
|
||||
export interface LineInfo {
|
||||
getLineCount(): number;
|
||||
getLineText(line: number): string;
|
||||
}
|
||||
|
||||
export function getLineInfo(text: string, lineStarts: ReadonlyArray<number>): LineInfo {
|
||||
return {
|
||||
getLineCount: () => lineStarts.length,
|
||||
getLineText: line => text.substring(lineStarts[line], lineStarts[line + 1])
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to find the sourceMappingURL comment at the end of a file.
|
||||
* @param text The source text of the file.
|
||||
* @param lineStarts The line starts of the file.
|
||||
*/
|
||||
export function tryGetSourceMappingURL(text: string, lineStarts: ReadonlyArray<number> = computeLineStarts(text)) {
|
||||
for (let index = lineStarts.length - 1; index >= 0; index--) {
|
||||
const line = text.substring(lineStarts[index], lineStarts[index + 1]);
|
||||
export function tryGetSourceMappingURL(lineInfo: LineInfo) {
|
||||
for (let index = lineInfo.getLineCount() - 1; index >= 0; index--) {
|
||||
const line = lineInfo.getLineText(index);
|
||||
const comment = sourceMapCommentRegExp.exec(line);
|
||||
if (comment) {
|
||||
return comment[1];
|
||||
@@ -573,7 +583,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
function compareSourcePositions(left: SourceMappedPosition, right: SourceMappedPosition) {
|
||||
return compareValues(left.sourceIndex, right.sourceIndex);
|
||||
// Compares sourcePosition without comparing sourceIndex
|
||||
// since the mappings are grouped by sourceIndex
|
||||
Debug.assert(left.sourceIndex === right.sourceIndex);
|
||||
return compareValues(left.sourcePosition, right.sourcePosition);
|
||||
}
|
||||
|
||||
function compareGeneratedPositions(left: MappedPosition, right: MappedPosition) {
|
||||
@@ -592,11 +605,9 @@ namespace ts {
|
||||
const mapDirectory = getDirectoryPath(mapPath);
|
||||
const sourceRoot = map.sourceRoot ? getNormalizedAbsolutePath(map.sourceRoot, mapDirectory) : mapDirectory;
|
||||
const generatedAbsoluteFilePath = getNormalizedAbsolutePath(map.file, mapDirectory);
|
||||
const generatedCanonicalFilePath = host.getCanonicalFileName(generatedAbsoluteFilePath) as Path;
|
||||
const generatedFile = host.getSourceFileLike(generatedCanonicalFilePath);
|
||||
const generatedFile = host.getSourceFileLike(generatedAbsoluteFilePath);
|
||||
const sourceFileAbsolutePaths = map.sources.map(source => getNormalizedAbsolutePath(source, sourceRoot));
|
||||
const sourceFileCanonicalPaths = sourceFileAbsolutePaths.map(source => host.getCanonicalFileName(source) as Path);
|
||||
const sourceToSourceIndexMap = createMapFromEntries(sourceFileCanonicalPaths.map((source, i) => [source, i] as [string, number]));
|
||||
const sourceToSourceIndexMap = createMapFromEntries(sourceFileAbsolutePaths.map((source, i) => [host.getCanonicalFileName(source), i] as [string, number]));
|
||||
let decodedMappings: ReadonlyArray<MappedPosition> | undefined;
|
||||
let generatedMappings: SortedReadonlyArray<MappedPosition> | undefined;
|
||||
let sourceMappings: ReadonlyArray<SortedReadonlyArray<SourceMappedPosition>> | undefined;
|
||||
@@ -608,16 +619,15 @@ namespace ts {
|
||||
|
||||
function processMapping(mapping: Mapping): MappedPosition {
|
||||
const generatedPosition = generatedFile !== undefined
|
||||
? getPositionOfLineAndCharacter(generatedFile, mapping.generatedLine, mapping.generatedCharacter)
|
||||
? getPositionOfLineAndCharacter(generatedFile, mapping.generatedLine, mapping.generatedCharacter, /*allowEdits*/ true)
|
||||
: -1;
|
||||
let source: string | undefined;
|
||||
let sourcePosition: number | undefined;
|
||||
if (isSourceMapping(mapping)) {
|
||||
const sourceFilePath = sourceFileCanonicalPaths[mapping.sourceIndex];
|
||||
const sourceFile = host.getSourceFileLike(sourceFilePath);
|
||||
const sourceFile = host.getSourceFileLike(sourceFileAbsolutePaths[mapping.sourceIndex]);
|
||||
source = map.sources[mapping.sourceIndex];
|
||||
sourcePosition = sourceFile !== undefined
|
||||
? getPositionOfLineAndCharacter(sourceFile, mapping.sourceLine, mapping.sourceCharacter)
|
||||
? getPositionOfLineAndCharacter(sourceFile, mapping.sourceLine, mapping.sourceCharacter, /*allowEdits*/ true)
|
||||
: -1;
|
||||
}
|
||||
return {
|
||||
|
||||
@@ -45,6 +45,7 @@ namespace ts {
|
||||
reportInaccessibleThisError,
|
||||
reportInaccessibleUniqueSymbolError,
|
||||
reportPrivateInBaseOfClassExpression,
|
||||
reportLikelyUnsafeImportRequiredError,
|
||||
moduleResolverHost: host,
|
||||
trackReferencedAmbientModule,
|
||||
trackExternalModuleSymbolOfImportTypeNode
|
||||
@@ -153,6 +154,14 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function reportLikelyUnsafeImportRequiredError(specifier: string) {
|
||||
if (errorNameNode) {
|
||||
context.addDiagnostic(createDiagnosticForNode(errorNameNode, Diagnostics.The_inferred_type_of_0_cannot_be_named_without_a_reference_to_1_This_is_likely_not_portable_A_type_annotation_is_necessary,
|
||||
declarationNameToString(errorNameNode),
|
||||
specifier));
|
||||
}
|
||||
}
|
||||
|
||||
function transformRoot(node: Bundle): Bundle;
|
||||
function transformRoot(node: SourceFile): SourceFile;
|
||||
function transformRoot(node: SourceFile | Bundle): SourceFile | Bundle;
|
||||
@@ -1091,7 +1100,8 @@ namespace ts {
|
||||
if (extendsClause && !isEntityNameExpression(extendsClause.expression) && extendsClause.expression.kind !== SyntaxKind.NullKeyword) {
|
||||
// We must add a temporary declaration for the extends clause expression
|
||||
|
||||
const newId = createOptimisticUniqueName(`${unescapeLeadingUnderscores(input.name!.escapedText)}_base`); // TODO: GH#18217
|
||||
const oldId = input.name ? unescapeLeadingUnderscores(input.name.escapedText) : "default";
|
||||
const newId = createOptimisticUniqueName(`${oldId}_base`);
|
||||
getSymbolAccessibilityDiagnostic = () => ({
|
||||
diagnosticMessage: Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1,
|
||||
errorNode: extendsClause,
|
||||
|
||||
@@ -389,6 +389,7 @@ namespace ts {
|
||||
diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1;
|
||||
break;
|
||||
|
||||
case SyntaxKind.ConstructorType:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
diagnosticMessage = Diagnostics.Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
|
||||
break;
|
||||
@@ -410,6 +411,7 @@ namespace ts {
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_function_has_or_is_using_private_name_1;
|
||||
break;
|
||||
|
||||
+52
-18
@@ -32,6 +32,8 @@ namespace ts {
|
||||
pretty?: boolean;
|
||||
|
||||
traceResolution?: boolean;
|
||||
/* @internal */ diagnostics?: boolean;
|
||||
/* @internal */ extendedDiagnostics?: boolean;
|
||||
}
|
||||
|
||||
enum BuildResultFlags {
|
||||
@@ -326,6 +328,11 @@ namespace ts {
|
||||
|
||||
reportDiagnostic: DiagnosticReporter; // Technically we want to move it out and allow steps of actions on Solution, but for now just merge stuff in build host here
|
||||
reportSolutionBuilderStatus: DiagnosticReporter;
|
||||
|
||||
// TODO: To do better with watch mode and normal build mode api that creates program and emits files
|
||||
// This currently helps enable --diagnostics and --extendedDiagnostics
|
||||
beforeCreateProgram?(options: CompilerOptions): void;
|
||||
afterProgramEmitAndDiagnostics?(program: Program): void;
|
||||
}
|
||||
|
||||
export interface SolutionBuilderHost extends SolutionBuilderHostBase {
|
||||
@@ -426,6 +433,7 @@ namespace ts {
|
||||
const missingRoots = createMap<true>();
|
||||
let globalDependencyGraph: DependencyGraph | undefined;
|
||||
const writeFileName = (s: string) => host.trace && host.trace(s);
|
||||
let readFileWithCache = (f: string) => host.readFile(f);
|
||||
|
||||
// Watch state
|
||||
const diagnostics = createFileMap<ReadonlyArray<Diagnostic>>(toPath);
|
||||
@@ -997,7 +1005,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function buildSingleProject(proj: ResolvedConfigFileName): BuildResultFlags {
|
||||
if (options.dry) {
|
||||
reportStatus(Diagnostics.A_non_dry_build_would_build_project_0, proj);
|
||||
@@ -1030,6 +1037,9 @@ namespace ts {
|
||||
options: configFile.options,
|
||||
configFileParsingDiagnostics: configFile.errors
|
||||
};
|
||||
if (host.beforeCreateProgram) {
|
||||
host.beforeCreateProgram(options);
|
||||
}
|
||||
const program = createProgram(programOptions);
|
||||
|
||||
// Don't emit anything in the presence of syntactic errors or options diagnostics
|
||||
@@ -1041,14 +1051,6 @@ namespace ts {
|
||||
return buildErrors(syntaxDiagnostics, BuildResultFlags.SyntaxErrors, "Syntactic");
|
||||
}
|
||||
|
||||
// Don't emit .d.ts if there are decl file errors
|
||||
if (getEmitDeclarations(program.getCompilerOptions())) {
|
||||
const declDiagnostics = program.getDeclarationDiagnostics();
|
||||
if (declDiagnostics.length) {
|
||||
return buildErrors(declDiagnostics, BuildResultFlags.DeclarationEmitErrors, "Declaration file");
|
||||
}
|
||||
}
|
||||
|
||||
// Same as above but now for semantic diagnostics
|
||||
const semanticDiagnostics = program.getSemanticDiagnostics();
|
||||
if (semanticDiagnostics.length) {
|
||||
@@ -1057,14 +1059,23 @@ namespace ts {
|
||||
|
||||
let newestDeclarationFileContentChangedTime = minimumDate;
|
||||
let anyDtsChanged = false;
|
||||
let emitDiagnostics: Diagnostic[] | undefined;
|
||||
const reportEmitDiagnostic = (d: Diagnostic) => (emitDiagnostics || (emitDiagnostics = [])).push(d);
|
||||
emitFilesAndReportErrors(program, reportEmitDiagnostic, writeFileName, /*reportSummary*/ undefined, (fileName, content, writeBom, onError) => {
|
||||
let declDiagnostics: Diagnostic[] | undefined;
|
||||
const reportDeclarationDiagnostics = (d: Diagnostic) => (declDiagnostics || (declDiagnostics = [])).push(d);
|
||||
const outputFiles: OutputFile[] = [];
|
||||
emitFilesAndReportErrors(program, reportDeclarationDiagnostics, writeFileName, /*reportSummary*/ undefined, (name, text, writeByteOrderMark) => outputFiles.push({ name, text, writeByteOrderMark }));
|
||||
// Don't emit .d.ts if there are decl file errors
|
||||
if (declDiagnostics) {
|
||||
return buildErrors(declDiagnostics, BuildResultFlags.DeclarationEmitErrors, "Declaration file");
|
||||
}
|
||||
|
||||
// Actual Emit
|
||||
const emitterDiagnostics = createDiagnosticCollection();
|
||||
outputFiles.forEach(({ name, text, writeByteOrderMark }) => {
|
||||
let priorChangeTime: Date | undefined;
|
||||
if (!anyDtsChanged && isDeclarationFile(fileName)) {
|
||||
if (!anyDtsChanged && isDeclarationFile(name)) {
|
||||
// Check for unchanged .d.ts files
|
||||
if (host.fileExists(fileName) && host.readFile(fileName) === content) {
|
||||
priorChangeTime = host.getModifiedTime(fileName);
|
||||
if (host.fileExists(name) && readFileWithCache(name) === text) {
|
||||
priorChangeTime = host.getModifiedTime(name);
|
||||
}
|
||||
else {
|
||||
resultFlags &= ~BuildResultFlags.DeclarationOutputUnchanged;
|
||||
@@ -1072,14 +1083,15 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
host.writeFile(fileName, content, writeBom, onError, emptyArray);
|
||||
writeFile(host, emitterDiagnostics, name, text, writeByteOrderMark);
|
||||
if (priorChangeTime !== undefined) {
|
||||
newestDeclarationFileContentChangedTime = newer(priorChangeTime, newestDeclarationFileContentChangedTime);
|
||||
unchangedOutputs.setValue(fileName, priorChangeTime);
|
||||
unchangedOutputs.setValue(name, priorChangeTime);
|
||||
}
|
||||
});
|
||||
|
||||
if (emitDiagnostics) {
|
||||
const emitDiagnostics = emitterDiagnostics.getDiagnostics();
|
||||
if (emitDiagnostics.length) {
|
||||
return buildErrors(emitDiagnostics, BuildResultFlags.EmitErrors, "Emit");
|
||||
}
|
||||
|
||||
@@ -1089,12 +1101,18 @@ namespace ts {
|
||||
};
|
||||
diagnostics.removeKey(proj);
|
||||
projectStatus.setValue(proj, status);
|
||||
if (host.afterProgramEmitAndDiagnostics) {
|
||||
host.afterProgramEmitAndDiagnostics(program);
|
||||
}
|
||||
return resultFlags;
|
||||
|
||||
function buildErrors(diagnostics: ReadonlyArray<Diagnostic>, errorFlags: BuildResultFlags, errorType: string) {
|
||||
resultFlags |= errorFlags;
|
||||
reportAndStoreErrors(proj, diagnostics);
|
||||
projectStatus.setValue(proj, { type: UpToDateStatusType.Unbuildable, reason: `${errorType} errors` });
|
||||
if (host.afterProgramEmitAndDiagnostics) {
|
||||
host.afterProgramEmitAndDiagnostics(program);
|
||||
}
|
||||
return resultFlags;
|
||||
}
|
||||
}
|
||||
@@ -1167,6 +1185,15 @@ namespace ts {
|
||||
|
||||
function buildAllProjects(): ExitStatus {
|
||||
if (options.watch) { reportWatchStatus(Diagnostics.Starting_compilation_in_watch_mode); }
|
||||
// TODO:: In watch mode as well to use caches for incremental build once we can invalidate caches correctly and have right api
|
||||
// Override readFile for json files and output .d.ts to cache the text
|
||||
const { originalReadFile, originalFileExists, originalDirectoryExists,
|
||||
originalCreateDirectory, originalWriteFile, originalGetSourceFile,
|
||||
readFileWithCache: newReadFileWithCache
|
||||
} = changeCompilerHostToUseCache(host, toPath, /*useCacheForSourceFile*/ true);
|
||||
const savedReadFileWithCache = readFileWithCache;
|
||||
readFileWithCache = newReadFileWithCache;
|
||||
|
||||
const graph = getGlobalDependencyGraph();
|
||||
reportBuildQueue(graph);
|
||||
let anyFailed = false;
|
||||
@@ -1217,6 +1244,13 @@ namespace ts {
|
||||
anyFailed = anyFailed || !!(buildResult & BuildResultFlags.AnyErrors);
|
||||
}
|
||||
reportErrorSummary();
|
||||
host.readFile = originalReadFile;
|
||||
host.fileExists = originalFileExists;
|
||||
host.directoryExists = originalDirectoryExists;
|
||||
host.createDirectory = originalCreateDirectory;
|
||||
host.writeFile = originalWriteFile;
|
||||
readFileWithCache = savedReadFileWithCache;
|
||||
host.getSourceFile = originalGetSourceFile;
|
||||
return anyFailed ? ExitStatus.DiagnosticsPresent_OutputsSkipped : ExitStatus.Success;
|
||||
}
|
||||
|
||||
|
||||
+31
-16
@@ -1745,6 +1745,9 @@ namespace ts {
|
||||
export type EntityNameExpression = Identifier | PropertyAccessEntityNameExpression;
|
||||
export type EntityNameOrEntityNameExpression = EntityName | EntityNameExpression;
|
||||
|
||||
/* @internal */
|
||||
export type AccessExpression = PropertyAccessExpression | ElementAccessExpression;
|
||||
|
||||
export interface PropertyAccessExpression extends MemberExpression, NamedDeclaration {
|
||||
kind: SyntaxKind.PropertyAccessExpression;
|
||||
expression: LeftHandSideExpression;
|
||||
@@ -2614,6 +2617,8 @@ namespace ts {
|
||||
export interface SourceFileLike {
|
||||
readonly text: string;
|
||||
lineMap?: ReadonlyArray<number>;
|
||||
/* @internal */
|
||||
getPositionOfLineAndCharacter?(line: number, character: number, allowEdits?: true): number;
|
||||
}
|
||||
|
||||
|
||||
@@ -3103,7 +3108,7 @@ namespace ts {
|
||||
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): string | number | undefined;
|
||||
isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName | ImportTypeNode, propertyName: string): boolean;
|
||||
/** Exclude accesses to private properties or methods with a `this` parameter that `type` doesn't satisfy. */
|
||||
/* @internal */ isValidPropertyAccessForCompletions(node: PropertyAccessExpression | ImportTypeNode, type: Type, property: Symbol): boolean;
|
||||
/* @internal */ isValidPropertyAccessForCompletions(node: PropertyAccessExpression | ImportTypeNode | QualifiedName, type: Type, property: Symbol): boolean;
|
||||
/** Follow all aliases to get the original symbol. */
|
||||
getAliasedSymbol(symbol: Symbol): Symbol;
|
||||
/** Follow a *single* alias to get the immediately aliased symbol. */
|
||||
@@ -3141,6 +3146,7 @@ namespace ts {
|
||||
/* @internal */ getNeverType(): Type;
|
||||
/* @internal */ getUnionType(types: Type[], subtypeReduction?: UnionReduction): Type;
|
||||
/* @internal */ createArrayType(elementType: Type): Type;
|
||||
/* @internal */ getElementTypeOfArrayType(arrayType: Type): Type | undefined;
|
||||
/* @internal */ createPromiseType(type: Type): Type;
|
||||
|
||||
/* @internal */ createAnonymousType(symbol: Symbol, members: SymbolTable, callSignatures: Signature[], constructSignatures: Signature[], stringIndexInfo: IndexInfo | undefined, numberIndexInfo: IndexInfo | undefined): Type;
|
||||
@@ -3261,15 +3267,17 @@ namespace ts {
|
||||
AllowUniqueESSymbolType = 1 << 20,
|
||||
AllowEmptyIndexInfoType = 1 << 21,
|
||||
|
||||
IgnoreErrors = AllowThisInObjectLiteral | AllowQualifedNameInPlaceOfIdentifier | AllowAnonymousIdentifier | AllowEmptyUnionOrIntersection | AllowEmptyTuple | AllowEmptyIndexInfoType,
|
||||
// Errors (cont.)
|
||||
AllowNodeModulesRelativePaths = 1 << 26,
|
||||
/* @internal */ DoNotIncludeSymbolChain = 1 << 27, // Skip looking up and printing an accessible symbol chain
|
||||
|
||||
IgnoreErrors = AllowThisInObjectLiteral | AllowQualifedNameInPlaceOfIdentifier | AllowAnonymousIdentifier | AllowEmptyUnionOrIntersection | AllowEmptyTuple | AllowEmptyIndexInfoType | AllowNodeModulesRelativePaths,
|
||||
|
||||
// State
|
||||
InObjectTypeLiteral = 1 << 22,
|
||||
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
|
||||
@@ -3650,6 +3658,8 @@ namespace ts {
|
||||
originatingImport?: ImportDeclaration | ImportCall; // Import declaration which produced the symbol, present if the symbol is marked as uncallable but had call signatures in `resolveESModuleSymbol`
|
||||
lateSymbol?: Symbol; // Late-bound symbol for a computed property
|
||||
specifierCache?: Map<string>; // For symbols corresponding to external modules, a cache of incoming path -> module specifier name mappings
|
||||
extendedContainers?: Symbol[]; // Containers (other than the parent) which this symbol is aliased in
|
||||
extendedContainersByFile?: Map<Symbol[]>; // Containers (other than the parent) which this symbol is aliased in
|
||||
variances?: Variance[]; // Alias symbol type argument variance cache
|
||||
}
|
||||
|
||||
@@ -3667,15 +3677,17 @@ namespace ts {
|
||||
Readonly = 1 << 3, // Readonly transient symbol
|
||||
Partial = 1 << 4, // Synthetic property present in some but not all constituents
|
||||
HasNonUniformType = 1 << 5, // Synthetic property with non-uniform type in constituents
|
||||
ContainsPublic = 1 << 6, // Synthetic property with public constituent(s)
|
||||
ContainsProtected = 1 << 7, // Synthetic property with protected constituent(s)
|
||||
ContainsPrivate = 1 << 8, // Synthetic property with private constituent(s)
|
||||
ContainsStatic = 1 << 9, // Synthetic property with static constituent(s)
|
||||
Late = 1 << 10, // Late-bound symbol for a computed property with a dynamic name
|
||||
ReverseMapped = 1 << 11, // Property of reverse-inferred homomorphic mapped type
|
||||
OptionalParameter = 1 << 12, // Optional parameter
|
||||
RestParameter = 1 << 13, // Rest parameter
|
||||
Synthetic = SyntheticProperty | SyntheticMethod
|
||||
HasLiteralType = 1 << 6, // Synthetic property with at least one literal type in constituents
|
||||
ContainsPublic = 1 << 7, // Synthetic property with public constituent(s)
|
||||
ContainsProtected = 1 << 8, // Synthetic property with protected constituent(s)
|
||||
ContainsPrivate = 1 << 9, // Synthetic property with private constituent(s)
|
||||
ContainsStatic = 1 << 10, // Synthetic property with static constituent(s)
|
||||
Late = 1 << 11, // Late-bound symbol for a computed property with a dynamic name
|
||||
ReverseMapped = 1 << 12, // Property of reverse-inferred homomorphic mapped type
|
||||
OptionalParameter = 1 << 13, // Optional parameter
|
||||
RestParameter = 1 << 14, // Rest parameter
|
||||
Synthetic = SyntheticProperty | SyntheticMethod,
|
||||
Discriminant = HasNonUniformType | HasLiteralType
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -4495,7 +4507,6 @@ namespace ts {
|
||||
downlevelIteration?: boolean;
|
||||
emitBOM?: boolean;
|
||||
emitDecoratorMetadata?: boolean;
|
||||
experimentalBigInt?: boolean;
|
||||
experimentalDecorators?: boolean;
|
||||
forceConsistentCasingInFileNames?: boolean;
|
||||
/*@internal*/help?: boolean;
|
||||
@@ -5010,6 +5021,9 @@ namespace ts {
|
||||
/* @internal */ hasInvalidatedResolution?: HasInvalidatedResolution;
|
||||
/* @internal */ hasChangedAutomaticTypeDirectiveNames?: boolean;
|
||||
createHash?(data: string): string;
|
||||
|
||||
// TODO: later handle this in better way in builder host instead once the api for tsbuild finalizes and doesnt use compilerHost as base
|
||||
/*@internal*/createDirectory?(directory: string): void;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -5521,9 +5535,9 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export interface DocumentPositionMapperHost {
|
||||
getSourceFileLike(path: Path): SourceFileLike | undefined;
|
||||
getSourceFileLike(fileName: string): SourceFileLike | undefined;
|
||||
getCanonicalFileName(path: string): string;
|
||||
log?(text: string): void;
|
||||
log(text: string): void;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5577,6 +5591,7 @@ namespace ts {
|
||||
reportInaccessibleThisError?(): void;
|
||||
reportPrivateInBaseOfClassExpression?(propertyName: string): void;
|
||||
reportInaccessibleUniqueSymbolError?(): void;
|
||||
reportLikelyUnsafeImportRequiredError?(specifier: string): void;
|
||||
moduleResolverHost?: ModuleSpecifierResolutionHost & { getSourceFiles(): ReadonlyArray<SourceFile>, getCommonSourceDirectory(): string };
|
||||
trackReferencedAmbientModule?(decl: ModuleDeclaration, symbol: Symbol): void;
|
||||
trackExternalModuleSymbolOfImportTypeNode?(symbol: Symbol): void;
|
||||
|
||||
+67
-39
@@ -1,4 +1,3 @@
|
||||
/** Non-internal stuff goes here */
|
||||
namespace ts {
|
||||
export function isExternalModuleNameRelative(moduleName: string): boolean {
|
||||
// TypeScript 1.0 spec (April 2014): 11.2.1
|
||||
@@ -2091,10 +2090,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function isJSDocConstructSignature(node: Node) {
|
||||
return node.kind === SyntaxKind.JSDocFunctionType &&
|
||||
(node as JSDocFunctionType).parameters.length > 0 &&
|
||||
(node as JSDocFunctionType).parameters[0].name &&
|
||||
((node as JSDocFunctionType).parameters[0].name as Identifier).escapedText === "new";
|
||||
const param = isJSDocFunctionType(node) ? firstOrUndefined(node.parameters) : undefined;
|
||||
const name = tryCast(param && param.name, isIdentifier);
|
||||
return !!name && name.escapedText === "new";
|
||||
}
|
||||
|
||||
export function isJSDocTypeAlias(node: Node): node is JSDocTypedefTag | JSDocCallbackTag {
|
||||
@@ -2123,7 +2121,7 @@ namespace ts {
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function getSingleInitializerOfVariableStatementOrPropertyDeclaration(node: Node): Expression | undefined {
|
||||
export function getSingleInitializerOfVariableStatementOrPropertyDeclaration(node: Node): Expression | undefined {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.VariableStatement:
|
||||
const v = getSingleVariableOfVariableStatement(node);
|
||||
@@ -3404,7 +3402,7 @@ namespace ts {
|
||||
return combinePaths(newDirPath, sourceFilePath);
|
||||
}
|
||||
|
||||
export function writeFile(host: EmitHost, diagnostics: DiagnosticCollection, fileName: string, data: string, writeByteOrderMark: boolean, sourceFiles?: ReadonlyArray<SourceFile>) {
|
||||
export function writeFile(host: { writeFile: WriteFileCallback; }, diagnostics: DiagnosticCollection, fileName: string, data: string, writeByteOrderMark: boolean, sourceFiles?: ReadonlyArray<SourceFile>) {
|
||||
host.writeFile(fileName, data, writeByteOrderMark, hostErrorMessage => {
|
||||
diagnostics.add(createCompilerDiagnostic(Diagnostics.Could_not_write_file_0_Colon_1, fileName, hostErrorMessage));
|
||||
}, sourceFiles);
|
||||
@@ -4567,6 +4565,35 @@ namespace ts {
|
||||
export function isObjectTypeDeclaration(node: Node): node is ObjectTypeDeclaration {
|
||||
return isClassLike(node) || isInterfaceDeclaration(node) || isTypeLiteralNode(node);
|
||||
}
|
||||
|
||||
export function isTypeNodeKind(kind: SyntaxKind) {
|
||||
return (kind >= SyntaxKind.FirstTypeNode && kind <= SyntaxKind.LastTypeNode)
|
||||
|| kind === SyntaxKind.AnyKeyword
|
||||
|| kind === SyntaxKind.UnknownKeyword
|
||||
|| kind === SyntaxKind.NumberKeyword
|
||||
|| kind === SyntaxKind.BigIntKeyword
|
||||
|| kind === SyntaxKind.ObjectKeyword
|
||||
|| kind === SyntaxKind.BooleanKeyword
|
||||
|| kind === SyntaxKind.StringKeyword
|
||||
|| kind === SyntaxKind.SymbolKeyword
|
||||
|| kind === SyntaxKind.ThisKeyword
|
||||
|| kind === SyntaxKind.VoidKeyword
|
||||
|| kind === SyntaxKind.UndefinedKeyword
|
||||
|| kind === SyntaxKind.NullKeyword
|
||||
|| kind === SyntaxKind.NeverKeyword
|
||||
|| kind === SyntaxKind.ExpressionWithTypeArguments
|
||||
|| kind === SyntaxKind.JSDocAllType
|
||||
|| kind === SyntaxKind.JSDocUnknownType
|
||||
|| kind === SyntaxKind.JSDocNullableType
|
||||
|| kind === SyntaxKind.JSDocNonNullableType
|
||||
|| kind === SyntaxKind.JSDocOptionalType
|
||||
|| kind === SyntaxKind.JSDocFunctionType
|
||||
|| kind === SyntaxKind.JSDocVariadicType;
|
||||
}
|
||||
|
||||
export function isAccessExpression(node: Node): node is AccessExpression {
|
||||
return node.kind === SyntaxKind.PropertyAccessExpression || node.kind === SyntaxKind.ElementAccessExpression;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ts {
|
||||
@@ -6112,6 +6139,10 @@ namespace ts {
|
||||
|| kind === SyntaxKind.TemplateTail;
|
||||
}
|
||||
|
||||
export function isImportOrExportSpecifier(node: Node): node is ImportSpecifier | ExportSpecifier {
|
||||
return isImportSpecifier(node) || isExportSpecifier(node);
|
||||
}
|
||||
|
||||
export function isStringTextContainingNode(node: Node): node is StringLiteral | TemplateLiteralToken {
|
||||
return node.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(node.kind);
|
||||
}
|
||||
@@ -6286,31 +6317,6 @@ namespace ts {
|
||||
|
||||
// Type
|
||||
|
||||
function isTypeNodeKind(kind: SyntaxKind) {
|
||||
return (kind >= SyntaxKind.FirstTypeNode && kind <= SyntaxKind.LastTypeNode)
|
||||
|| kind === SyntaxKind.AnyKeyword
|
||||
|| kind === SyntaxKind.UnknownKeyword
|
||||
|| kind === SyntaxKind.NumberKeyword
|
||||
|| kind === SyntaxKind.BigIntKeyword
|
||||
|| kind === SyntaxKind.ObjectKeyword
|
||||
|| kind === SyntaxKind.BooleanKeyword
|
||||
|| kind === SyntaxKind.StringKeyword
|
||||
|| kind === SyntaxKind.SymbolKeyword
|
||||
|| kind === SyntaxKind.ThisKeyword
|
||||
|| kind === SyntaxKind.VoidKeyword
|
||||
|| kind === SyntaxKind.UndefinedKeyword
|
||||
|| kind === SyntaxKind.NullKeyword
|
||||
|| kind === SyntaxKind.NeverKeyword
|
||||
|| kind === SyntaxKind.ExpressionWithTypeArguments
|
||||
|| kind === SyntaxKind.JSDocAllType
|
||||
|| kind === SyntaxKind.JSDocUnknownType
|
||||
|| kind === SyntaxKind.JSDocNullableType
|
||||
|| kind === SyntaxKind.JSDocNonNullableType
|
||||
|| kind === SyntaxKind.JSDocOptionalType
|
||||
|| kind === SyntaxKind.JSDocFunctionType
|
||||
|| kind === SyntaxKind.JSDocVariadicType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Node test that determines whether a node is a valid type node.
|
||||
* This differs from the `isPartOfTypeNode` function which determines whether a node is *part*
|
||||
@@ -6838,7 +6844,7 @@ namespace ts {
|
||||
|
||||
// TODO: determine what this does before making it public.
|
||||
/* @internal */
|
||||
export function isJSDocTag(node: Node): boolean {
|
||||
export function isJSDocTag(node: Node): node is JSDocTag {
|
||||
return node.kind >= SyntaxKind.FirstJSDocTagNode && node.kind <= SyntaxKind.LastJSDocTagNode;
|
||||
}
|
||||
|
||||
@@ -6980,8 +6986,8 @@ namespace ts {
|
||||
getSourceMapSourceConstructor: () => <any>SourceMapSource,
|
||||
};
|
||||
|
||||
export function formatStringFromArgs(text: string, args: ArrayLike<string>, baseIndex = 0): string {
|
||||
return text.replace(/{(\d+)}/g, (_match, index: string) => Debug.assertDefined(args[+index + baseIndex]));
|
||||
export function formatStringFromArgs(text: string, args: ArrayLike<string | number>, baseIndex = 0): string {
|
||||
return text.replace(/{(\d+)}/g, (_match, index: string) => "" + Debug.assertDefined(args[+index + baseIndex]));
|
||||
}
|
||||
|
||||
export let localizedDiagnosticMessages: MapLike<string> | undefined;
|
||||
@@ -7060,7 +7066,7 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain | undefined, message: DiagnosticMessage, ...args: (string | undefined)[]): DiagnosticMessageChain;
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticMessageChain;
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain | undefined, message: DiagnosticMessage): DiagnosticMessageChain {
|
||||
let text = getLocaleSpecificMessage(message);
|
||||
|
||||
@@ -7685,16 +7691,38 @@ namespace ts {
|
||||
return path;
|
||||
}
|
||||
|
||||
// check path for these segments: '', '.'. '..'
|
||||
const relativePathSegmentRegExp = /(^|\/)\.{0,2}($|\/)/;
|
||||
|
||||
function comparePathsWorker(a: string, b: string, componentComparer: (a: string, b: string) => Comparison) {
|
||||
if (a === b) return Comparison.EqualTo;
|
||||
if (a === undefined) return Comparison.LessThan;
|
||||
if (b === undefined) return Comparison.GreaterThan;
|
||||
|
||||
// NOTE: Performance optimization - shortcut if the root segments differ as there would be no
|
||||
// need to perform path reduction.
|
||||
const aRoot = a.substring(0, getRootLength(a));
|
||||
const bRoot = b.substring(0, getRootLength(b));
|
||||
const result = compareStringsCaseInsensitive(aRoot, bRoot);
|
||||
if (result !== Comparison.EqualTo) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// NOTE: Performance optimization - shortcut if there are no relative path segments in
|
||||
// the non-root portion of the path
|
||||
const aRest = a.substring(aRoot.length);
|
||||
const bRest = b.substring(bRoot.length);
|
||||
if (!relativePathSegmentRegExp.test(aRest) && !relativePathSegmentRegExp.test(bRest)) {
|
||||
return componentComparer(aRest, bRest);
|
||||
}
|
||||
|
||||
// The path contains a relative path segment. Normalize the paths and perform a slower component
|
||||
// by component comparison.
|
||||
const aComponents = reducePathComponents(getPathComponents(a));
|
||||
const bComponents = reducePathComponents(getPathComponents(b));
|
||||
const sharedLength = Math.min(aComponents.length, bComponents.length);
|
||||
for (let i = 0; i < sharedLength; i++) {
|
||||
const stringComparer = i === 0 ? compareStringsCaseInsensitive : componentComparer;
|
||||
const result = stringComparer(aComponents[i], bComponents[i]);
|
||||
for (let i = 1; i < sharedLength; i++) {
|
||||
const result = componentComparer(aComponents[i], bComponents[i]);
|
||||
if (result !== Comparison.EqualTo) {
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace ts.server {
|
||||
private sequence = 0;
|
||||
private lineMaps: Map<number[]> = createMap<number[]>();
|
||||
private messages: string[] = [];
|
||||
private lastRenameEntry: RenameEntry;
|
||||
private lastRenameEntry: RenameEntry | undefined;
|
||||
|
||||
constructor(private host: SessionClientHost) {
|
||||
}
|
||||
@@ -431,7 +431,7 @@ namespace ts.server {
|
||||
this.getRenameInfo(fileName, position, findInStrings, findInComments);
|
||||
}
|
||||
|
||||
return this.lastRenameEntry.locations;
|
||||
return this.lastRenameEntry!.locations;
|
||||
}
|
||||
|
||||
private decodeNavigationBarItems(items: protocol.NavigationBarItem[] | undefined, fileName: string, lineMap: number[]): NavigationBarItem[] {
|
||||
|
||||
@@ -215,7 +215,7 @@ namespace fakes {
|
||||
|
||||
private _setParentNodes: boolean;
|
||||
private _sourceFiles: collections.SortedMap<string, ts.SourceFile>;
|
||||
private _parseConfigHost: ParseConfigHost;
|
||||
private _parseConfigHost: ParseConfigHost | undefined;
|
||||
private _newLine: string;
|
||||
|
||||
constructor(sys: System | vfs.FileSystem, options = ts.getDefaultCompilerOptions(), setParentNodes = false) {
|
||||
|
||||
+12
-16
@@ -158,7 +158,7 @@ namespace FourSlash {
|
||||
public lastKnownMarker = "";
|
||||
|
||||
// The file that's currently 'opened'
|
||||
public activeFile: FourSlashFile;
|
||||
public activeFile!: FourSlashFile;
|
||||
|
||||
// Whether or not we should format on keystrokes
|
||||
public enableFormatting = true;
|
||||
@@ -571,7 +571,8 @@ namespace FourSlash {
|
||||
public verifyNoErrors() {
|
||||
ts.forEachKey(this.inputFiles, fileName => {
|
||||
if (!ts.isAnySupportedFileExtension(fileName)
|
||||
|| !this.getProgram().getCompilerOptions().allowJs && !ts.extensionIsTS(ts.extensionFromPath(fileName))) return;
|
||||
|| Harness.getConfigNameFromFileName(fileName)
|
||||
|| !this.getProgram().getCompilerOptions().allowJs && !ts.resolutionExtensionIsTSOrJson(ts.extensionFromPath(fileName))) return;
|
||||
const errors = this.getDiagnostics(fileName).filter(e => e.category !== ts.DiagnosticCategory.Suggestion);
|
||||
if (errors.length) {
|
||||
this.printErrorLog(/*expectErrors*/ false, errors);
|
||||
@@ -599,7 +600,7 @@ namespace FourSlash {
|
||||
throw new Error("Expected exactly one output from emit of " + this.activeFile.fileName);
|
||||
}
|
||||
|
||||
const evaluation = new Function(`${emit.outputFiles[0].text};\r\nreturn (${expr});`)();
|
||||
const evaluation = new Function(`${emit.outputFiles[0].text};\r\nreturn (${expr});`)(); // tslint:disable-line:function-constructor
|
||||
if (evaluation !== value) {
|
||||
this.raiseError(`Expected evaluation of expression "${expr}" to equal "${value}", but got "${evaluation}"`);
|
||||
}
|
||||
@@ -854,9 +855,9 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
/** Use `getProgram` instead of accessing this directly. */
|
||||
private _program: ts.Program;
|
||||
private _program: ts.Program | undefined;
|
||||
/** Use `getChecker` instead of accessing this directly. */
|
||||
private _checker: ts.TypeChecker;
|
||||
private _checker: ts.TypeChecker | undefined;
|
||||
|
||||
private getProgram(): ts.Program {
|
||||
return this._program || (this._program = this.languageService.getProgram()!); // TODO: GH#18217
|
||||
@@ -2783,11 +2784,6 @@ Actual: ${stringify(fullActual)}`);
|
||||
assert.deepEqual(unique(this.getApplicableRefactorsAtSelection(), r => r.name), names);
|
||||
}
|
||||
|
||||
public verifyRefactor({ name, actionName, refactors }: FourSlashInterface.VerifyRefactorOptions) {
|
||||
const actualRefactors = this.getApplicableRefactorsAtSelection().filter(r => r.name === name && r.actions.some(a => a.name === actionName));
|
||||
this.assertObjectsEqual(actualRefactors, refactors);
|
||||
}
|
||||
|
||||
public verifyApplicableRefactorAvailableForRange(negative: boolean) {
|
||||
const ranges = this.getRanges();
|
||||
if (!(ranges && ranges.length === 1)) {
|
||||
@@ -3738,7 +3734,7 @@ namespace FourSlashInterface {
|
||||
}
|
||||
|
||||
export class VerifyNegatable {
|
||||
public not: VerifyNegatable;
|
||||
public not: VerifyNegatable | undefined;
|
||||
|
||||
constructor(protected state: FourSlash.TestState, private negative = false) {
|
||||
if (!negative) {
|
||||
@@ -3822,10 +3818,6 @@ namespace FourSlashInterface {
|
||||
this.state.verifyRefactorsAvailable(names);
|
||||
}
|
||||
|
||||
public refactor(options: VerifyRefactorOptions) {
|
||||
this.state.verifyRefactor(options);
|
||||
}
|
||||
|
||||
public refactorAvailable(name: string, actionName?: string) {
|
||||
this.state.verifyRefactorAvailable(this.negative, name, actionName);
|
||||
}
|
||||
@@ -4447,7 +4439,7 @@ namespace FourSlashInterface {
|
||||
export const keywords: ReadonlyArray<ExpectedCompletionEntryObject> = keywordsWithUndefined.filter(k => k.name !== "undefined");
|
||||
|
||||
export const typeKeywords: ReadonlyArray<ExpectedCompletionEntryObject> =
|
||||
["false", "null", "true", "void", "any", "boolean", "keyof", "never", "number", "object", "string", "symbol", "undefined", "unique", "unknown"].map(keywordEntry);
|
||||
["false", "null", "true", "void", "any", "boolean", "keyof", "never", "number", "object", "string", "symbol", "undefined", "unique", "unknown", "bigint"].map(keywordEntry);
|
||||
|
||||
const globalTypeDecls: ReadonlyArray<ExpectedCompletionEntryObject> = [
|
||||
interfaceEntry("Symbol"),
|
||||
@@ -4458,6 +4450,8 @@ namespace FourSlashInterface {
|
||||
interfaceEntry("ObjectConstructor"),
|
||||
constEntry("Function"),
|
||||
interfaceEntry("FunctionConstructor"),
|
||||
typeEntry("ThisParameterType"),
|
||||
typeEntry("OmitThisParameter"),
|
||||
interfaceEntry("CallableFunction"),
|
||||
interfaceEntry("NewableFunction"),
|
||||
interfaceEntry("IArguments"),
|
||||
@@ -4783,6 +4777,7 @@ namespace FourSlashInterface {
|
||||
"package",
|
||||
"yield",
|
||||
"async",
|
||||
"await",
|
||||
].map(keywordEntry);
|
||||
|
||||
// TODO: many of these are inappropriate to always provide
|
||||
@@ -4915,6 +4910,7 @@ namespace FourSlashInterface {
|
||||
"package",
|
||||
"yield",
|
||||
"async",
|
||||
"await",
|
||||
].map(keywordEntry);
|
||||
|
||||
export const globalKeywordsPlusUndefined: ReadonlyArray<ExpectedCompletionEntryObject> = (() => {
|
||||
|
||||
@@ -28,12 +28,10 @@ var assert: typeof _chai.assert = _chai.assert;
|
||||
};
|
||||
}
|
||||
|
||||
var global: NodeJS.Global = Function("return this").call(undefined);
|
||||
var global: NodeJS.Global = Function("return this").call(undefined); // tslint:disable-line:function-constructor
|
||||
|
||||
declare var window: {};
|
||||
declare var XMLHttpRequest: {
|
||||
new(): XMLHttpRequest;
|
||||
};
|
||||
declare var XMLHttpRequest: new() => XMLHttpRequest;
|
||||
interface XMLHttpRequest {
|
||||
readonly readyState: number;
|
||||
readonly responseText: string;
|
||||
|
||||
@@ -289,8 +289,8 @@ namespace Harness.LanguageService {
|
||||
class ShimLanguageServiceHost extends LanguageServiceAdapterHost implements ts.LanguageServiceShimHost, ts.CoreServicesShimHost {
|
||||
private nativeHost: NativeLanguageServiceHost;
|
||||
|
||||
public getModuleResolutionsForFile: (fileName: string) => string;
|
||||
public getTypeReferenceDirectiveResolutionsForFile: (fileName: string) => string;
|
||||
public getModuleResolutionsForFile: ((fileName: string) => string) | undefined;
|
||||
public getTypeReferenceDirectiveResolutionsForFile: ((fileName: string) => string) | undefined;
|
||||
|
||||
constructor(preprocessToResolve: boolean, cancellationToken?: ts.HostCancellationToken, options?: ts.CompilerOptions) {
|
||||
super(cancellationToken, options);
|
||||
@@ -639,7 +639,7 @@ namespace Harness.LanguageService {
|
||||
|
||||
// Server adapter
|
||||
class SessionClientHost extends NativeLanguageServiceHost implements ts.server.SessionClientHost {
|
||||
private client: ts.server.SessionClient;
|
||||
private client!: ts.server.SessionClient;
|
||||
|
||||
constructor(cancellationToken: ts.HostCancellationToken | undefined, settings: ts.CompilerOptions | undefined) {
|
||||
super(cancellationToken, settings);
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace Harness.SourceMapRecorder {
|
||||
SourceMapDecoder.initializeSourceMapDecoding(sourceMapData);
|
||||
sourceMapRecorder.WriteLine("===================================================================");
|
||||
sourceMapRecorder.WriteLine("JsFile: " + sourceMapData.sourceMap.file);
|
||||
sourceMapRecorder.WriteLine("mapUrl: " + ts.tryGetSourceMappingURL(jsFile.text, jsLineMap));
|
||||
sourceMapRecorder.WriteLine("mapUrl: " + ts.tryGetSourceMappingURL(ts.getLineInfo(jsFile.text, jsLineMap)));
|
||||
sourceMapRecorder.WriteLine("sourceRoot: " + sourceMapData.sourceMap.sourceRoot);
|
||||
sourceMapRecorder.WriteLine("sources: " + sourceMapData.sourceMap.sources);
|
||||
if (sourceMapData.sourceMap.sourcesContent) {
|
||||
|
||||
@@ -21,7 +21,7 @@ interface TypeWriterResult {
|
||||
}
|
||||
|
||||
class TypeWriterWalker {
|
||||
currentSourceFile: ts.SourceFile;
|
||||
currentSourceFile!: ts.SourceFile;
|
||||
|
||||
private checker: ts.TypeChecker;
|
||||
|
||||
|
||||
@@ -341,7 +341,7 @@ interface Array<T> {}`
|
||||
private readonly currentDirectory: string;
|
||||
private readonly dynamicPriorityWatchFile: HostWatchFile | undefined;
|
||||
private readonly customRecursiveWatchDirectory: HostWatchDirectory | undefined;
|
||||
public require: (initialPath: string, moduleName: string) => server.RequireResult;
|
||||
public require: ((initialPath: string, moduleName: string) => server.RequireResult) | undefined;
|
||||
|
||||
constructor(public withSafeList: boolean, public useCaseSensitiveFileNames: boolean, executingFilePath: string, currentDirectory: string, fileOrFolderorSymLinkList: ReadonlyArray<FileOrFolderOrSymLink>, public readonly newLine = "\n", public readonly useWindowsStylePath?: boolean, private readonly environmentVariables?: Map<string>) {
|
||||
this.getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
|
||||
Vendored
+12
-2
@@ -295,6 +295,16 @@ interface FunctionConstructor {
|
||||
|
||||
declare const Function: FunctionConstructor;
|
||||
|
||||
/**
|
||||
* Extracts the type of the 'this' parameter of a function type, or 'unknown' if the function type has no 'this' parameter.
|
||||
*/
|
||||
type ThisParameterType<T> = T extends (this: unknown, ...args: any[]) => any ? unknown : T extends (this: infer U, ...args: any[]) => any ? U : unknown;
|
||||
|
||||
/**
|
||||
* Removes the 'this' parameter from a function type.
|
||||
*/
|
||||
type OmitThisParameter<T> = unknown extends ThisParameterType<T> ? T : T extends (...args: infer A) => infer R ? (...args: A) => R : T;
|
||||
|
||||
interface CallableFunction extends Function {
|
||||
/**
|
||||
* Calls the function with the specified object as the this value and the elements of specified array as the arguments.
|
||||
@@ -317,7 +327,7 @@ interface CallableFunction extends Function {
|
||||
* @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>(this: T, thisArg: ThisParameterType<T>): OmitThisParameter<T>;
|
||||
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;
|
||||
@@ -347,7 +357,7 @@ interface NewableFunction extends Function {
|
||||
* @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<T>(this: T, thisArg: any): T;
|
||||
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;
|
||||
|
||||
+258
-14
@@ -123,11 +123,22 @@ namespace ts.server {
|
||||
|
||||
export interface FileStats {
|
||||
readonly js: number;
|
||||
readonly jsSize?: number;
|
||||
|
||||
readonly jsx: number;
|
||||
readonly jsxSize?: number;
|
||||
|
||||
readonly ts: number;
|
||||
readonly tsSize?: number;
|
||||
|
||||
readonly tsx: number;
|
||||
readonly tsxSize?: number;
|
||||
|
||||
readonly dts: number;
|
||||
readonly dtsSize?: number;
|
||||
|
||||
readonly deferred: number;
|
||||
readonly deferredSize?: number;
|
||||
}
|
||||
|
||||
export interface OpenFileInfo {
|
||||
@@ -331,6 +342,7 @@ namespace ts.server {
|
||||
FailedLookupLocation = "Directory of Failed lookup locations in module resolution",
|
||||
TypeRoots = "Type root directory",
|
||||
NodeModulesForClosedScriptInfo = "node_modules for closed script infos in them",
|
||||
MissingSourceMapFile = "Missing source map file"
|
||||
}
|
||||
|
||||
const enum ConfigFileWatcherStatus {
|
||||
@@ -426,7 +438,8 @@ namespace ts.server {
|
||||
/**
|
||||
* Container of all known scripts
|
||||
*/
|
||||
private readonly filenameToScriptInfo = createMap<ScriptInfo>();
|
||||
/*@internal*/
|
||||
readonly filenameToScriptInfo = createMap<ScriptInfo>();
|
||||
private readonly scriptInfoInNodeModulesWatchers = createMap <ScriptInfoInNodeModulesWatcher>();
|
||||
/**
|
||||
* Contains all the deleted script info's version information so that
|
||||
@@ -468,7 +481,7 @@ namespace ts.server {
|
||||
*/
|
||||
private readonly openFilesWithNonRootedDiskPath = createMap<ScriptInfo>();
|
||||
|
||||
private compilerOptionsForInferredProjects: CompilerOptions;
|
||||
private compilerOptionsForInferredProjects: CompilerOptions | undefined;
|
||||
private compilerOptionsForInferredProjectsPerProjectRoot = createMap<CompilerOptions>();
|
||||
/**
|
||||
* Project size for configured or external projects
|
||||
@@ -490,7 +503,7 @@ namespace ts.server {
|
||||
|
||||
private pendingProjectUpdates = createMap<Project>();
|
||||
/* @internal */
|
||||
pendingEnsureProjectForOpenFiles: boolean;
|
||||
pendingEnsureProjectForOpenFiles = false;
|
||||
|
||||
readonly currentDirectory: NormalizedPath;
|
||||
readonly toCanonicalFileName: (f: string) => string;
|
||||
@@ -933,10 +946,42 @@ namespace ts.server {
|
||||
// this file and set of inferred projects
|
||||
info.delayReloadNonMixedContentFile();
|
||||
this.delayUpdateProjectGraphs(info.containingProjects);
|
||||
this.handleSourceMapProjects(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private handleSourceMapProjects(info: ScriptInfo) {
|
||||
// Change in d.ts, update source projects as well
|
||||
if (info.sourceMapFilePath) {
|
||||
if (isString(info.sourceMapFilePath)) {
|
||||
const sourceMapFileInfo = this.getScriptInfoForPath(info.sourceMapFilePath);
|
||||
this.delayUpdateSourceInfoProjects(sourceMapFileInfo && sourceMapFileInfo.sourceInfos);
|
||||
}
|
||||
else {
|
||||
this.delayUpdateSourceInfoProjects(info.sourceMapFilePath.sourceInfos);
|
||||
}
|
||||
}
|
||||
// Change in mapInfo, update declarationProjects and source projects
|
||||
this.delayUpdateSourceInfoProjects(info.sourceInfos);
|
||||
if (info.declarationInfoPath) {
|
||||
this.delayUpdateProjectsOfScriptInfoPath(info.declarationInfoPath);
|
||||
}
|
||||
}
|
||||
|
||||
private delayUpdateSourceInfoProjects(sourceInfos: Map<true> | undefined) {
|
||||
if (sourceInfos) {
|
||||
sourceInfos.forEach((_value, path) => this.delayUpdateProjectsOfScriptInfoPath(path as Path));
|
||||
}
|
||||
}
|
||||
|
||||
private delayUpdateProjectsOfScriptInfoPath(path: Path) {
|
||||
const info = this.getScriptInfoForPath(path);
|
||||
if (info) {
|
||||
this.delayUpdateProjectGraphs(info.containingProjects);
|
||||
}
|
||||
}
|
||||
|
||||
private handleDeletedFile(info: ScriptInfo) {
|
||||
this.stopWatchingScriptInfo(info);
|
||||
|
||||
@@ -950,6 +995,15 @@ namespace ts.server {
|
||||
|
||||
// update projects to make sure that set of referenced files is correct
|
||||
this.delayUpdateProjectGraphs(containingProjects);
|
||||
this.handleSourceMapProjects(info);
|
||||
info.closeSourceMapFileWatcher();
|
||||
// need to recalculate source map from declaration file
|
||||
if (info.declarationInfoPath) {
|
||||
const declarationInfo = this.getScriptInfoForPath(info.declarationInfoPath);
|
||||
if (declarationInfo) {
|
||||
declarationInfo.sourceMapFilePath = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1223,7 +1277,8 @@ namespace ts.server {
|
||||
private setConfigFileExistenceByNewConfiguredProject(project: ConfiguredProject) {
|
||||
const configFileExistenceInfo = this.getConfigFileExistenceInfo(project);
|
||||
if (configFileExistenceInfo) {
|
||||
Debug.assert(configFileExistenceInfo.exists);
|
||||
// The existance might not be set if the file watcher is not invoked by the time config project is created by external project
|
||||
configFileExistenceInfo.exists = true;
|
||||
// close existing watcher
|
||||
if (configFileExistenceInfo.configFileWatcherForRootOfInferredProject) {
|
||||
const configFileName = project.getConfigFilePath();
|
||||
@@ -1600,7 +1655,7 @@ namespace ts.server {
|
||||
setProjectOptionsUsed(project);
|
||||
const data: ProjectInfoTelemetryEventData = {
|
||||
projectId: this.host.createSHA256Hash(project.projectName),
|
||||
fileStats: countEachFileTypes(project.getScriptInfos()),
|
||||
fileStats: countEachFileTypes(project.getScriptInfos(), /*includeSizes*/ true),
|
||||
compilerOptions: convertCompilerOptionsForTelemetry(project.getCompilationSettings()),
|
||||
typeAcquisition: convertTypeAcquisition(project.getTypeAcquisition()),
|
||||
extends: projectOptions && projectOptions.configHasExtendsProperty,
|
||||
@@ -1925,7 +1980,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private createInferredProject(currentDirectory: string | undefined, isSingleInferredProject?: boolean, projectRootPath?: NormalizedPath): InferredProject {
|
||||
const compilerOptions = projectRootPath && this.compilerOptionsForInferredProjectsPerProjectRoot.get(projectRootPath) || this.compilerOptionsForInferredProjects;
|
||||
const compilerOptions = projectRootPath && this.compilerOptionsForInferredProjectsPerProjectRoot.get(projectRootPath) || this.compilerOptionsForInferredProjects!; // TODO: GH#18217
|
||||
const project = new InferredProject(this, this.documentRegistry, compilerOptions, projectRootPath, currentDirectory, this.currentPluginConfigOverrides);
|
||||
if (isSingleInferredProject) {
|
||||
this.inferredProjects.unshift(project);
|
||||
@@ -2184,6 +2239,150 @@ namespace ts.server {
|
||||
return this.filenameToScriptInfo.get(fileName);
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getDocumentPositionMapper(project: Project, generatedFileName: string, sourceFileName?: string): DocumentPositionMapper | undefined {
|
||||
// Since declaration info and map file watches arent updating project's directory structure host (which can cache file structure) use host
|
||||
const declarationInfo = this.getOrCreateScriptInfoNotOpenedByClient(generatedFileName, project.currentDirectory, this.host);
|
||||
if (!declarationInfo) return undefined;
|
||||
|
||||
// Try to get from cache
|
||||
declarationInfo.getSnapshot(); // Ensure synchronized
|
||||
if (isString(declarationInfo.sourceMapFilePath)) {
|
||||
// Ensure mapper is synchronized
|
||||
const sourceMapFileInfo = this.getScriptInfoForPath(declarationInfo.sourceMapFilePath);
|
||||
if (sourceMapFileInfo) {
|
||||
sourceMapFileInfo.getSnapshot();
|
||||
if (sourceMapFileInfo.documentPositionMapper !== undefined) {
|
||||
sourceMapFileInfo.sourceInfos = this.addSourceInfoToSourceMap(sourceFileName, project, sourceMapFileInfo.sourceInfos);
|
||||
return sourceMapFileInfo.documentPositionMapper ? sourceMapFileInfo.documentPositionMapper : undefined;
|
||||
}
|
||||
}
|
||||
declarationInfo.sourceMapFilePath = undefined;
|
||||
}
|
||||
else if (declarationInfo.sourceMapFilePath) {
|
||||
declarationInfo.sourceMapFilePath.sourceInfos = this.addSourceInfoToSourceMap(sourceFileName, project, declarationInfo.sourceMapFilePath.sourceInfos);
|
||||
return undefined;
|
||||
}
|
||||
else if (declarationInfo.sourceMapFilePath !== undefined) {
|
||||
// Doesnt have sourceMap
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Create the mapper
|
||||
let sourceMapFileInfo: ScriptInfo | undefined;
|
||||
let mapFileNameFromDeclarationInfo: string | undefined;
|
||||
|
||||
let readMapFile: ReadMapFile | undefined = (mapFileName, mapFileNameFromDts) => {
|
||||
const mapInfo = this.getOrCreateScriptInfoNotOpenedByClient(mapFileName, project.currentDirectory, this.host);
|
||||
if (!mapInfo) {
|
||||
mapFileNameFromDeclarationInfo = mapFileNameFromDts;
|
||||
return undefined;
|
||||
}
|
||||
sourceMapFileInfo = mapInfo;
|
||||
const snap = mapInfo.getSnapshot();
|
||||
if (mapInfo.documentPositionMapper !== undefined) return mapInfo.documentPositionMapper;
|
||||
return snap.getText(0, snap.getLength());
|
||||
};
|
||||
const projectName = project.projectName;
|
||||
const documentPositionMapper = getDocumentPositionMapper(
|
||||
{ getCanonicalFileName: this.toCanonicalFileName, log: s => this.logger.info(s), getSourceFileLike: f => this.getSourceFileLike(f, projectName, declarationInfo) },
|
||||
declarationInfo.fileName,
|
||||
declarationInfo.getLineInfo(),
|
||||
readMapFile
|
||||
);
|
||||
readMapFile = undefined; // Remove ref to project
|
||||
if (sourceMapFileInfo) {
|
||||
declarationInfo.sourceMapFilePath = sourceMapFileInfo.path;
|
||||
sourceMapFileInfo.declarationInfoPath = declarationInfo.path;
|
||||
sourceMapFileInfo.documentPositionMapper = documentPositionMapper || false;
|
||||
sourceMapFileInfo.sourceInfos = this.addSourceInfoToSourceMap(sourceFileName, project, sourceMapFileInfo.sourceInfos);
|
||||
}
|
||||
else if (mapFileNameFromDeclarationInfo) {
|
||||
declarationInfo.sourceMapFilePath = {
|
||||
watcher: this.addMissingSourceMapFile(
|
||||
project.currentDirectory === this.currentDirectory ?
|
||||
mapFileNameFromDeclarationInfo :
|
||||
getNormalizedAbsolutePath(mapFileNameFromDeclarationInfo, project.currentDirectory),
|
||||
declarationInfo.path
|
||||
),
|
||||
sourceInfos: this.addSourceInfoToSourceMap(sourceFileName, project)
|
||||
};
|
||||
}
|
||||
else {
|
||||
declarationInfo.sourceMapFilePath = false;
|
||||
}
|
||||
return documentPositionMapper;
|
||||
}
|
||||
|
||||
private addSourceInfoToSourceMap(sourceFileName: string | undefined, project: Project, sourceInfos?: Map<true>) {
|
||||
if (sourceFileName) {
|
||||
// Attach as source
|
||||
const sourceInfo = this.getOrCreateScriptInfoNotOpenedByClient(sourceFileName, project.currentDirectory, project.directoryStructureHost)!;
|
||||
(sourceInfos || (sourceInfos = createMap())).set(sourceInfo.path, true);
|
||||
}
|
||||
return sourceInfos;
|
||||
}
|
||||
|
||||
private addMissingSourceMapFile(mapFileName: string, declarationInfoPath: Path) {
|
||||
const fileWatcher = this.watchFactory.watchFile(
|
||||
this.host,
|
||||
mapFileName,
|
||||
() => {
|
||||
const declarationInfo = this.getScriptInfoForPath(declarationInfoPath);
|
||||
if (declarationInfo && declarationInfo.sourceMapFilePath && !isString(declarationInfo.sourceMapFilePath)) {
|
||||
// Update declaration and source projects
|
||||
this.delayUpdateProjectGraphs(declarationInfo.containingProjects);
|
||||
this.delayUpdateSourceInfoProjects(declarationInfo.sourceMapFilePath.sourceInfos);
|
||||
declarationInfo.closeSourceMapFileWatcher();
|
||||
}
|
||||
},
|
||||
PollingInterval.High,
|
||||
WatchType.MissingSourceMapFile,
|
||||
);
|
||||
return fileWatcher;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getSourceFileLike(fileName: string, projectNameOrProject: string | Project, declarationInfo?: ScriptInfo) {
|
||||
const project = (projectNameOrProject as Project).projectName ? projectNameOrProject as Project : this.findProject(projectNameOrProject as string);
|
||||
if (project) {
|
||||
const path = project.toPath(fileName);
|
||||
const sourceFile = project.getSourceFile(path);
|
||||
if (sourceFile && sourceFile.resolvedPath === path) return sourceFile;
|
||||
}
|
||||
|
||||
// Need to look for other files.
|
||||
const info = this.getOrCreateScriptInfoNotOpenedByClient(fileName, (project || this).currentDirectory, project ? project.directoryStructureHost : this.host);
|
||||
if (!info) return undefined;
|
||||
|
||||
// Attach as source
|
||||
if (declarationInfo && isString(declarationInfo.sourceMapFilePath) && info !== declarationInfo) {
|
||||
const sourceMapInfo = this.getScriptInfoForPath(declarationInfo.sourceMapFilePath);
|
||||
if (sourceMapInfo) {
|
||||
(sourceMapInfo.sourceInfos || (sourceMapInfo.sourceInfos = createMap())).set(info.path, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Key doesnt matter since its only for text and lines
|
||||
if (info.cacheSourceFile) return info.cacheSourceFile.sourceFile;
|
||||
|
||||
// Create sourceFileLike
|
||||
if (!info.sourceFileLike) {
|
||||
info.sourceFileLike = {
|
||||
get text() {
|
||||
Debug.fail("shouldnt need text");
|
||||
return "";
|
||||
},
|
||||
getLineAndCharacterOfPosition: pos => {
|
||||
const lineOffset = info.positionToLineOffset(pos);
|
||||
return { line: lineOffset.line - 1, character: lineOffset.offset - 1 };
|
||||
},
|
||||
getPositionOfLineAndCharacter: (line, character, allowEdits) => info.lineOffsetToPosition(line + 1, character + 1, allowEdits)
|
||||
};
|
||||
}
|
||||
return info.sourceFileLike;
|
||||
}
|
||||
|
||||
setHostConfiguration(args: protocol.ConfigureRequestArguments) {
|
||||
if (args.file) {
|
||||
const info = this.getScriptInfoForNormalizedPath(toNormalizedPath(args.file));
|
||||
@@ -2405,7 +2604,7 @@ namespace ts.server {
|
||||
|
||||
/** @internal */
|
||||
fileExists(fileName: NormalizedPath): boolean {
|
||||
return this.filenameToScriptInfo.has(fileName) || this.host.fileExists(fileName);
|
||||
return !!this.getScriptInfoForNormalizedPath(fileName) || this.host.fileExists(fileName);
|
||||
}
|
||||
|
||||
private findExternalProjectContainingOpenScriptInfo(info: ScriptInfo): ExternalProject | undefined {
|
||||
@@ -2479,13 +2678,7 @@ namespace ts.server {
|
||||
// when some file/s were closed which resulted in project removal.
|
||||
// It was then postponed to cleanup these script infos so that they can be reused if
|
||||
// the file from that old project is reopened because of opening file from here.
|
||||
this.filenameToScriptInfo.forEach(info => {
|
||||
if (!info.isScriptOpen() && info.isOrphan()) {
|
||||
// if there are not projects that include this script info - delete it
|
||||
this.stopWatchingScriptInfo(info);
|
||||
this.deleteScriptInfo(info);
|
||||
}
|
||||
});
|
||||
this.removeOrphanScriptInfos();
|
||||
|
||||
this.printProjects();
|
||||
|
||||
@@ -2528,6 +2721,57 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
private removeOrphanScriptInfos() {
|
||||
const toRemoveScriptInfos = cloneMap(this.filenameToScriptInfo);
|
||||
this.filenameToScriptInfo.forEach(info => {
|
||||
// If script info is open or orphan, retain it and its dependencies
|
||||
if (!info.isScriptOpen() && info.isOrphan()) {
|
||||
// Otherwise if there is any source info that is alive, this alive too
|
||||
if (!info.sourceMapFilePath) return;
|
||||
let sourceInfos: Map<true> | undefined;
|
||||
if (isString(info.sourceMapFilePath)) {
|
||||
const sourceMapInfo = this.getScriptInfoForPath(info.sourceMapFilePath);
|
||||
sourceInfos = sourceMapInfo && sourceMapInfo.sourceInfos;
|
||||
}
|
||||
else {
|
||||
sourceInfos = info.sourceMapFilePath.sourceInfos;
|
||||
}
|
||||
if (!sourceInfos) return;
|
||||
if (!forEachKey(sourceInfos, path => {
|
||||
const info = this.getScriptInfoForPath(path as Path);
|
||||
return !!info && (info.isScriptOpen() || !info.isOrphan());
|
||||
})) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Retain this script info
|
||||
toRemoveScriptInfos.delete(info.path);
|
||||
if (info.sourceMapFilePath) {
|
||||
let sourceInfos: Map<true> | undefined;
|
||||
if (isString(info.sourceMapFilePath)) {
|
||||
// And map file info and source infos
|
||||
toRemoveScriptInfos.delete(info.sourceMapFilePath);
|
||||
const sourceMapInfo = this.getScriptInfoForPath(info.sourceMapFilePath);
|
||||
sourceInfos = sourceMapInfo && sourceMapInfo.sourceInfos;
|
||||
}
|
||||
else {
|
||||
sourceInfos = info.sourceMapFilePath.sourceInfos;
|
||||
}
|
||||
if (sourceInfos) {
|
||||
sourceInfos.forEach((_value, path) => toRemoveScriptInfos.delete(path));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
toRemoveScriptInfos.forEach(info => {
|
||||
// if there are not projects that include this script info - delete it
|
||||
this.stopWatchingScriptInfo(info);
|
||||
this.deleteScriptInfo(info);
|
||||
info.closeSourceMapFileWatcher();
|
||||
});
|
||||
}
|
||||
|
||||
private telemetryOnOpenFile(scriptInfo: ScriptInfo): void {
|
||||
if (this.syntaxOnly || !this.eventHandler || !scriptInfo.isJavaScript() || !addToSeen(this.allJsFilesForOpenFileTelemetry, scriptInfo.path)) {
|
||||
return;
|
||||
|
||||
+55
-25
@@ -10,26 +10,43 @@ namespace ts.server {
|
||||
export type Mutable<T> = { -readonly [K in keyof T]: T[K]; };
|
||||
|
||||
/* @internal */
|
||||
export function countEachFileTypes(infos: ScriptInfo[]): FileStats {
|
||||
const result: Mutable<FileStats> = { js: 0, jsx: 0, ts: 0, tsx: 0, dts: 0, deferred: 0 };
|
||||
export function countEachFileTypes(infos: ScriptInfo[], includeSizes = false): FileStats {
|
||||
const result: Mutable<FileStats> = {
|
||||
js: 0, jsSize: 0,
|
||||
jsx: 0, jsxSize: 0,
|
||||
ts: 0, tsSize: 0,
|
||||
tsx: 0, tsxSize: 0,
|
||||
dts: 0, dtsSize: 0,
|
||||
deferred: 0, deferredSize: 0,
|
||||
};
|
||||
for (const info of infos) {
|
||||
const fileSize = includeSizes ? info.getTelemetryFileSize() : 0;
|
||||
switch (info.scriptKind) {
|
||||
case ScriptKind.JS:
|
||||
result.js += 1;
|
||||
result.jsSize! += fileSize;
|
||||
break;
|
||||
case ScriptKind.JSX:
|
||||
result.jsx += 1;
|
||||
result.jsxSize! += fileSize;
|
||||
break;
|
||||
case ScriptKind.TS:
|
||||
fileExtensionIs(info.fileName, Extension.Dts)
|
||||
? result.dts += 1
|
||||
: result.ts += 1;
|
||||
if (fileExtensionIs(info.fileName, Extension.Dts)) {
|
||||
result.dts += 1;
|
||||
result.dtsSize! += fileSize;
|
||||
}
|
||||
else {
|
||||
result.ts += 1;
|
||||
result.tsSize! += fileSize;
|
||||
}
|
||||
break;
|
||||
case ScriptKind.TSX:
|
||||
result.tsx += 1;
|
||||
result.tsxSize! += fileSize;
|
||||
break;
|
||||
case ScriptKind.Deferred:
|
||||
result.deferred += 1;
|
||||
result.deferredSize! += fileSize;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -95,9 +112,9 @@ namespace ts.server {
|
||||
export abstract class Project implements LanguageServiceHost, ModuleResolutionHost {
|
||||
private rootFiles: ScriptInfo[] = [];
|
||||
private rootFilesMap: Map<ProjectRoot> = createMap<ProjectRoot>();
|
||||
private program: Program;
|
||||
private externalFiles: SortedReadonlyArray<string>;
|
||||
private missingFilesMap: Map<FileWatcher>;
|
||||
private program: Program | undefined;
|
||||
private externalFiles: SortedReadonlyArray<string> | undefined;
|
||||
private missingFilesMap: Map<FileWatcher> | undefined;
|
||||
private plugins: PluginModuleWithName[] = [];
|
||||
|
||||
/*@internal*/
|
||||
@@ -124,7 +141,7 @@ namespace ts.server {
|
||||
readonly realpath?: (path: string) => string;
|
||||
|
||||
/*@internal*/
|
||||
hasInvalidatedResolution: HasInvalidatedResolution;
|
||||
hasInvalidatedResolution: HasInvalidatedResolution | undefined;
|
||||
|
||||
/*@internal*/
|
||||
resolutionCache: ResolutionCache;
|
||||
@@ -137,7 +154,7 @@ namespace ts.server {
|
||||
/**
|
||||
* Set of files that was returned from the last call to getChangesSinceVersion.
|
||||
*/
|
||||
private lastReportedFileNames: Map<true>;
|
||||
private lastReportedFileNames: Map<true> | undefined;
|
||||
/**
|
||||
* Last version that was reported.
|
||||
*/
|
||||
@@ -486,6 +503,16 @@ namespace ts.server {
|
||||
return this.getLanguageService().getSourceMapper();
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getDocumentPositionMapper(generatedFileName: string, sourceFileName?: string): DocumentPositionMapper | undefined {
|
||||
return this.projectService.getDocumentPositionMapper(this, generatedFileName, sourceFileName);
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getSourceFileLike(fileName: string) {
|
||||
return this.projectService.getSourceFileLike(fileName, this);
|
||||
}
|
||||
|
||||
private shouldEmitFile(scriptInfo: ScriptInfo) {
|
||||
return scriptInfo && !scriptInfo.isDynamicOrHasMixedContent();
|
||||
}
|
||||
@@ -495,8 +522,8 @@ namespace ts.server {
|
||||
return [];
|
||||
}
|
||||
updateProjectIfDirty(this);
|
||||
this.builderState = BuilderState.create(this.program, this.projectService.toCanonicalFileName, this.builderState);
|
||||
return mapDefined(BuilderState.getFilesAffectedBy(this.builderState, this.program, scriptInfo.path, this.cancellationToken, data => this.projectService.host.createHash!(data)), // TODO: GH#18217
|
||||
this.builderState = BuilderState.create(this.program!, this.projectService.toCanonicalFileName, this.builderState);
|
||||
return mapDefined(BuilderState.getFilesAffectedBy(this.builderState, this.program!, scriptInfo.path, this.cancellationToken, data => this.projectService.host.createHash!(data)), // TODO: GH#18217
|
||||
sourceFile => this.shouldEmitFile(this.projectService.getScriptInfoForPath(sourceFile.path)!) ? sourceFile.fileName : undefined);
|
||||
}
|
||||
|
||||
@@ -577,7 +604,7 @@ namespace ts.server {
|
||||
|
||||
/* @internal */
|
||||
getSourceFileOrConfigFile(path: Path): SourceFile | undefined {
|
||||
const options = this.program.getCompilerOptions();
|
||||
const options = this.program!.getCompilerOptions();
|
||||
return path === options.configFilePath ? options.configFile : this.getSourceFile(path);
|
||||
}
|
||||
|
||||
@@ -664,7 +691,7 @@ namespace ts.server {
|
||||
// if language service is not enabled - return just root files
|
||||
return this.rootFiles;
|
||||
}
|
||||
return map(this.program.getSourceFiles(), sourceFile => {
|
||||
return map(this.program!.getSourceFiles(), sourceFile => {
|
||||
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!;
|
||||
@@ -732,7 +759,10 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
containsScriptInfo(info: ScriptInfo): boolean {
|
||||
return this.isRoot(info) || (this.program && this.program.getSourceFileByPath(info.path) !== undefined);
|
||||
if (this.isRoot(info)) return true;
|
||||
if (!this.program) return false;
|
||||
const file = this.program.getSourceFileByPath(info.path);
|
||||
return !!file && file.resolvedPath === info.path;
|
||||
}
|
||||
|
||||
containsFile(filename: NormalizedPath, requireOpen?: boolean): boolean {
|
||||
@@ -828,7 +858,7 @@ namespace ts.server {
|
||||
// (can reuse cached imports for files that were not changed)
|
||||
// 4. compilation settings were changed in the way that might affect module resolution - drop all caches and collect all data from the scratch
|
||||
if (hasNewProgram || changedFiles.length) {
|
||||
this.lastCachedUnresolvedImportsList = getUnresolvedImports(this.program, this.cachedUnresolvedImportsPerFile);
|
||||
this.lastCachedUnresolvedImportsList = getUnresolvedImports(this.program!, this.cachedUnresolvedImportsPerFile);
|
||||
}
|
||||
|
||||
this.projectService.typingsCache.enqueueInstallTypingsForProject(this, this.lastCachedUnresolvedImportsList, hasAddedorRemovedFiles);
|
||||
@@ -855,7 +885,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
getCurrentProgram() {
|
||||
getCurrentProgram(): Program | undefined {
|
||||
return this.program;
|
||||
}
|
||||
|
||||
@@ -894,7 +924,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
oldProgram.forEachResolvedProjectReference((resolvedProjectReference, resolvedProjectReferencePath) => {
|
||||
if (resolvedProjectReference && !this.program.getResolvedProjectReferenceByPath(resolvedProjectReferencePath)) {
|
||||
if (resolvedProjectReference && !this.program!.getResolvedProjectReferenceByPath(resolvedProjectReferencePath)) {
|
||||
this.detachScriptInfoFromProject(resolvedProjectReference.sourceFile.fileName);
|
||||
}
|
||||
});
|
||||
@@ -950,8 +980,8 @@ namespace ts.server {
|
||||
this.getCachedDirectoryStructureHost().addOrDeleteFile(fileName, missingFilePath, eventKind);
|
||||
}
|
||||
|
||||
if (eventKind === FileWatcherEventKind.Created && this.missingFilesMap.has(missingFilePath)) {
|
||||
this.missingFilesMap.delete(missingFilePath);
|
||||
if (eventKind === FileWatcherEventKind.Created && this.missingFilesMap!.has(missingFilePath)) {
|
||||
this.missingFilesMap!.delete(missingFilePath);
|
||||
fileWatcher.close();
|
||||
|
||||
// When a missing file is created, we should update the graph.
|
||||
@@ -966,7 +996,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private isWatchedMissingFile(path: Path) {
|
||||
return this.missingFilesMap && this.missingFilesMap.has(path);
|
||||
return !!this.missingFilesMap && this.missingFilesMap.has(path);
|
||||
}
|
||||
|
||||
getScriptInfoForNormalizedPath(fileName: NormalizedPath): ScriptInfo | undefined {
|
||||
@@ -1327,14 +1357,14 @@ namespace ts.server {
|
||||
* Otherwise it will create an InferredProject.
|
||||
*/
|
||||
export class ConfiguredProject extends Project {
|
||||
private typeAcquisition: TypeAcquisition;
|
||||
private typeAcquisition!: TypeAcquisition; // TODO: GH#18217
|
||||
/* @internal */
|
||||
configFileWatcher: FileWatcher | undefined;
|
||||
private directoriesWatchedForWildcards: Map<WildcardDirectoryWatcher> | undefined;
|
||||
readonly canonicalConfigFilePath: NormalizedPath;
|
||||
|
||||
/* @internal */
|
||||
pendingReload: ConfigFileProgramReloadLevel;
|
||||
pendingReload: ConfigFileProgramReloadLevel | undefined;
|
||||
/* @internal */
|
||||
pendingReloadReason: string | undefined;
|
||||
|
||||
@@ -1342,7 +1372,7 @@ namespace ts.server {
|
||||
configFileSpecs: ConfigFileSpecs | undefined;
|
||||
|
||||
/*@internal*/
|
||||
canConfigFileJsonReportNoInputFiles: boolean;
|
||||
canConfigFileJsonReportNoInputFiles = false;
|
||||
|
||||
/** Ref count to the project when opened from external project */
|
||||
private externalProjectRefCount = 0;
|
||||
@@ -1573,7 +1603,7 @@ namespace ts.server {
|
||||
*/
|
||||
export class ExternalProject extends Project {
|
||||
excludedFiles: ReadonlyArray<NormalizedPath> = [];
|
||||
private typeAcquisition: TypeAcquisition;
|
||||
private typeAcquisition!: TypeAcquisition; // TODO: GH#18217
|
||||
/*@internal*/
|
||||
constructor(public externalProjectName: string,
|
||||
projectService: ProjectService,
|
||||
|
||||
+113
-17
@@ -25,18 +25,26 @@ namespace ts.server {
|
||||
*/
|
||||
private lineMap: number[] | undefined;
|
||||
|
||||
/**
|
||||
* When a large file is loaded, text will artificially be set to "".
|
||||
* In order to be able to report correct telemetry, we store the actual
|
||||
* file size in this case. (In other cases where text === "", e.g.
|
||||
* for mixed content or dynamic files, fileSize will be undefined.)
|
||||
*/
|
||||
private fileSize: number | undefined;
|
||||
|
||||
/**
|
||||
* True if the text is for the file thats open in the editor
|
||||
*/
|
||||
public isOpen: boolean;
|
||||
public isOpen = false;
|
||||
/**
|
||||
* True if the text present is the text from the file on the disk
|
||||
*/
|
||||
private ownFileText: boolean;
|
||||
private ownFileText = false;
|
||||
/**
|
||||
* True when reloading contents of file from the disk is pending
|
||||
*/
|
||||
private pendingReloadFromDisk: boolean;
|
||||
private pendingReloadFromDisk = false;
|
||||
|
||||
constructor(private readonly host: ServerHost, private readonly fileName: NormalizedPath, initialVersion: ScriptInfoVersion | undefined, private readonly info: ScriptInfo) {
|
||||
this.version = initialVersion || { svc: 0, text: 0 };
|
||||
@@ -56,10 +64,22 @@ namespace ts.server {
|
||||
this.switchToScriptVersionCache();
|
||||
}
|
||||
|
||||
private resetSourceMapInfo() {
|
||||
this.info.sourceFileLike = undefined;
|
||||
this.info.closeSourceMapFileWatcher();
|
||||
this.info.sourceMapFilePath = undefined;
|
||||
this.info.declarationInfoPath = undefined;
|
||||
this.info.sourceInfos = undefined;
|
||||
this.info.documentPositionMapper = undefined;
|
||||
}
|
||||
|
||||
/** Public for testing */
|
||||
public useText(newText?: string) {
|
||||
this.svc = undefined;
|
||||
this.text = newText;
|
||||
this.lineMap = undefined;
|
||||
this.fileSize = undefined;
|
||||
this.resetSourceMapInfo();
|
||||
this.version.text++;
|
||||
}
|
||||
|
||||
@@ -68,13 +88,15 @@ namespace ts.server {
|
||||
this.ownFileText = false;
|
||||
this.text = undefined;
|
||||
this.lineMap = undefined;
|
||||
this.fileSize = undefined;
|
||||
this.resetSourceMapInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the contents as newText
|
||||
* returns true if text changed
|
||||
*/
|
||||
public reload(newText: string) {
|
||||
public reload(newText: string): boolean {
|
||||
Debug.assert(newText !== undefined);
|
||||
|
||||
// Reload always has fresh content
|
||||
@@ -91,6 +113,8 @@ namespace ts.server {
|
||||
this.ownFileText = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,7 +122,9 @@ namespace ts.server {
|
||||
* returns true if text changed
|
||||
*/
|
||||
public reloadWithFileText(tempFileName?: string) {
|
||||
const reloaded = this.reload(this.getFileText(tempFileName));
|
||||
const { text: newText, fileSize } = this.getFileTextAndSize(tempFileName);
|
||||
const reloaded = this.reload(newText);
|
||||
this.fileSize = fileSize; // NB: after reload since reload clears it
|
||||
this.ownFileText = !tempFileName || tempFileName === this.fileName;
|
||||
return reloaded;
|
||||
}
|
||||
@@ -118,14 +144,31 @@ namespace ts.server {
|
||||
this.pendingReloadFromDisk = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* For telemetry purposes, we would like to be able to report the size of the file.
|
||||
* However, we do not want telemetry to require extra file I/O so we report a size
|
||||
* that may be stale (e.g. may not reflect change made on disk since the last reload).
|
||||
* NB: Will read from disk if the file contents have never been loaded because
|
||||
* telemetry falsely indicating size 0 would be counter-productive.
|
||||
*/
|
||||
public getTelemetryFileSize(): number {
|
||||
return !!this.fileSize
|
||||
? this.fileSize
|
||||
: !!this.text // Check text before svc because its length is cheaper
|
||||
? this.text.length // Could be wrong if this.pendingReloadFromDisk
|
||||
: !!this.svc
|
||||
? this.svc.getSnapshot().getLength() // Could be wrong if this.pendingReloadFromDisk
|
||||
: this.getSnapshot().getLength(); // Should be strictly correct
|
||||
}
|
||||
|
||||
public getSnapshot(): IScriptSnapshot {
|
||||
return this.useScriptVersionCacheIfValidOrOpen()
|
||||
? this.svc!.getSnapshot()
|
||||
: ScriptSnapshot.fromString(this.getOrLoadText());
|
||||
}
|
||||
|
||||
public getLineInfo(line: number): AbsolutePositionAndLineText {
|
||||
return this.switchToScriptVersionCache().getLineInfo(line);
|
||||
public getAbsolutePositionAndLineText(line: number): AbsolutePositionAndLineText {
|
||||
return this.switchToScriptVersionCache().getAbsolutePositionAndLineText(line);
|
||||
}
|
||||
/**
|
||||
* @param line 0 based index
|
||||
@@ -144,9 +187,9 @@ namespace ts.server {
|
||||
* @param line 1 based index
|
||||
* @param offset 1 based index
|
||||
*/
|
||||
lineOffsetToPosition(line: number, offset: number): number {
|
||||
lineOffsetToPosition(line: number, offset: number, allowEdits?: true): number {
|
||||
if (!this.useScriptVersionCacheIfValidOrOpen()) {
|
||||
return computePositionOfLineAndCharacter(this.getLineMap(), line - 1, offset - 1, this.text);
|
||||
return computePositionOfLineAndCharacter(this.getLineMap(), line - 1, offset - 1, this.text, allowEdits);
|
||||
}
|
||||
|
||||
// TODO: assert this offset is actually on the line
|
||||
@@ -161,7 +204,7 @@ namespace ts.server {
|
||||
return this.svc!.positionToLineOffset(position);
|
||||
}
|
||||
|
||||
private getFileText(tempFileName?: string) {
|
||||
private getFileTextAndSize(tempFileName?: string): { text: string, fileSize?: number } {
|
||||
let text: string;
|
||||
const fileName = tempFileName || this.fileName;
|
||||
const getText = () => text === undefined ? (text = this.host.readFile(fileName) || "") : text;
|
||||
@@ -173,10 +216,10 @@ namespace ts.server {
|
||||
const service = this.info.containingProjects[0].projectService;
|
||||
service.logger.info(`Skipped loading contents of large file ${fileName} for info ${this.info.fileName}: fileSize: ${fileSize}`);
|
||||
this.info.containingProjects[0].projectService.sendLargeFileReferencedEvent(fileName, fileSize);
|
||||
return "";
|
||||
return { text: "", fileSize };
|
||||
}
|
||||
}
|
||||
return getText();
|
||||
return { text: getText() };
|
||||
}
|
||||
|
||||
private switchToScriptVersionCache(): ScriptVersionCache {
|
||||
@@ -214,6 +257,17 @@ namespace ts.server {
|
||||
Debug.assert(!this.svc, "ScriptVersionCache should not be set");
|
||||
return this.lineMap || (this.lineMap = computeLineStarts(this.getOrLoadText()));
|
||||
}
|
||||
|
||||
getLineInfo(): LineInfo {
|
||||
if (this.svc) {
|
||||
return {
|
||||
getLineCount: () => this.svc!.getLineCount(),
|
||||
getLineText: line => this.svc!.getAbsolutePositionAndLineText(line + 1).lineText!
|
||||
};
|
||||
}
|
||||
const lineMap = this.getLineMap();
|
||||
return getLineInfo(this.text!, lineMap);
|
||||
}
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
@@ -227,6 +281,12 @@ namespace ts.server {
|
||||
sourceFile: SourceFile;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export interface SourceMapFileWatcher {
|
||||
watcher: FileWatcher;
|
||||
sourceInfos?: Map<true>;
|
||||
}
|
||||
|
||||
export class ScriptInfo {
|
||||
/**
|
||||
* All projects that include this file
|
||||
@@ -247,11 +307,25 @@ namespace ts.server {
|
||||
private realpath: Path | undefined;
|
||||
|
||||
/*@internal*/
|
||||
cacheSourceFile: DocumentRegistrySourceFileCache;
|
||||
cacheSourceFile: DocumentRegistrySourceFileCache | undefined;
|
||||
|
||||
/*@internal*/
|
||||
mTime?: number;
|
||||
|
||||
/*@internal*/
|
||||
sourceFileLike?: SourceFileLike;
|
||||
|
||||
/*@internal*/
|
||||
sourceMapFilePath?: Path | SourceMapFileWatcher | false;
|
||||
|
||||
// Present on sourceMapFile info
|
||||
/*@internal*/
|
||||
declarationInfoPath?: Path;
|
||||
/*@internal*/
|
||||
sourceInfos?: Map<true>;
|
||||
/*@internal*/
|
||||
documentPositionMapper?: DocumentPositionMapper | false;
|
||||
|
||||
constructor(
|
||||
private readonly host: ServerHost,
|
||||
readonly fileName: NormalizedPath,
|
||||
@@ -276,6 +350,11 @@ namespace ts.server {
|
||||
return this.textStorage.version;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getTelemetryFileSize() {
|
||||
return this.textStorage.getTelemetryFileSize();
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
public isDynamicOrHasMixedContent() {
|
||||
return this.hasMixedContent || this.isDynamic;
|
||||
@@ -484,8 +563,8 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getLineInfo(line: number): AbsolutePositionAndLineText {
|
||||
return this.textStorage.getLineInfo(line);
|
||||
getAbsolutePositionAndLineText(line: number): AbsolutePositionAndLineText {
|
||||
return this.textStorage.getAbsolutePositionAndLineText(line);
|
||||
}
|
||||
|
||||
editContent(start: number, end: number, newText: string): void {
|
||||
@@ -514,8 +593,12 @@ namespace ts.server {
|
||||
* @param line 1 based index
|
||||
* @param offset 1 based index
|
||||
*/
|
||||
lineOffsetToPosition(line: number, offset: number): number {
|
||||
return this.textStorage.lineOffsetToPosition(line, offset);
|
||||
lineOffsetToPosition(line: number, offset: number): number;
|
||||
/*@internal*/
|
||||
// tslint:disable-next-line:unified-signatures
|
||||
lineOffsetToPosition(line: number, offset: number, allowEdits?: true): number;
|
||||
lineOffsetToPosition(line: number, offset: number, allowEdits?: true): number {
|
||||
return this.textStorage.lineOffsetToPosition(line, offset, allowEdits);
|
||||
}
|
||||
|
||||
positionToLineOffset(position: number): protocol.Location {
|
||||
@@ -525,5 +608,18 @@ namespace ts.server {
|
||||
public isJavaScript() {
|
||||
return this.scriptKind === ScriptKind.JS || this.scriptKind === ScriptKind.JSX;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getLineInfo(): LineInfo {
|
||||
return this.textStorage.getLineInfo();
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
closeSourceMapFileWatcher() {
|
||||
if (this.sourceMapFilePath && !isString(this.sourceMapFilePath)) {
|
||||
closeFileWatcherOf(this.sourceMapFilePath);
|
||||
this.sourceMapFilePath = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,11 +41,11 @@ namespace ts.server {
|
||||
// path to start of range
|
||||
private readonly startPath: LineCollection[];
|
||||
private readonly endBranch: LineCollection[] = [];
|
||||
private branchNode: LineNode;
|
||||
private branchNode: LineNode | undefined;
|
||||
// path to current node
|
||||
private readonly stack: LineNode[];
|
||||
private state = CharRangeSection.Entire;
|
||||
private lineCollectionAtBranch: LineCollection;
|
||||
private lineCollectionAtBranch: LineCollection | undefined;
|
||||
private initialText = "";
|
||||
private trailingText = "";
|
||||
|
||||
@@ -308,8 +308,8 @@ namespace ts.server {
|
||||
return this._getSnapshot().version;
|
||||
}
|
||||
|
||||
getLineInfo(line: number): AbsolutePositionAndLineText {
|
||||
return this._getSnapshot().index.lineNumberToInfo(line);
|
||||
getAbsolutePositionAndLineText(oneBasedLine: number): AbsolutePositionAndLineText {
|
||||
return this._getSnapshot().index.lineNumberToInfo(oneBasedLine);
|
||||
}
|
||||
|
||||
lineOffsetToPosition(line: number, column: number): number {
|
||||
@@ -348,6 +348,10 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
getLineCount() {
|
||||
return this._getSnapshot().index.getLineCount();
|
||||
}
|
||||
|
||||
static fromString(script: string) {
|
||||
const svc = new ScriptVersionCache();
|
||||
const snap = new LineIndexSnapshot(0, svc, new LineIndex());
|
||||
@@ -383,7 +387,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
export class LineIndex {
|
||||
root: LineNode;
|
||||
root!: LineNode;
|
||||
// set this to true to check each edit for accuracy
|
||||
checkEdits = false;
|
||||
|
||||
@@ -400,8 +404,12 @@ namespace ts.server {
|
||||
return this.root.charOffsetToLineInfo(1, position);
|
||||
}
|
||||
|
||||
getLineCount() {
|
||||
return this.root.lineCount();
|
||||
}
|
||||
|
||||
lineNumberToInfo(oneBasedLine: number): AbsolutePositionAndLineText {
|
||||
const lineCount = this.root.lineCount();
|
||||
const lineCount = this.getLineCount();
|
||||
if (oneBasedLine <= lineCount) {
|
||||
const { position, leaf } = this.root.lineNumberToInfo(oneBasedLine, 0);
|
||||
return { absolutePosition: position, lineText: leaf && leaf.text };
|
||||
|
||||
@@ -516,7 +516,7 @@ namespace ts.server {
|
||||
protected projectService: ProjectService;
|
||||
private changeSeq = 0;
|
||||
|
||||
private currentRequestId: number;
|
||||
private currentRequestId!: number;
|
||||
private errorCheck: MultistepOperation;
|
||||
|
||||
protected host: ServerHost;
|
||||
@@ -1474,7 +1474,7 @@ namespace ts.server {
|
||||
// only to the previous line. If all this is true, then
|
||||
// add edits necessary to properly indent the current line.
|
||||
if ((args.key === "\n") && ((!edits) || (edits.length === 0) || allEditsBeforePos(edits, position))) {
|
||||
const { lineText, absolutePosition } = scriptInfo.getLineInfo(args.line);
|
||||
const { lineText, absolutePosition } = scriptInfo.getAbsolutePositionAndLineText(args.line);
|
||||
if (lineText && lineText.search("\\S") < 0) {
|
||||
const preferredIndent = languageService.getIndentationAtPosition(file, position, formatOptions);
|
||||
let hasIndent = 0;
|
||||
@@ -1811,7 +1811,7 @@ namespace ts.server {
|
||||
return (<protocol.FileLocationRequestArgs>locationOrSpan).line !== undefined;
|
||||
}
|
||||
|
||||
private extractPositionAndRange(args: protocol.FileLocationOrRangeRequestArgs, scriptInfo: ScriptInfo): { position: number, textRange: TextRange } {
|
||||
private extractPositionOrRange(args: protocol.FileLocationOrRangeRequestArgs, scriptInfo: ScriptInfo): number | TextRange {
|
||||
let position: number | undefined;
|
||||
let textRange: TextRange | undefined;
|
||||
if (this.isLocation(args)) {
|
||||
@@ -1821,7 +1821,7 @@ namespace ts.server {
|
||||
const { startPosition, endPosition } = this.getStartAndEndPosition(args, scriptInfo);
|
||||
textRange = { pos: startPosition, end: endPosition };
|
||||
}
|
||||
return { position: position!, textRange: textRange! }; // TODO: GH#18217
|
||||
return Debug.assertDefined(position === undefined ? textRange : position);
|
||||
|
||||
function getPosition(loc: protocol.FileLocationRequestArgs) {
|
||||
return loc.position !== undefined ? loc.position : scriptInfo.lineOffsetToPosition(loc.line, loc.offset);
|
||||
@@ -1831,19 +1831,16 @@ namespace ts.server {
|
||||
private getApplicableRefactors(args: protocol.GetApplicableRefactorsRequestArgs): protocol.ApplicableRefactorInfo[] {
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
const scriptInfo = project.getScriptInfoForNormalizedPath(file)!;
|
||||
const { position, textRange } = this.extractPositionAndRange(args, scriptInfo);
|
||||
return project.getLanguageService().getApplicableRefactors(file, position || textRange, this.getPreferences(file));
|
||||
return project.getLanguageService().getApplicableRefactors(file, this.extractPositionOrRange(args, scriptInfo), this.getPreferences(file));
|
||||
}
|
||||
|
||||
private getEditsForRefactor(args: protocol.GetEditsForRefactorRequestArgs, simplifiedResult: boolean): RefactorEditInfo | protocol.RefactorEditInfo {
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
const scriptInfo = project.getScriptInfoForNormalizedPath(file)!;
|
||||
const { position, textRange } = this.extractPositionAndRange(args, scriptInfo);
|
||||
|
||||
const result = project.getLanguageService().getEditsForRefactor(
|
||||
file,
|
||||
this.getFormatOptions(file),
|
||||
position || textRange,
|
||||
this.extractPositionOrRange(args, scriptInfo),
|
||||
args.refactor,
|
||||
args.action,
|
||||
this.getPreferences(file),
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
const fixId = "addNameToNamelessParameter";
|
||||
const errorCodes = [Diagnostics.Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1.code];
|
||||
registerCodeFix({
|
||||
errorCodes,
|
||||
getCodeActions: (context) => {
|
||||
const changes = textChanges.ChangeTracker.with(context, t => makeChange(t, context.sourceFile, context.span.start));
|
||||
return [createCodeFixAction(fixId, changes, Diagnostics.Add_parameter_name, fixId, Diagnostics.Add_names_to_all_parameters_without_names)];
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => makeChange(changes, diag.file, diag.start)),
|
||||
});
|
||||
|
||||
function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number) {
|
||||
const token = getTokenAtPosition(sourceFile, pos);
|
||||
if (!isIdentifier(token)) {
|
||||
return Debug.fail("add-name-to-nameless-parameter operates on identifiers, but got a " + formatSyntaxKind(token.kind));
|
||||
}
|
||||
const param = token.parent;
|
||||
if (!isParameter(param)) {
|
||||
return Debug.fail("Tried to add a parameter name to a non-parameter: " + formatSyntaxKind(token.kind));
|
||||
}
|
||||
const i = param.parent.parameters.indexOf(param);
|
||||
Debug.assert(!param.type, "Tried to add a parameter name to a parameter that already had one.");
|
||||
Debug.assert(i > -1, "Parameter not found in parent parameter list.");
|
||||
const replacement = createParameter(
|
||||
/*decorators*/ undefined,
|
||||
param.modifiers,
|
||||
param.dotDotDotToken,
|
||||
"arg" + i,
|
||||
param.questionToken,
|
||||
createTypeReferenceNode(token, /*typeArguments*/ undefined),
|
||||
param.initializer);
|
||||
changeTracker.replaceNode(sourceFile, token, replacement);
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,9 @@ namespace ts.codefix {
|
||||
const errorCodes = [
|
||||
Diagnostics.Property_0_does_not_exist_on_type_1.code,
|
||||
Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2.code,
|
||||
Diagnostics.Property_0_is_missing_in_type_1_but_required_in_type_2.code,
|
||||
Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2.code,
|
||||
Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more.code
|
||||
];
|
||||
const fixId = "addMissingMember";
|
||||
registerCodeFix({
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
const fixId = "addMissingNewOperator";
|
||||
const errorCodes = [Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new.code];
|
||||
registerCodeFix({
|
||||
errorCodes,
|
||||
getCodeActions(context) {
|
||||
const { sourceFile, span } = context;
|
||||
const changes = textChanges.ChangeTracker.with(context, t => addMissingNewOperator(t, sourceFile, span));
|
||||
return [createCodeFixAction(fixId, changes, Diagnostics.Add_missing_new_operator_to_call, fixId, Diagnostics.Add_missing_new_operator_to_all_calls)];
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) =>
|
||||
addMissingNewOperator(changes, context.sourceFile, diag)),
|
||||
});
|
||||
|
||||
function addMissingNewOperator(changes: textChanges.ChangeTracker, sourceFile: SourceFile, span: TextSpan): void {
|
||||
const call = cast(findAncestorMatchingSpan(sourceFile, span), isCallExpression);
|
||||
const newExpression = createNew(call.expression, call.typeArguments, call.arguments);
|
||||
|
||||
changes.replaceNode(sourceFile, call, newExpression);
|
||||
}
|
||||
|
||||
function findAncestorMatchingSpan(sourceFile: SourceFile, span: TextSpan): Node {
|
||||
let token = getTokenAtPosition(sourceFile, span.start);
|
||||
const end = textSpanEnd(span);
|
||||
while (token.end < end) {
|
||||
token = token.parent;
|
||||
}
|
||||
return token;
|
||||
}
|
||||
}
|
||||
@@ -97,7 +97,7 @@ namespace ts.codefix {
|
||||
optional: boolean,
|
||||
body: Block | undefined,
|
||||
): MethodDeclaration | undefined {
|
||||
const signatureDeclaration = <MethodDeclaration>checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration, NodeBuilderFlags.SuppressAnyReturnType);
|
||||
const signatureDeclaration = <MethodDeclaration>checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration, NodeBuilderFlags.NoTruncation | NodeBuilderFlags.SuppressAnyReturnType);
|
||||
if (!signatureDeclaration) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -187,24 +187,10 @@ namespace ts.codefix {
|
||||
}
|
||||
}
|
||||
|
||||
function isApplicableFunctionForInference(declaration: FunctionLike): declaration is MethodDeclaration | FunctionDeclaration | ConstructorDeclaration {
|
||||
switch (declaration.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.Constructor:
|
||||
return true;
|
||||
case SyntaxKind.FunctionExpression:
|
||||
const parent = declaration.parent;
|
||||
return isVariableDeclaration(parent) && isIdentifier(parent.name) || !!declaration.name;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function annotateParameters(changes: textChanges.ChangeTracker, sourceFile: SourceFile, parameterDeclaration: ParameterDeclaration, containingFunction: FunctionLike, program: Program, host: LanguageServiceHost, cancellationToken: CancellationToken): void {
|
||||
if (!isIdentifier(parameterDeclaration.name) || !isApplicableFunctionForInference(containingFunction)) {
|
||||
if (!isIdentifier(parameterDeclaration.name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const parameterInferences = inferTypeForParametersFromUsage(containingFunction, sourceFile, program, cancellationToken) ||
|
||||
containingFunction.parameters.map<ParameterInference>(p => ({
|
||||
declaration: p,
|
||||
@@ -216,11 +202,14 @@ namespace ts.codefix {
|
||||
annotateJSDocParameters(changes, sourceFile, parameterInferences, program, host);
|
||||
}
|
||||
else {
|
||||
const needParens = isArrowFunction(containingFunction) && !findChildOfKind(containingFunction, SyntaxKind.OpenParenToken, sourceFile);
|
||||
if (needParens) changes.insertNodeBefore(sourceFile, first(containingFunction.parameters), createToken(SyntaxKind.OpenParenToken));
|
||||
for (const { declaration, type } of parameterInferences) {
|
||||
if (declaration && !declaration.type && !declaration.initializer) {
|
||||
annotate(changes, sourceFile, declaration, type, program, host);
|
||||
}
|
||||
}
|
||||
if (needParens) changes.insertNodeAfter(sourceFile, last(containingFunction.parameters), createToken(SyntaxKind.CloseParenToken));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,12 +331,13 @@ namespace ts.codefix {
|
||||
return InferFromReference.unifyFromContext(types, checker);
|
||||
}
|
||||
|
||||
function inferTypeForParametersFromUsage(containingFunction: FunctionLikeDeclaration, sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken): ParameterInference[] | undefined {
|
||||
function inferTypeForParametersFromUsage(containingFunction: FunctionLike, sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken): ParameterInference[] | undefined {
|
||||
let searchToken;
|
||||
switch (containingFunction.kind) {
|
||||
case SyntaxKind.Constructor:
|
||||
searchToken = findChildOfKind<Token<SyntaxKind.ConstructorKeyword>>(containingFunction, SyntaxKind.ConstructorKeyword, sourceFile);
|
||||
break;
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
const parent = containingFunction.parent;
|
||||
searchToken = isVariableDeclaration(parent) && isIdentifier(parent.name) ?
|
||||
@@ -379,8 +369,8 @@ namespace ts.codefix {
|
||||
interface UsageContext {
|
||||
isNumber?: boolean;
|
||||
isString?: boolean;
|
||||
hasNonVacuousType?: boolean;
|
||||
hasNonVacuousNonAnonymousType?: boolean;
|
||||
/** Used ambiguously, eg x + ___ or object[___]; results in string | number if no other evidence exists */
|
||||
isNumberOrString?: boolean;
|
||||
|
||||
candidateTypes?: Type[];
|
||||
properties?: UnderscoreEscapedMap<UsageContext>;
|
||||
@@ -399,7 +389,7 @@ namespace ts.codefix {
|
||||
return inferFromContext(usageContext, checker);
|
||||
}
|
||||
|
||||
export function inferTypeForParametersFromReferences(references: ReadonlyArray<Identifier>, declaration: FunctionLikeDeclaration, program: Program, cancellationToken: CancellationToken): ParameterInference[] | undefined {
|
||||
export function inferTypeForParametersFromReferences(references: ReadonlyArray<Identifier>, declaration: FunctionLike, program: Program, cancellationToken: CancellationToken): ParameterInference[] | undefined {
|
||||
const checker = program.getTypeChecker();
|
||||
if (references.length === 0) {
|
||||
return undefined;
|
||||
@@ -413,10 +403,9 @@ namespace ts.codefix {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
inferTypeFromContext(reference, checker, usageContext);
|
||||
}
|
||||
const isConstructor = declaration.kind === SyntaxKind.Constructor;
|
||||
const callContexts = isConstructor ? usageContext.constructContexts : usageContext.callContexts;
|
||||
return callContexts && declaration.parameters.map((parameter, parameterIndex): ParameterInference => {
|
||||
const types: Type[] = [];
|
||||
const callContexts = [...usageContext.constructContexts || [], ...usageContext.callContexts || []];
|
||||
return declaration.parameters.map((parameter, parameterIndex): ParameterInference => {
|
||||
const types = [];
|
||||
const isRest = isRestParameter(parameter);
|
||||
let isOptional = false;
|
||||
for (const callContext of callContexts) {
|
||||
@@ -434,7 +423,8 @@ namespace ts.codefix {
|
||||
}
|
||||
}
|
||||
if (isIdentifier(parameter.name)) {
|
||||
types.push(...inferTypesFromReferences(getReferences(parameter.name, program, cancellationToken), checker, cancellationToken));
|
||||
const inferred = inferTypesFromReferences(getReferences(parameter.name, program, cancellationToken), checker, cancellationToken);
|
||||
types.push(...(isRest ? mapDefined(inferred, checker.getElementTypeOfArrayType) : inferred));
|
||||
}
|
||||
const type = unifyFromContext(types, checker);
|
||||
return {
|
||||
@@ -510,8 +500,7 @@ namespace ts.codefix {
|
||||
break;
|
||||
|
||||
case SyntaxKind.PlusToken:
|
||||
usageContext.isNumber = true;
|
||||
usageContext.isString = true;
|
||||
usageContext.isNumberOrString = true;
|
||||
break;
|
||||
|
||||
// case SyntaxKind.ExclamationToken:
|
||||
@@ -582,8 +571,7 @@ namespace ts.codefix {
|
||||
usageContext.isString = true;
|
||||
}
|
||||
else {
|
||||
usageContext.isNumber = true;
|
||||
usageContext.isString = true;
|
||||
usageContext.isNumberOrString = true;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -657,8 +645,7 @@ namespace ts.codefix {
|
||||
|
||||
function inferTypeFromPropertyElementExpressionContext(parent: ElementAccessExpression, node: Expression, checker: TypeChecker, usageContext: UsageContext): void {
|
||||
if (node === parent.argumentExpression) {
|
||||
usageContext.isNumber = true;
|
||||
usageContext.isString = true;
|
||||
usageContext.isNumberOrString = true;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
@@ -674,17 +661,50 @@ namespace ts.codefix {
|
||||
}
|
||||
}
|
||||
|
||||
interface Priority {
|
||||
high: (t: Type) => boolean;
|
||||
low: (t: Type) => boolean;
|
||||
}
|
||||
|
||||
function removeLowPriorityInferences(inferences: ReadonlyArray<Type>, priorities: Priority[]): Type[] {
|
||||
const toRemove: ((t: Type) => boolean)[] = [];
|
||||
for (const i of inferences) {
|
||||
for (const { high, low } of priorities) {
|
||||
if (high(i)) {
|
||||
Debug.assert(!low(i));
|
||||
toRemove.push(low);
|
||||
}
|
||||
}
|
||||
}
|
||||
return inferences.filter(i => toRemove.every(f => !f(i)));
|
||||
}
|
||||
|
||||
export function unifyFromContext(inferences: ReadonlyArray<Type>, checker: TypeChecker, fallback = checker.getAnyType()): Type {
|
||||
if (!inferences.length) return fallback;
|
||||
const hasNonVacuousType = inferences.some(i => !(i.flags & (TypeFlags.Any | TypeFlags.Void)));
|
||||
const hasNonVacuousNonAnonymousType = inferences.some(
|
||||
i => !(i.flags & (TypeFlags.Nullable | TypeFlags.Any | TypeFlags.Void)) && !(checker.getObjectFlags(i) & ObjectFlags.Anonymous));
|
||||
const anons = inferences.filter(i => checker.getObjectFlags(i) & ObjectFlags.Anonymous) as AnonymousType[];
|
||||
const good = [];
|
||||
if (!hasNonVacuousNonAnonymousType && anons.length) {
|
||||
|
||||
// 1. string or number individually override string | number
|
||||
// 2. non-any, non-void overrides any or void
|
||||
// 3. non-nullable, non-any, non-void, non-anonymous overrides anonymous types
|
||||
const stringNumber = checker.getUnionType([checker.getStringType(), checker.getNumberType()]);
|
||||
const priorities: Priority[] = [
|
||||
{
|
||||
high: t => t === checker.getStringType() || t === checker.getNumberType(),
|
||||
low: t => t === stringNumber
|
||||
},
|
||||
{
|
||||
high: t => !(t.flags & (TypeFlags.Any | TypeFlags.Void)),
|
||||
low: t => !!(t.flags & (TypeFlags.Any | TypeFlags.Void))
|
||||
},
|
||||
{
|
||||
high: t => !(t.flags & (TypeFlags.Nullable | TypeFlags.Any | TypeFlags.Void)) && !(checker.getObjectFlags(t) & ObjectFlags.Anonymous),
|
||||
low: t => !!(checker.getObjectFlags(t) & ObjectFlags.Anonymous)
|
||||
}];
|
||||
let good = removeLowPriorityInferences(inferences, priorities);
|
||||
const anons = good.filter(i => checker.getObjectFlags(i) & ObjectFlags.Anonymous) as AnonymousType[];
|
||||
if (anons.length) {
|
||||
good = good.filter(i => !(checker.getObjectFlags(i) & ObjectFlags.Anonymous));
|
||||
good.push(unifyAnonymousTypes(anons, checker));
|
||||
}
|
||||
good.push(...inferences.filter(i => !(checker.getObjectFlags(i) & ObjectFlags.Anonymous) && !(hasNonVacuousType && i.flags & (TypeFlags.Any | TypeFlags.Void))));
|
||||
return checker.getWidenedType(checker.getUnionType(good));
|
||||
}
|
||||
|
||||
@@ -731,12 +751,16 @@ namespace ts.codefix {
|
||||
|
||||
function inferFromContext(usageContext: UsageContext, checker: TypeChecker) {
|
||||
const types = [];
|
||||
|
||||
if (usageContext.isNumber) {
|
||||
types.push(checker.getNumberType());
|
||||
}
|
||||
if (usageContext.isString) {
|
||||
types.push(checker.getStringType());
|
||||
}
|
||||
if (usageContext.isNumberOrString) {
|
||||
types.push(checker.getUnionType([checker.getStringType(), checker.getNumberType()]));
|
||||
}
|
||||
|
||||
types.push(...(usageContext.candidateTypes || []).map(t => checker.getBaseTypeOfLiteralType(t)));
|
||||
|
||||
@@ -750,7 +774,7 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
if (usageContext.numberIndexContext) {
|
||||
return [checker.createArrayType(recur(usageContext.numberIndexContext))];
|
||||
types.push(checker.createArrayType(recur(usageContext.numberIndexContext)));
|
||||
}
|
||||
else if (usageContext.properties || usageContext.callContexts || usageContext.constructContexts || usageContext.stringIndexContext) {
|
||||
const members = createUnderscoreEscapedMap<Symbol>();
|
||||
|
||||
+20
-12
@@ -913,7 +913,7 @@ namespace ts.Completions {
|
||||
}
|
||||
else {
|
||||
for (const symbol of type.getApparentProperties()) {
|
||||
if (typeChecker.isValidPropertyAccessForCompletions(node.kind === SyntaxKind.ImportType ? <ImportTypeNode>node : <PropertyAccessExpression>node.parent, type, symbol)) {
|
||||
if (typeChecker.isValidPropertyAccessForCompletions(node.kind === SyntaxKind.ImportType ? <ImportTypeNode>node : <PropertyAccessExpression | QualifiedName>node.parent, type, symbol)) {
|
||||
addPropertySymbol(symbol);
|
||||
}
|
||||
}
|
||||
@@ -1021,7 +1021,8 @@ namespace ts.Completions {
|
||||
const scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile;
|
||||
isInSnippetScope = isSnippetScope(scopeNode);
|
||||
|
||||
const symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias;
|
||||
const isTypeOnly = isTypeOnlyCompletion();
|
||||
const symbolMeanings = (isTypeOnly ? SymbolFlags.None : SymbolFlags.Value) | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias;
|
||||
|
||||
symbols = Debug.assertEachDefined(typeChecker.getSymbolsInScope(scopeNode, symbolMeanings), "getSymbolsInScope() should all be defined");
|
||||
|
||||
@@ -1049,12 +1050,10 @@ namespace ts.Completions {
|
||||
if (sourceFile.externalModuleIndicator) return true;
|
||||
// If already using commonjs, don't introduce ES6.
|
||||
if (sourceFile.commonJsModuleIndicator) return false;
|
||||
// For JS, stay on the safe side.
|
||||
if (isUncheckedFile) return false;
|
||||
// If some file is using ES6 modules, assume that it's OK to add more.
|
||||
if (programContainsEs6Modules(program)) return true;
|
||||
// If module transpilation is enabled or we're targeting es6 or above, or not emitting, OK.
|
||||
return compilerOptionsIndicateEs6Modules(program.getCompilerOptions());
|
||||
if (compilerOptionsIndicateEs6Modules(program.getCompilerOptions())) return true;
|
||||
// If some file is using ES6 modules, assume that it's OK to add more.
|
||||
return programContainsEs6Modules(program);
|
||||
}
|
||||
|
||||
function isSnippetScope(scopeNode: Node): boolean {
|
||||
@@ -1070,9 +1069,9 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
function filterGlobalCompletion(symbols: Symbol[]): void {
|
||||
const isTypeOnlyCompletion = insideJsDocTagTypeExpression || !isContextTokenValueLocation(contextToken) && (isPartOfTypeNode(location) || isContextTokenTypeLocation(contextToken));
|
||||
const allowTypes = isTypeOnlyCompletion || !isContextTokenValueLocation(contextToken) && isPossiblyTypeArgumentPosition(contextToken, sourceFile, typeChecker);
|
||||
if (isTypeOnlyCompletion) keywordFilters = KeywordCompletionFilters.TypeKeywords;
|
||||
const isTypeOnly = isTypeOnlyCompletion();
|
||||
const allowTypes = isTypeOnly || !isContextTokenValueLocation(contextToken) && isPossiblyTypeArgumentPosition(contextToken, sourceFile, typeChecker);
|
||||
if (isTypeOnly) keywordFilters = KeywordCompletionFilters.TypeKeywords;
|
||||
|
||||
filterMutate(symbols, symbol => {
|
||||
if (!isSourceFile(location)) {
|
||||
@@ -1091,7 +1090,7 @@ namespace ts.Completions {
|
||||
if (allowTypes) {
|
||||
// Its a type, but you can reach it by namespace.type as well
|
||||
const symbolAllowedAsType = symbolCanBeReferencedAtTypeLocation(symbol);
|
||||
if (symbolAllowedAsType || isTypeOnlyCompletion) {
|
||||
if (symbolAllowedAsType || isTypeOnly) {
|
||||
return symbolAllowedAsType;
|
||||
}
|
||||
}
|
||||
@@ -1102,6 +1101,10 @@ namespace ts.Completions {
|
||||
});
|
||||
}
|
||||
|
||||
function isTypeOnlyCompletion(): boolean {
|
||||
return insideJsDocTagTypeExpression || !isContextTokenValueLocation(contextToken) && (isPartOfTypeNode(location) || isContextTokenTypeLocation(contextToken));
|
||||
}
|
||||
|
||||
function isContextTokenValueLocation(contextToken: Node) {
|
||||
return contextToken &&
|
||||
contextToken.kind === SyntaxKind.TypeOfKeyword &&
|
||||
@@ -1532,6 +1535,7 @@ namespace ts.Completions {
|
||||
if (contextToken) {
|
||||
const parent = contextToken.parent;
|
||||
switch (contextToken.kind) {
|
||||
case SyntaxKind.GreaterThanToken: // End of a type argument list
|
||||
case SyntaxKind.LessThanSlashToken:
|
||||
case SyntaxKind.SlashToken:
|
||||
case SyntaxKind.Identifier:
|
||||
@@ -1540,6 +1544,10 @@ namespace ts.Completions {
|
||||
case SyntaxKind.JsxAttribute:
|
||||
case SyntaxKind.JsxSpreadAttribute:
|
||||
if (parent && (parent.kind === SyntaxKind.JsxSelfClosingElement || parent.kind === SyntaxKind.JsxOpeningElement)) {
|
||||
if (contextToken.kind === SyntaxKind.GreaterThanToken) {
|
||||
const precedingToken = findPrecedingToken(contextToken.pos, sourceFile, /*startNode*/ undefined);
|
||||
if (!(parent as JsxOpeningLikeElement).typeArguments || (precedingToken && precedingToken.kind === SyntaxKind.SlashToken)) break;
|
||||
}
|
||||
return <JsxOpeningLikeElement>parent;
|
||||
}
|
||||
else if (parent.kind === SyntaxKind.JsxAttribute) {
|
||||
@@ -1949,7 +1957,7 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
function isFunctionLikeBodyKeyword(kind: SyntaxKind) {
|
||||
return kind === SyntaxKind.AsyncKeyword || !isContextualKeyword(kind) && !isClassMemberCompletionKeyword(kind);
|
||||
return kind === SyntaxKind.AsyncKeyword || kind === SyntaxKind.AwaitKeyword || !isContextualKeyword(kind) && !isClassMemberCompletionKeyword(kind);
|
||||
}
|
||||
|
||||
function keywordForNode(node: Node): SyntaxKind {
|
||||
|
||||
@@ -89,10 +89,10 @@ namespace ts.FindAllReferences {
|
||||
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));
|
||||
return map(flattenEntries(Core.getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, options)), entry => convertEntry(entry, node, program.getTypeChecker()));
|
||||
}
|
||||
|
||||
export type ToReferenceOrRenameEntry<T> = (entry: Entry, originalNode: Node) => T;
|
||||
export type ToReferenceOrRenameEntry<T> = (entry: Entry, originalNode: Node, checker: TypeChecker) => T;
|
||||
|
||||
export function getReferenceEntriesForNode(
|
||||
position: number,
|
||||
@@ -157,8 +157,8 @@ namespace ts.FindAllReferences {
|
||||
return { displayParts, kind: symbolKind };
|
||||
}
|
||||
|
||||
export function toRenameLocation(entry: Entry, originalNode: Node): RenameLocation {
|
||||
return { ...entryToDocumentSpan(entry), ...getPrefixAndSuffixText(entry, originalNode) };
|
||||
export function toRenameLocation(entry: Entry, originalNode: Node, checker: TypeChecker): RenameLocation {
|
||||
return { ...entryToDocumentSpan(entry), ...getPrefixAndSuffixText(entry, originalNode, checker) };
|
||||
}
|
||||
|
||||
export function toReferenceEntry(entry: Entry): ReferenceEntry {
|
||||
@@ -188,25 +188,28 @@ namespace ts.FindAllReferences {
|
||||
}
|
||||
}
|
||||
|
||||
function getPrefixAndSuffixText(entry: Entry, originalNode: Node): { readonly prefixText?: string, readonly suffixText?: string } {
|
||||
interface PrefixAndSuffix { readonly prefixText?: string; readonly suffixText?: string; }
|
||||
function getPrefixAndSuffixText(entry: Entry, originalNode: Node, checker: TypeChecker): PrefixAndSuffix {
|
||||
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 + ": " };
|
||||
}
|
||||
const prefixColon: PrefixAndSuffix = { prefixText: name + ": " };
|
||||
const suffixColon: PrefixAndSuffix = { suffixText: ": " + name };
|
||||
return kind === EntryKind.SearchedLocalFoundProperty ? prefixColon
|
||||
: kind === EntryKind.SearchedPropertyFoundLocal ? suffixColon
|
||||
// In `const o = { x }; o.x`, symbolAtLocation at `x` in `{ x }` is the property symbol.
|
||||
// For a binding element `const { x } = o;`, symbolAtLocation at `x` is the property symbol.
|
||||
: isShorthandAssignment ? suffixColon : prefixColon;
|
||||
}
|
||||
else if (isImportSpecifier(entry.node.parent) && !entry.node.parent.propertyName) {
|
||||
// If the original symbol was using this alias, just rename the alias.
|
||||
const originalSymbol = isExportSpecifier(originalNode.parent) ? checker.getExportSpecifierLocalTargetSymbol(originalNode.parent) : checker.getSymbolAtLocation(originalNode);
|
||||
return contains(originalSymbol!.declarations, entry.node.parent) ? { prefixText: name + " as " } : emptyOptions;
|
||||
}
|
||||
else if (isExportSpecifier(entry.node.parent) && !entry.node.parent.propertyName) {
|
||||
return originalNode === entry.node ? { prefixText: name + " as " } : { suffixText: " as " + name };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,8 +483,8 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
|
||||
/** Core find-all-references algorithm for a normal symbol. */
|
||||
function getReferencedSymbolsForSymbol(symbol: Symbol, node: Node | undefined, sourceFiles: ReadonlyArray<SourceFile>, sourceFilesSet: ReadonlyMap<true>, checker: TypeChecker, cancellationToken: CancellationToken, options: Options): SymbolAndEntries[] {
|
||||
symbol = node && skipPastExportOrImportSpecifierOrUnion(symbol, node, checker) || symbol;
|
||||
function getReferencedSymbolsForSymbol(originalSymbol: Symbol, node: Node | undefined, sourceFiles: ReadonlyArray<SourceFile>, sourceFilesSet: ReadonlyMap<true>, checker: TypeChecker, cancellationToken: CancellationToken, options: Options): SymbolAndEntries[] {
|
||||
const symbol = node && skipPastExportOrImportSpecifierOrUnion(originalSymbol, node, checker, !!options.isForRename) || originalSymbol;
|
||||
|
||||
// Compute the meaning from the location and the symbol it references
|
||||
const searchMeaning = node ? getIntersectingMeaningFromDeclarations(node, symbol) : SemanticMeaning.All;
|
||||
@@ -489,7 +492,12 @@ namespace ts.FindAllReferences.Core {
|
||||
const result: SymbolAndEntries[] = [];
|
||||
const state = new State(sourceFiles, sourceFilesSet, node ? getSpecialSearchKind(node) : SpecialSearchKind.None, checker, cancellationToken, searchMeaning, options, result);
|
||||
|
||||
if (node && node.kind === SyntaxKind.DefaultKeyword) {
|
||||
const exportSpecifier = !options.isForRename ? undefined : find(symbol.declarations, isExportSpecifier);
|
||||
if (exportSpecifier) {
|
||||
// When renaming at an export specifier, rename the export and not the thing being exported.
|
||||
getReferencesAtExportSpecifier(exportSpecifier.name, symbol, exportSpecifier, state.createSearch(node, originalSymbol, /*comingFrom*/ undefined), state, /*addReferencesHere*/ true, /*alwaysGetReferences*/ true);
|
||||
}
|
||||
else if (node && node.kind === SyntaxKind.DefaultKeyword) {
|
||||
addReference(node, symbol, state);
|
||||
searchForImportsOfExport(node, symbol, { exportingModuleSymbol: Debug.assertDefined(symbol.parent, "Expected export symbol to have a parent"), exportKind: ExportKind.Default }, state);
|
||||
}
|
||||
@@ -530,16 +538,11 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
|
||||
/** Handle a few special cases relating to export/import specifiers. */
|
||||
function skipPastExportOrImportSpecifierOrUnion(symbol: Symbol, node: Node, checker: TypeChecker): Symbol | undefined {
|
||||
function skipPastExportOrImportSpecifierOrUnion(symbol: Symbol, node: Node, checker: TypeChecker, isForRename: boolean): Symbol | undefined {
|
||||
const { parent } = node;
|
||||
if (isExportSpecifier(parent)) {
|
||||
if (isExportSpecifier(parent) && !isForRename) {
|
||||
return getLocalSymbolForExportSpecifier(node as Identifier, symbol, parent, checker);
|
||||
}
|
||||
if (isImportSpecifier(parent) && parent.propertyName === node) {
|
||||
// We're at `foo` in `import { foo as bar }`. Probably intended to find all refs on the original, not just on the import.
|
||||
return checker.getImmediateAliasedSymbol(symbol)!;
|
||||
}
|
||||
|
||||
// If the symbol is declared as part of a declaration like `{ type: "a" } | { type: "b" }`, use the property on the union type to get more references.
|
||||
return firstDefined(symbol.declarations, decl => {
|
||||
if (!decl.parent) {
|
||||
@@ -741,7 +744,8 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
for (const indirectUser of indirectUsers) {
|
||||
for (const node of getPossibleSymbolReferenceNodes(indirectUser, isDefaultExport ? "default" : exportName)) {
|
||||
if (isIdentifier(node) && checker.getSymbolAtLocation(node) === exportSymbol) {
|
||||
// Import specifiers should be handled by importSearches
|
||||
if (isIdentifier(node) && !isImportOrExportSpecifier(node.parent) && checker.getSymbolAtLocation(node) === exportSymbol) {
|
||||
cb(node);
|
||||
}
|
||||
}
|
||||
@@ -754,7 +758,7 @@ namespace ts.FindAllReferences.Core {
|
||||
// Don't rename an import type `import("./module-name")` when renaming `name` in `export = name;`
|
||||
if (!isIdentifier(singleRef)) return false;
|
||||
// At `default` in `import { default as x }` or `export { default as x }`, do add a reference, but do not rename.
|
||||
return !((isExportSpecifier(singleRef.parent) || isImportSpecifier(singleRef.parent)) && singleRef.escapedText === InternalSymbolName.Default);
|
||||
return !(isImportOrExportSpecifier(singleRef.parent) && singleRef.escapedText === InternalSymbolName.Default);
|
||||
}
|
||||
|
||||
// Go to the symbol we imported from and find references for it.
|
||||
@@ -1058,17 +1062,25 @@ namespace ts.FindAllReferences.Core {
|
||||
getImportOrExportReferences(referenceLocation, referenceSymbol, search, state);
|
||||
}
|
||||
|
||||
function getReferencesAtExportSpecifier(referenceLocation: Identifier, referenceSymbol: Symbol, exportSpecifier: ExportSpecifier, search: Search, state: State, addReferencesHere: boolean): void {
|
||||
function getReferencesAtExportSpecifier(
|
||||
referenceLocation: Identifier,
|
||||
referenceSymbol: Symbol,
|
||||
exportSpecifier: ExportSpecifier,
|
||||
search: Search,
|
||||
state: State,
|
||||
addReferencesHere: boolean,
|
||||
alwaysGetReferences?: boolean,
|
||||
): void {
|
||||
const { parent, propertyName, name } = exportSpecifier;
|
||||
const exportDeclaration = parent.parent;
|
||||
const localSymbol = getLocalSymbolForExportSpecifier(referenceLocation, referenceSymbol, exportSpecifier, state.checker);
|
||||
if (!search.includes(localSymbol)) {
|
||||
if (!alwaysGetReferences && !search.includes(localSymbol)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!propertyName) {
|
||||
// Don't rename at `export { default } from "m";`. (but do continue to search for imports of the re-export)
|
||||
if (!(state.options.isForRename && name.escapedText === InternalSymbolName.Default)) {
|
||||
if (!(state.options.isForRename && (name.escapedText === InternalSymbolName.Default))) {
|
||||
addRef();
|
||||
}
|
||||
}
|
||||
@@ -1080,7 +1092,7 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
|
||||
if (addReferencesHere && !state.options.isForRename && state.markSeenReExportRHS(name)) {
|
||||
addReference(name, referenceSymbol, state);
|
||||
addReference(name, Debug.assertDefined(exportSpecifier.symbol), state);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1090,15 +1102,15 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
|
||||
// For `export { foo as bar }`, rename `foo`, but not `bar`.
|
||||
if (!(referenceLocation === propertyName && state.options.isForRename)) {
|
||||
if (!state.options.isForRename || alwaysGetReferences) {
|
||||
const exportKind = referenceLocation.originalKeywordKind === SyntaxKind.DefaultKeyword ? ExportKind.Default : ExportKind.Named;
|
||||
const exportInfo = getExportInfo(referenceSymbol, exportKind, state.checker);
|
||||
if (!exportInfo) return Debug.fail();
|
||||
searchForImportsOfExport(referenceLocation, referenceSymbol, exportInfo, state);
|
||||
const exportSymbol = Debug.assertDefined(exportSpecifier.symbol);
|
||||
const exportInfo = Debug.assertDefined(getExportInfo(exportSymbol, exportKind, state.checker));
|
||||
searchForImportsOfExport(referenceLocation, exportSymbol, exportInfo, state);
|
||||
}
|
||||
|
||||
// At `export { x } from "foo"`, also search for the imported symbol `"foo".x`.
|
||||
if (search.comingFrom !== ImportExport.Export && exportDeclaration.moduleSpecifier && !propertyName) {
|
||||
if (search.comingFrom !== ImportExport.Export && exportDeclaration.moduleSpecifier && !propertyName && !state.options.isForRename) {
|
||||
const imported = state.checker.getExportSpecifierLocalTargetSymbol(exportSpecifier);
|
||||
if (imported) searchForImportedSymbol(imported, state);
|
||||
}
|
||||
@@ -1133,12 +1145,11 @@ namespace ts.FindAllReferences.Core {
|
||||
const { symbol } = importOrExport;
|
||||
|
||||
if (importOrExport.kind === ImportExport.Import) {
|
||||
if (!state.options.isForRename || importOrExport.isNamedImport) {
|
||||
if (!state.options.isForRename) {
|
||||
searchForImportedSymbol(symbol, state);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// We don't check for `state.isForRename`, even for default exports, because importers that previously matched the export name should be updated to continue matching.
|
||||
searchForImportsOfExport(referenceLocation, symbol, importOrExport.exportInfo, state);
|
||||
}
|
||||
}
|
||||
@@ -1417,6 +1428,10 @@ namespace ts.FindAllReferences.Core {
|
||||
return [{ definition: { type: DefinitionKind.Symbol, symbol: searchSpaceNode.symbol }, references }];
|
||||
}
|
||||
|
||||
function isParameterName(node: Node) {
|
||||
return node.kind === SyntaxKind.Identifier && node.parent.kind === SyntaxKind.Parameter && (<ParameterDeclaration>node.parent).name === node;
|
||||
}
|
||||
|
||||
function getReferencesForThisKeyword(thisOrSuperKeyword: Node, sourceFiles: ReadonlyArray<SourceFile>, cancellationToken: CancellationToken): SymbolAndEntries[] | undefined {
|
||||
let searchSpaceNode = getThisContainer(thisOrSuperKeyword, /* includeArrowFunctions */ false);
|
||||
|
||||
@@ -1439,7 +1454,7 @@ namespace ts.FindAllReferences.Core {
|
||||
searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class
|
||||
break;
|
||||
case SyntaxKind.SourceFile:
|
||||
if (isExternalModule(<SourceFile>searchSpaceNode)) {
|
||||
if (isExternalModule(<SourceFile>searchSpaceNode) || isParameterName(thisOrSuperKeyword)) {
|
||||
return undefined;
|
||||
}
|
||||
// falls through
|
||||
@@ -1472,7 +1487,7 @@ namespace ts.FindAllReferences.Core {
|
||||
// and has the appropriate static modifier from the original container.
|
||||
return container.parent && searchSpaceNode.symbol === container.parent.symbol && (getModifierFlags(container) & ModifierFlags.Static) === staticFlag;
|
||||
case SyntaxKind.SourceFile:
|
||||
return container.kind === SyntaxKind.SourceFile && !isExternalModule(<SourceFile>container);
|
||||
return container.kind === SyntaxKind.SourceFile && !isExternalModule(<SourceFile>container) && !isParameterName(node);
|
||||
}
|
||||
});
|
||||
}).map(n => nodeEntry(n));
|
||||
|
||||
@@ -1106,10 +1106,7 @@ namespace ts.formatting {
|
||||
* Trimming will be done for lines after the previous range
|
||||
*/
|
||||
function trimTrailingWhitespacesForRemainingRange() {
|
||||
if (!previousRange) {
|
||||
return;
|
||||
}
|
||||
const startPosition = previousRange.end;
|
||||
const startPosition = previousRange ? previousRange.end : originalRange.pos;
|
||||
|
||||
const startLine = sourceFile.getLineAndCharacterOfPosition(startPosition).line;
|
||||
const endLine = sourceFile.getLineAndCharacterOfPosition(originalRange.end).line;
|
||||
|
||||
@@ -10,11 +10,11 @@ namespace ts.formatting {
|
||||
}
|
||||
|
||||
export class FormattingContext {
|
||||
public currentTokenSpan: TextRangeWithKind;
|
||||
public nextTokenSpan: TextRangeWithKind;
|
||||
public contextNode: Node;
|
||||
public currentTokenParent: Node;
|
||||
public nextTokenParent: Node;
|
||||
public currentTokenSpan!: TextRangeWithKind;
|
||||
public nextTokenSpan!: TextRangeWithKind;
|
||||
public contextNode!: Node;
|
||||
public currentTokenParent!: Node;
|
||||
public nextTokenParent!: Node;
|
||||
|
||||
private contextNodeAllOnSameLine: boolean | undefined;
|
||||
private nextNodeAllOnSameLine: boolean | undefined;
|
||||
@@ -26,17 +26,11 @@ namespace ts.formatting {
|
||||
}
|
||||
|
||||
public updateContext(currentRange: TextRangeWithKind, currentTokenParent: Node, nextRange: TextRangeWithKind, nextTokenParent: Node, commonParent: Node) {
|
||||
Debug.assert(currentRange !== undefined, "currentTokenSpan is null");
|
||||
Debug.assert(currentTokenParent !== undefined, "currentTokenParent is null");
|
||||
Debug.assert(nextRange !== undefined, "nextTokenSpan is null");
|
||||
Debug.assert(nextTokenParent !== undefined, "nextTokenParent is null");
|
||||
Debug.assert(commonParent !== undefined, "commonParent is null");
|
||||
|
||||
this.currentTokenSpan = currentRange;
|
||||
this.currentTokenParent = currentTokenParent;
|
||||
this.nextTokenSpan = nextRange;
|
||||
this.nextTokenParent = nextTokenParent;
|
||||
this.contextNode = commonParent;
|
||||
this.currentTokenSpan = Debug.assertDefined(currentRange);
|
||||
this.currentTokenParent = Debug.assertDefined(currentTokenParent);
|
||||
this.nextTokenSpan = Debug.assertDefined(nextRange);
|
||||
this.nextTokenParent = Debug.assertDefined(nextTokenParent);
|
||||
this.contextNode = Debug.assertDefined(commonParent);
|
||||
|
||||
// drop cached results
|
||||
this.contextNodeAllOnSameLine = undefined;
|
||||
|
||||
@@ -424,7 +424,6 @@ namespace ts.FindAllReferences {
|
||||
export interface ImportedSymbol {
|
||||
kind: ImportExport.Import;
|
||||
symbol: Symbol;
|
||||
isNamedImport: boolean;
|
||||
}
|
||||
export interface ExportedSymbol {
|
||||
kind: ImportExport.Export;
|
||||
@@ -467,7 +466,7 @@ namespace ts.FindAllReferences {
|
||||
}
|
||||
|
||||
const lhsSymbol = checker.getSymbolAtLocation(exportNode.name)!;
|
||||
return { kind: ImportExport.Import, symbol: lhsSymbol, isNamedImport: false };
|
||||
return { kind: ImportExport.Import, symbol: lhsSymbol };
|
||||
}
|
||||
else {
|
||||
return exportInfo(symbol, getExportKindForDeclaration(exportNode));
|
||||
@@ -542,7 +541,7 @@ namespace ts.FindAllReferences {
|
||||
// (All imports returned from this function will be ignored anyway if we are in rename and this is a not a named export.)
|
||||
const importedName = symbolEscapedNameNoDefault(importedSymbol);
|
||||
if (importedName === undefined || importedName === InternalSymbolName.Default || importedName === symbol.escapedName) {
|
||||
return { kind: ImportExport.Import, symbol: importedSymbol, ...isImport };
|
||||
return { kind: ImportExport.Import, symbol: importedSymbol };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -588,22 +587,20 @@ namespace ts.FindAllReferences {
|
||||
}
|
||||
}
|
||||
|
||||
function isNodeImport(node: Node): { isNamedImport: boolean } | undefined {
|
||||
function isNodeImport(node: Node): boolean {
|
||||
const { parent } = node;
|
||||
switch (parent.kind) {
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
return (parent as ImportEqualsDeclaration).name === node && isExternalModuleImportEquals(parent as ImportEqualsDeclaration)
|
||||
? { isNamedImport: false }
|
||||
: undefined;
|
||||
return (parent as ImportEqualsDeclaration).name === node && isExternalModuleImportEquals(parent as ImportEqualsDeclaration);
|
||||
case SyntaxKind.ImportSpecifier:
|
||||
// For a rename import `{ foo as bar }`, don't search for the imported symbol. Just find local uses of `bar`.
|
||||
return (parent as ImportSpecifier).propertyName ? undefined : { isNamedImport: true };
|
||||
return !(parent as ImportSpecifier).propertyName;
|
||||
case SyntaxKind.ImportClause:
|
||||
case SyntaxKind.NamespaceImport:
|
||||
Debug.assert((parent as ImportClause | NamespaceImport).name === node);
|
||||
return { isNamedImport: false };
|
||||
return true;
|
||||
default:
|
||||
return undefined;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -660,7 +660,7 @@ namespace ts.NavigationBar {
|
||||
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(", ");
|
||||
const args = mapDefined(parent.arguments, a => isStringLiteralLike(a) ? a.getText(curSourceFile) : undefined).join(", ");
|
||||
return `${name}(${args}) callback`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,10 @@ namespace ts.OutliningElementsCollector {
|
||||
addOutliningForLeadingCommentsForNode(n, sourceFile, cancellationToken, out);
|
||||
}
|
||||
|
||||
if (isFunctionExpressionAssignedToVariable(n)) {
|
||||
addOutliningForLeadingCommentsForNode(n.parent.parent.parent, sourceFile, cancellationToken, out);
|
||||
}
|
||||
|
||||
const span = getOutliningSpanForNode(n, sourceFile);
|
||||
if (span) out.push(span);
|
||||
|
||||
@@ -54,6 +58,14 @@ namespace ts.OutliningElementsCollector {
|
||||
}
|
||||
depthRemaining++;
|
||||
}
|
||||
|
||||
function isFunctionExpressionAssignedToVariable(n: Node) {
|
||||
if (!isFunctionExpression(n) && !isArrowFunction(n)) {
|
||||
return false;
|
||||
}
|
||||
const ancestor = findAncestor(n, isVariableStatement);
|
||||
return !!ancestor && getSingleInitializerOfVariableStatementOrPropertyDeclaration(ancestor) === n;
|
||||
}
|
||||
}
|
||||
|
||||
function addRegionOutliningSpans(sourceFile: SourceFile, out: Push<OutliningSpan>): void {
|
||||
@@ -175,6 +187,7 @@ namespace ts.OutliningElementsCollector {
|
||||
case SyntaxKind.ModuleBlock:
|
||||
return spanForNode(n.parent);
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.ClassExpression:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.CaseBlock:
|
||||
@@ -206,10 +219,10 @@ namespace ts.OutliningElementsCollector {
|
||||
}
|
||||
|
||||
function spanForObjectOrArrayLiteral(node: Node, open: SyntaxKind.OpenBraceToken | SyntaxKind.OpenBracketToken = SyntaxKind.OpenBraceToken): OutliningSpan | undefined {
|
||||
// If the block has no leading keywords and is inside an array literal,
|
||||
// If the block has no leading keywords and is inside an array literal or call expression,
|
||||
// we only want to collapse the span of the block.
|
||||
// Otherwise, the collapsed section will include the end of the previous line.
|
||||
return spanForNode(node, /*autoCollapse*/ false, /*useFullStart*/ !isArrayLiteralExpression(node.parent), open);
|
||||
return spanForNode(node, /*autoCollapse*/ false, /*useFullStart*/ !isArrayLiteralExpression(node.parent) && !isCallExpression(node.parent), open);
|
||||
}
|
||||
|
||||
function spanForNode(hintSpanNode: Node, autoCollapse = false, useFullStart = true, open: SyntaxKind.OpenBraceToken | SyntaxKind.OpenBracketToken = SyntaxKind.OpenBraceToken): OutliningSpan | undefined {
|
||||
|
||||
@@ -449,8 +449,7 @@ namespace ts.refactor.extractSymbol {
|
||||
case SyntaxKind.ThisKeyword:
|
||||
rangeFacts |= RangeFacts.UsesThis;
|
||||
break;
|
||||
case SyntaxKind.LabeledStatement:
|
||||
{
|
||||
case SyntaxKind.LabeledStatement: {
|
||||
const label = (<LabeledStatement>node).label;
|
||||
(seenLabels || (seenLabels = [])).push(label.escapedText);
|
||||
forEachChild(node, visit);
|
||||
@@ -458,8 +457,7 @@ namespace ts.refactor.extractSymbol {
|
||||
break;
|
||||
}
|
||||
case SyntaxKind.BreakStatement:
|
||||
case SyntaxKind.ContinueStatement:
|
||||
{
|
||||
case SyntaxKind.ContinueStatement: {
|
||||
const label = (<BreakStatement | ContinueStatement>node).label;
|
||||
if (label) {
|
||||
if (!contains(seenLabels, label.escapedText)) {
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
|
||||
readonly declaration: AcceptedDeclaration;
|
||||
readonly fieldName: AcceptedNameType;
|
||||
readonly accessorName: AcceptedNameType;
|
||||
readonly originalName: AcceptedNameType;
|
||||
readonly originalName: string;
|
||||
readonly renameAccessor: boolean;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
|
||||
// readonly modifier only existed in classLikeDeclaration
|
||||
const constructor = getFirstConstructorWithBody(<ClassLikeDeclaration>container);
|
||||
if (constructor) {
|
||||
updateReadonlyPropertyInitializerStatementConstructor(changeTracker, context, constructor, fieldName, originalName);
|
||||
updateReadonlyPropertyInitializerStatementConstructor(changeTracker, file, constructor, fieldName.text, originalName);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -135,7 +135,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
|
||||
isReadonly: hasReadonlyModifier(declaration),
|
||||
type: getTypeAnnotationNode(declaration),
|
||||
container: declaration.kind === SyntaxKind.Parameter ? declaration.parent.parent : declaration.parent,
|
||||
originalName: <AcceptedNameType>declaration.name,
|
||||
originalName: (<AcceptedNameType>declaration.name).text,
|
||||
declaration,
|
||||
fieldName,
|
||||
accessorName,
|
||||
@@ -221,22 +221,22 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
|
||||
: changeTracker.insertNodeAfter(file, declaration, accessor);
|
||||
}
|
||||
|
||||
function updateReadonlyPropertyInitializerStatementConstructor(changeTracker: textChanges.ChangeTracker, context: RefactorContext, constructor: ConstructorDeclaration, fieldName: AcceptedNameType, originalName: AcceptedNameType) {
|
||||
function updateReadonlyPropertyInitializerStatementConstructor(changeTracker: textChanges.ChangeTracker, file: SourceFile, constructor: ConstructorDeclaration, fieldName: string, originalName: string) {
|
||||
if (!constructor.body) return;
|
||||
const { file, program, cancellationToken } = context;
|
||||
|
||||
const referenceEntries = mapDefined(FindAllReferences.getReferenceEntriesForNode(originalName.parent.pos, originalName, program, [file], cancellationToken!), entry => // TODO: GH#18217
|
||||
(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;
|
||||
const accessorName = createIdentifier(fieldName.text);
|
||||
const node = isBinaryExpression(parent)
|
||||
? updateBinary(parent, accessorName, parent.right, parent.operatorToken)
|
||||
: isPropertyAccessExpression(parent)
|
||||
? updatePropertyAccess(parent, parent.expression, accessorName)
|
||||
: Debug.fail("Unexpected write access token");
|
||||
changeTracker.replaceNode(file, parent, node);
|
||||
constructor.body.forEachChild(function recur(node) {
|
||||
if (isElementAccessExpression(node) &&
|
||||
node.expression.kind === SyntaxKind.ThisKeyword &&
|
||||
isStringLiteral(node.argumentExpression) &&
|
||||
node.argumentExpression.text === originalName &&
|
||||
isWriteAccess(node)) {
|
||||
changeTracker.replaceNode(file, node.argumentExpression, createStringLiteral(fieldName));
|
||||
}
|
||||
if (isPropertyAccessExpression(node) && node.expression.kind === SyntaxKind.ThisKeyword && node.name.text === originalName && isWriteAccess(node)) {
|
||||
changeTracker.replaceNode(file, node.name, createIdentifier(fieldName));
|
||||
}
|
||||
if (!isFunctionLike(node) && !isClassLike(node)) {
|
||||
node.forEachChild(recur);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace ts.Rename {
|
||||
|
||||
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 withoutIndex = endsWith(node.text, "/index") || endsWith(node.text, "/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;
|
||||
|
||||
+100
-89
@@ -17,9 +17,9 @@ namespace ts {
|
||||
public end: number;
|
||||
public flags: NodeFlags;
|
||||
public parent: Node;
|
||||
public symbol: Symbol;
|
||||
public jsDoc: JSDoc[];
|
||||
public original: Node;
|
||||
public symbol!: Symbol; // Actually optional, but it was too annoying to access `node.symbol!` everywhere since in many cases we know it must be defined
|
||||
public jsDoc?: JSDoc[];
|
||||
public original?: Node;
|
||||
public transformFlags: TransformFlags;
|
||||
private _children: Node[] | undefined;
|
||||
|
||||
@@ -196,14 +196,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
class TokenOrIdentifierObject implements Node {
|
||||
public kind: SyntaxKind;
|
||||
public kind!: SyntaxKind;
|
||||
public pos: number;
|
||||
public end: number;
|
||||
public flags: NodeFlags;
|
||||
public parent: Node;
|
||||
public symbol: Symbol;
|
||||
public jsDocComments: JSDoc[];
|
||||
public transformFlags: TransformFlags;
|
||||
public symbol!: Symbol;
|
||||
public jsDocComments?: JSDoc[];
|
||||
public transformFlags!: TransformFlags;
|
||||
|
||||
constructor(pos: number, end: number) {
|
||||
// Set properties in same order as NodeObject
|
||||
@@ -280,8 +280,8 @@ namespace ts {
|
||||
class SymbolObject implements Symbol {
|
||||
flags: SymbolFlags;
|
||||
escapedName: __String;
|
||||
declarations: Declaration[];
|
||||
valueDeclaration: Declaration;
|
||||
declarations!: Declaration[];
|
||||
valueDeclaration!: Declaration;
|
||||
|
||||
// Undefined is used to indicate the value has not been computed. If, after computing, the
|
||||
// symbol has no doc comment, then the empty array will be returned.
|
||||
@@ -334,7 +334,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
class TokenObject<TKind extends SyntaxKind> extends TokenOrIdentifierObject implements Token<TKind> {
|
||||
public symbol: Symbol;
|
||||
public symbol!: Symbol;
|
||||
public kind: TKind;
|
||||
|
||||
constructor(kind: TKind, pos: number, end: number) {
|
||||
@@ -344,10 +344,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
class IdentifierObject extends TokenOrIdentifierObject implements Identifier {
|
||||
public kind: SyntaxKind.Identifier;
|
||||
public escapedText: __String;
|
||||
public symbol: Symbol;
|
||||
public autoGenerateFlags: GeneratedIdentifierFlags;
|
||||
public kind!: SyntaxKind.Identifier;
|
||||
public escapedText!: __String;
|
||||
public symbol!: Symbol;
|
||||
public autoGenerateFlags!: GeneratedIdentifierFlags;
|
||||
_primaryExpressionBrand: any;
|
||||
_memberExpressionBrand: any;
|
||||
_leftHandSideExpressionBrand: any;
|
||||
@@ -355,7 +355,7 @@ namespace ts {
|
||||
_unaryExpressionBrand: any;
|
||||
_expressionBrand: any;
|
||||
_declarationBrand: any;
|
||||
/*@internal*/typeArguments: NodeArray<TypeNode>;
|
||||
/*@internal*/typeArguments!: NodeArray<TypeNode>;
|
||||
constructor(_kind: SyntaxKind.Identifier, pos: number, end: number) {
|
||||
super(pos, end);
|
||||
}
|
||||
@@ -370,8 +370,8 @@ namespace ts {
|
||||
checker: TypeChecker;
|
||||
flags: TypeFlags;
|
||||
objectFlags?: ObjectFlags;
|
||||
id: number;
|
||||
symbol: Symbol;
|
||||
id!: number;
|
||||
symbol!: Symbol;
|
||||
constructor(checker: TypeChecker, flags: TypeFlags) {
|
||||
this.checker = checker;
|
||||
this.flags = flags;
|
||||
@@ -447,16 +447,16 @@ namespace ts {
|
||||
|
||||
class SignatureObject implements Signature {
|
||||
checker: TypeChecker;
|
||||
declaration: SignatureDeclaration;
|
||||
declaration!: SignatureDeclaration;
|
||||
typeParameters?: TypeParameter[];
|
||||
parameters: Symbol[];
|
||||
thisParameter: Symbol;
|
||||
resolvedReturnType: Type;
|
||||
parameters!: Symbol[];
|
||||
thisParameter!: Symbol;
|
||||
resolvedReturnType!: Type;
|
||||
resolvedTypePredicate: TypePredicate | undefined;
|
||||
minTypeArgumentCount: number;
|
||||
minArgumentCount: number;
|
||||
hasRestParameter: boolean;
|
||||
hasLiteralTypes: boolean;
|
||||
minTypeArgumentCount!: number;
|
||||
minArgumentCount!: number;
|
||||
hasRestParameter!: boolean;
|
||||
hasLiteralTypes!: boolean;
|
||||
|
||||
// Undefined is used to indicate the value has not been computed. If, after computing, the
|
||||
// symbol has no doc comment, then the empty array will be returned.
|
||||
@@ -536,55 +536,55 @@ namespace ts {
|
||||
}
|
||||
|
||||
class SourceFileObject extends NodeObject implements SourceFile {
|
||||
public kind: SyntaxKind.SourceFile;
|
||||
public kind!: SyntaxKind.SourceFile;
|
||||
public _declarationBrand: any;
|
||||
public fileName: string;
|
||||
public path: Path;
|
||||
public resolvedPath: Path;
|
||||
public originalFileName: string;
|
||||
public text: string;
|
||||
public scriptSnapshot: IScriptSnapshot;
|
||||
public lineMap: ReadonlyArray<number>;
|
||||
public fileName!: string;
|
||||
public path!: Path;
|
||||
public resolvedPath!: Path;
|
||||
public originalFileName!: string;
|
||||
public text!: string;
|
||||
public scriptSnapshot!: IScriptSnapshot;
|
||||
public lineMap!: ReadonlyArray<number>;
|
||||
|
||||
public statements: NodeArray<Statement>;
|
||||
public endOfFileToken: Token<SyntaxKind.EndOfFileToken>;
|
||||
public statements!: NodeArray<Statement>;
|
||||
public endOfFileToken!: Token<SyntaxKind.EndOfFileToken>;
|
||||
|
||||
public amdDependencies: { name: string; path: string }[];
|
||||
public moduleName: string;
|
||||
public referencedFiles: FileReference[];
|
||||
public typeReferenceDirectives: FileReference[];
|
||||
public libReferenceDirectives: FileReference[];
|
||||
public amdDependencies!: { name: string; path: string }[];
|
||||
public moduleName!: string;
|
||||
public referencedFiles!: FileReference[];
|
||||
public typeReferenceDirectives!: FileReference[];
|
||||
public libReferenceDirectives!: FileReference[];
|
||||
|
||||
public syntacticDiagnostics: DiagnosticWithLocation[];
|
||||
public parseDiagnostics: DiagnosticWithLocation[];
|
||||
public bindDiagnostics: DiagnosticWithLocation[];
|
||||
public syntacticDiagnostics!: DiagnosticWithLocation[];
|
||||
public parseDiagnostics!: DiagnosticWithLocation[];
|
||||
public bindDiagnostics!: DiagnosticWithLocation[];
|
||||
public bindSuggestionDiagnostics?: DiagnosticWithLocation[];
|
||||
|
||||
public isDeclarationFile: boolean;
|
||||
public isDefaultLib: boolean;
|
||||
public hasNoDefaultLib: boolean;
|
||||
public externalModuleIndicator: Node; // The first node that causes this file to be an external module
|
||||
public commonJsModuleIndicator: Node; // The first node that causes this file to be a CommonJS module
|
||||
public nodeCount: number;
|
||||
public identifierCount: number;
|
||||
public symbolCount: number;
|
||||
public version: string;
|
||||
public scriptKind: ScriptKind;
|
||||
public languageVersion: ScriptTarget;
|
||||
public languageVariant: LanguageVariant;
|
||||
public identifiers: Map<string>;
|
||||
public nameTable: UnderscoreEscapedMap<number>;
|
||||
public resolvedModules: Map<ResolvedModuleFull>;
|
||||
public resolvedTypeReferenceDirectiveNames: Map<ResolvedTypeReferenceDirective>;
|
||||
public imports: ReadonlyArray<StringLiteralLike>;
|
||||
public moduleAugmentations: StringLiteral[];
|
||||
private namedDeclarations: Map<Declaration[]>;
|
||||
public ambientModuleNames: string[];
|
||||
public isDeclarationFile!: boolean;
|
||||
public isDefaultLib!: boolean;
|
||||
public hasNoDefaultLib!: boolean;
|
||||
public externalModuleIndicator!: Node; // The first node that causes this file to be an external module
|
||||
public commonJsModuleIndicator!: Node; // The first node that causes this file to be a CommonJS module
|
||||
public nodeCount!: number;
|
||||
public identifierCount!: number;
|
||||
public symbolCount!: number;
|
||||
public version!: string;
|
||||
public scriptKind!: ScriptKind;
|
||||
public languageVersion!: ScriptTarget;
|
||||
public languageVariant!: LanguageVariant;
|
||||
public identifiers!: Map<string>;
|
||||
public nameTable: UnderscoreEscapedMap<number> | undefined;
|
||||
public resolvedModules: Map<ResolvedModuleFull> | undefined;
|
||||
public resolvedTypeReferenceDirectiveNames!: Map<ResolvedTypeReferenceDirective>;
|
||||
public imports!: ReadonlyArray<StringLiteralLike>;
|
||||
public moduleAugmentations!: StringLiteral[];
|
||||
private namedDeclarations: Map<Declaration[]> | undefined;
|
||||
public ambientModuleNames!: string[];
|
||||
public checkJsDirective: CheckJsDirective | undefined;
|
||||
public possiblyContainDynamicImport: boolean;
|
||||
public pragmas: PragmaMap;
|
||||
public localJsxFactory: EntityName;
|
||||
public localJsxNamespace: __String;
|
||||
public possiblyContainDynamicImport?: boolean;
|
||||
public pragmas!: PragmaMap;
|
||||
public localJsxFactory: EntityName | undefined;
|
||||
public localJsxNamespace: __String | undefined;
|
||||
|
||||
constructor(kind: SyntaxKind, pos: number, end: number) {
|
||||
super(kind, pos, end);
|
||||
@@ -602,8 +602,8 @@ namespace ts {
|
||||
return getLineStarts(this);
|
||||
}
|
||||
|
||||
public getPositionOfLineAndCharacter(line: number, character: number): number {
|
||||
return getPositionOfLineAndCharacter(this, line, character);
|
||||
public getPositionOfLineAndCharacter(line: number, character: number, allowEdits?: true): number {
|
||||
return computePositionOfLineAndCharacter(getLineStarts(this), line, character, this.text, allowEdits);
|
||||
}
|
||||
|
||||
public getLineEndOfPosition(pos: number): number {
|
||||
@@ -774,7 +774,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
class SourceMapSourceObject implements SourceMapSource {
|
||||
lineMap: number[];
|
||||
lineMap!: number[];
|
||||
constructor(public fileName: string, public text: string, public skipTrivia?: (pos: number) => number) { }
|
||||
|
||||
public getLineAndCharacterOfPosition(pos: number): LineAndCharacter {
|
||||
@@ -955,10 +955,10 @@ namespace ts {
|
||||
class SyntaxTreeCache {
|
||||
// For our syntactic only features, we also keep a cache of the syntax tree for the
|
||||
// currently edited file.
|
||||
private currentFileName: string;
|
||||
private currentFileVersion: string;
|
||||
private currentFileScriptSnapshot: IScriptSnapshot;
|
||||
private currentSourceFile: SourceFile;
|
||||
private currentFileName: string | undefined;
|
||||
private currentFileVersion: string | undefined;
|
||||
private currentFileScriptSnapshot: IScriptSnapshot | undefined;
|
||||
private currentSourceFile: SourceFile | undefined;
|
||||
|
||||
constructor(private host: LanguageServiceHost) {
|
||||
}
|
||||
@@ -980,8 +980,8 @@ namespace ts {
|
||||
}
|
||||
else if (this.currentFileVersion !== version) {
|
||||
// This is the same file, just a newer version. Incrementally parse the file.
|
||||
const editRange = scriptSnapshot.getChangeRange(this.currentFileScriptSnapshot);
|
||||
sourceFile = updateLanguageServiceSourceFile(this.currentSourceFile, scriptSnapshot, version, editRange);
|
||||
const editRange = scriptSnapshot.getChangeRange(this.currentFileScriptSnapshot!);
|
||||
sourceFile = updateLanguageServiceSourceFile(this.currentSourceFile!, scriptSnapshot, version, editRange);
|
||||
}
|
||||
|
||||
if (sourceFile) {
|
||||
@@ -992,7 +992,7 @@ namespace ts {
|
||||
this.currentSourceFile = sourceFile;
|
||||
}
|
||||
|
||||
return this.currentSourceFile;
|
||||
return this.currentSourceFile!;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1139,7 +1139,16 @@ namespace ts {
|
||||
const useCaseSensitiveFileNames = hostUsesCaseSensitiveFileNames(host);
|
||||
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
|
||||
const sourceMapper = getSourceMapper(useCaseSensitiveFileNames, currentDirectory, log, host, () => program);
|
||||
const sourceMapper = getSourceMapper({
|
||||
useCaseSensitiveFileNames: () => useCaseSensitiveFileNames,
|
||||
getCurrentDirectory: () => currentDirectory,
|
||||
getProgram,
|
||||
fileExists: host.fileExists && (f => host.fileExists!(f)),
|
||||
readFile: host.readFile && ((f, encoding) => host.readFile!(f, encoding)),
|
||||
getDocumentPositionMapper: host.getDocumentPositionMapper && ((generatedFileName, sourceFileName) => host.getDocumentPositionMapper!(generatedFileName, sourceFileName)),
|
||||
getSourceFileLike: host.getSourceFileLike && (f => host.getSourceFileLike!(f)),
|
||||
log
|
||||
});
|
||||
|
||||
function getValidSourceFile(fileName: string): SourceFile {
|
||||
const sourceFile = program.getSourceFile(fileName);
|
||||
@@ -1203,15 +1212,7 @@ namespace ts {
|
||||
writeFile: noop,
|
||||
getCurrentDirectory: () => currentDirectory,
|
||||
fileExists,
|
||||
readFile(fileName) {
|
||||
// stub missing host functionality
|
||||
const path = toPath(fileName, currentDirectory, getCanonicalFileName);
|
||||
const entry = hostCache && hostCache.getEntryByPath(path);
|
||||
if (entry) {
|
||||
return isString(entry) ? undefined : getSnapshotText(entry.scriptSnapshot);
|
||||
}
|
||||
return host.readFile && host.readFile(fileName);
|
||||
},
|
||||
readFile,
|
||||
realpath: host.realpath && (path => host.realpath!(path)),
|
||||
directoryExists: directoryName => {
|
||||
return directoryProbablyExists(directoryName, host);
|
||||
@@ -1272,6 +1273,16 @@ namespace ts {
|
||||
(!!host.fileExists && host.fileExists(fileName));
|
||||
}
|
||||
|
||||
function readFile(fileName: string) {
|
||||
// stub missing host functionality
|
||||
const path = toPath(fileName, currentDirectory, getCanonicalFileName);
|
||||
const entry = hostCache && hostCache.getEntryByPath(path);
|
||||
if (entry) {
|
||||
return isString(entry) ? undefined : getSnapshotText(entry.scriptSnapshot);
|
||||
}
|
||||
return host.readFile && host.readFile(fileName);
|
||||
}
|
||||
|
||||
// Release any files we have acquired in the old program but are
|
||||
// not part of the new program.
|
||||
function onReleaseOldSourceFile(oldSourceFile: SourceFile, oldOptions: CompilerOptions) {
|
||||
@@ -1481,7 +1492,7 @@ namespace ts {
|
||||
function shouldGetType(sourceFile: SourceFile, node: Node, position: number): boolean {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return !isLabelName(node);
|
||||
return !isLabelName(node) && !isTagName(node);
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.QualifiedName:
|
||||
// Don't return quickInfo if inside the comment in `a/**/.b`
|
||||
@@ -2159,7 +2170,7 @@ namespace ts {
|
||||
function initializeNameTable(sourceFile: SourceFile): void {
|
||||
const nameTable = sourceFile.nameTable = createUnderscoreEscapedMap<number>();
|
||||
sourceFile.forEachChild(function walk(node) {
|
||||
if (isIdentifier(node) && node.escapedText || isStringOrNumericLiteralLike(node) && literalIsName(node)) {
|
||||
if (isIdentifier(node) && !isTagName(node) && node.escapedText || isStringOrNumericLiteralLike(node) && literalIsName(node)) {
|
||||
const text = getEscapedTextOfIdentifierOrLiteral(node);
|
||||
nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1);
|
||||
}
|
||||
|
||||
+11
-5
@@ -331,9 +331,9 @@ namespace ts {
|
||||
private loggingEnabled = false;
|
||||
private tracingEnabled = false;
|
||||
|
||||
public resolveModuleNames: (moduleName: string[], containingFile: string) => (ResolvedModuleFull | undefined)[];
|
||||
public resolveTypeReferenceDirectives: (typeDirectiveNames: string[], containingFile: string) => (ResolvedTypeReferenceDirective | undefined)[];
|
||||
public directoryExists: (directoryName: string) => boolean;
|
||||
public resolveModuleNames: ((moduleName: string[], containingFile: string) => (ResolvedModuleFull | undefined)[]) | undefined;
|
||||
public resolveTypeReferenceDirectives: ((typeDirectiveNames: string[], containingFile: string) => (ResolvedTypeReferenceDirective | undefined)[]) | undefined;
|
||||
public directoryExists: ((directoryName: string) => boolean) | undefined;
|
||||
|
||||
constructor(private shimHost: LanguageServiceShimHost) {
|
||||
// if shimHost is a COM object then property check will become method call with no arguments.
|
||||
@@ -490,13 +490,19 @@ namespace ts {
|
||||
public useCaseSensitiveFileNames: boolean;
|
||||
|
||||
constructor(private shimHost: CoreServicesShimHost) {
|
||||
this.useCaseSensitiveFileNames = this.shimHost.useCaseSensitiveFileNames ? this.shimHost.useCaseSensitiveFileNames() : false;
|
||||
this.useCaseSensitiveFileNames = this.shimHost.useCaseSensitiveFileNames ? this.shimHost.useCaseSensitiveFileNames() : false;
|
||||
if ("directoryExists" in this.shimHost) {
|
||||
this.directoryExists = directoryName => this.shimHost.directoryExists(directoryName);
|
||||
}
|
||||
else {
|
||||
this.directoryExists = undefined!; // TODO: GH#18217
|
||||
}
|
||||
if ("realpath" in this.shimHost) {
|
||||
this.realpath = path => this.shimHost.realpath!(path); // TODO: GH#18217
|
||||
}
|
||||
else {
|
||||
this.realpath = undefined!; // TODO: GH#18217
|
||||
}
|
||||
}
|
||||
|
||||
public readDirectory(rootDir: string, extensions: ReadonlyArray<string>, exclude: ReadonlyArray<string>, include: ReadonlyArray<string>, depth?: number): string[] {
|
||||
@@ -1182,7 +1188,7 @@ namespace ts {
|
||||
|
||||
export class TypeScriptServicesFactory implements ShimFactory {
|
||||
private _shims: Shim[] = [];
|
||||
private documentRegistry: DocumentRegistry;
|
||||
private documentRegistry: DocumentRegistry | undefined;
|
||||
|
||||
/*
|
||||
* Returns script API version.
|
||||
|
||||
+134
-103
@@ -9,151 +9,182 @@ namespace ts {
|
||||
clearCache(): void;
|
||||
}
|
||||
|
||||
export function getSourceMapper(
|
||||
useCaseSensitiveFileNames: boolean,
|
||||
currentDirectory: string,
|
||||
log: (message: string) => void,
|
||||
host: LanguageServiceHost,
|
||||
getProgram: () => Program,
|
||||
): SourceMapper {
|
||||
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
let sourcemappedFileCache: SourceFileLikeCache;
|
||||
export interface SourceMapperHost {
|
||||
useCaseSensitiveFileNames(): boolean;
|
||||
getCurrentDirectory(): string;
|
||||
getProgram(): Program | undefined;
|
||||
fileExists?(path: string): boolean;
|
||||
readFile?(path: string, encoding?: string): string | undefined;
|
||||
getSourceFileLike?(fileName: string): SourceFileLike | undefined;
|
||||
getDocumentPositionMapper?(generatedFileName: string, sourceFileName?: string): DocumentPositionMapper | undefined;
|
||||
log(s: string): void;
|
||||
}
|
||||
|
||||
export function getSourceMapper(host: SourceMapperHost): SourceMapper {
|
||||
const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames());
|
||||
const currentDirectory = host.getCurrentDirectory();
|
||||
const sourceFileLike = createMap<SourceFileLike | false>();
|
||||
const documentPositionMappers = createMap<DocumentPositionMapper>();
|
||||
return { tryGetSourcePosition, tryGetGeneratedPosition, toLineColumnOffset, clearCache };
|
||||
|
||||
function toPath(fileName: string) {
|
||||
return ts.toPath(fileName, currentDirectory, getCanonicalFileName);
|
||||
}
|
||||
|
||||
function scanForSourcemapURL(fileName: string) {
|
||||
const mappedFile = sourcemappedFileCache.get(toPath(fileName));
|
||||
if (!mappedFile) {
|
||||
return;
|
||||
}
|
||||
function getDocumentPositionMapper(generatedFileName: string, sourceFileName?: string) {
|
||||
const path = toPath(generatedFileName);
|
||||
const value = documentPositionMappers.get(path);
|
||||
if (value) return value;
|
||||
|
||||
return tryGetSourceMappingURL(mappedFile.text, getLineStarts(mappedFile));
|
||||
}
|
||||
|
||||
function convertDocumentToSourceMapper(file: { sourceMapper?: DocumentPositionMapper }, contents: string, mapFileName: string) {
|
||||
const map = tryParseRawSourceMap(contents);
|
||||
if (!map || !map.sources || !map.file || !map.mappings) {
|
||||
// obviously invalid map
|
||||
return file.sourceMapper = identitySourceMapConsumer;
|
||||
let mapper: DocumentPositionMapper | undefined;
|
||||
if (host.getDocumentPositionMapper) {
|
||||
mapper = host.getDocumentPositionMapper(generatedFileName, sourceFileName);
|
||||
}
|
||||
const program = getProgram();
|
||||
return file.sourceMapper = createDocumentPositionMapper({
|
||||
getSourceFileLike: s => {
|
||||
// Lookup file in program, if provided
|
||||
const file = program && program.getSourceFileByPath(s);
|
||||
// file returned here could be .d.ts when asked for .ts file if projectReferences and module resolution created this source file
|
||||
if (file === undefined || file.resolvedPath !== s) {
|
||||
// Otherwise check the cache (which may hit disk)
|
||||
return sourcemappedFileCache.get(s);
|
||||
}
|
||||
return file;
|
||||
},
|
||||
getCanonicalFileName,
|
||||
log,
|
||||
}, map, mapFileName);
|
||||
}
|
||||
|
||||
function getSourceMapper(fileName: string, file: SourceFileLike): DocumentPositionMapper {
|
||||
if (!host.readFile || !host.fileExists) {
|
||||
return file.sourceMapper = identitySourceMapConsumer;
|
||||
else if (host.readFile) {
|
||||
const file = getSourceFileLike(generatedFileName);
|
||||
mapper = file && ts.getDocumentPositionMapper(
|
||||
{ getSourceFileLike, getCanonicalFileName, log: s => host.log(s) },
|
||||
generatedFileName,
|
||||
getLineInfo(file.text, getLineStarts(file)),
|
||||
f => !host.fileExists || host.fileExists(f) ? host.readFile!(f) : undefined
|
||||
);
|
||||
}
|
||||
if (file.sourceMapper) {
|
||||
return file.sourceMapper;
|
||||
}
|
||||
let mapFileName = scanForSourcemapURL(fileName);
|
||||
if (mapFileName) {
|
||||
const match = base64UrlRegExp.exec(mapFileName);
|
||||
if (match) {
|
||||
if (match[1]) {
|
||||
const base64Object = match[1];
|
||||
return convertDocumentToSourceMapper(file, base64decode(sys, base64Object), fileName);
|
||||
}
|
||||
// Not a data URL we can parse, skip it
|
||||
mapFileName = undefined;
|
||||
}
|
||||
}
|
||||
const possibleMapLocations: string[] = [];
|
||||
if (mapFileName) {
|
||||
possibleMapLocations.push(mapFileName);
|
||||
}
|
||||
possibleMapLocations.push(fileName + ".map");
|
||||
for (const location of possibleMapLocations) {
|
||||
const mapPath = ts.toPath(location, getDirectoryPath(fileName), getCanonicalFileName);
|
||||
if (host.fileExists(mapPath)) {
|
||||
return convertDocumentToSourceMapper(file, host.readFile(mapPath)!, mapPath); // TODO: GH#18217
|
||||
}
|
||||
}
|
||||
return file.sourceMapper = identitySourceMapConsumer;
|
||||
documentPositionMappers.set(path, mapper || identitySourceMapConsumer);
|
||||
return mapper || identitySourceMapConsumer;
|
||||
}
|
||||
|
||||
function tryGetSourcePosition(info: DocumentPosition): DocumentPosition | undefined {
|
||||
if (!isDeclarationFileName(info.fileName)) return undefined;
|
||||
|
||||
const file = getFile(info.fileName);
|
||||
const file = getSourceFile(info.fileName);
|
||||
if (!file) return undefined;
|
||||
const newLoc = getSourceMapper(info.fileName, file).getSourcePosition(info);
|
||||
return newLoc === info ? undefined : tryGetSourcePosition(newLoc) || newLoc;
|
||||
|
||||
const newLoc = getDocumentPositionMapper(info.fileName).getSourcePosition(info);
|
||||
return !newLoc || newLoc === info ? undefined : tryGetSourcePosition(newLoc) || newLoc;
|
||||
}
|
||||
|
||||
function tryGetGeneratedPosition(info: DocumentPosition): DocumentPosition | undefined {
|
||||
const program = getProgram();
|
||||
if (isDeclarationFileName(info.fileName)) return undefined;
|
||||
|
||||
const sourceFile = getSourceFile(info.fileName);
|
||||
if (!sourceFile) return undefined;
|
||||
|
||||
const program = host.getProgram()!;
|
||||
const options = program.getCompilerOptions();
|
||||
const outPath = options.outFile || options.out;
|
||||
|
||||
const declarationPath = outPath ?
|
||||
removeFileExtension(outPath) + Extension.Dts :
|
||||
getDeclarationEmitOutputFilePathWorker(info.fileName, program.getCompilerOptions(), currentDirectory, program.getCommonSourceDirectory(), getCanonicalFileName);
|
||||
if (declarationPath === undefined) return undefined;
|
||||
const declarationFile = getFile(declarationPath);
|
||||
if (!declarationFile) return undefined;
|
||||
const newLoc = getSourceMapper(declarationPath, declarationFile).getGeneratedPosition(info);
|
||||
|
||||
const newLoc = getDocumentPositionMapper(declarationPath, info.fileName).getGeneratedPosition(info);
|
||||
return newLoc === info ? undefined : newLoc;
|
||||
}
|
||||
|
||||
function getFile(fileName: string): SourceFileLike | undefined {
|
||||
function getSourceFile(fileName: string) {
|
||||
const program = host.getProgram();
|
||||
if (!program) return undefined;
|
||||
|
||||
const path = toPath(fileName);
|
||||
const file = getProgram().getSourceFileByPath(path);
|
||||
if (file && file.resolvedPath === path) {
|
||||
return file;
|
||||
// file returned here could be .d.ts when asked for .ts file if projectReferences and module resolution created this source file
|
||||
const file = program.getSourceFileByPath(path);
|
||||
return file && file.resolvedPath === path ? file : undefined;
|
||||
}
|
||||
|
||||
function getOrCreateSourceFileLike(fileName: string): SourceFileLike | undefined {
|
||||
const path = toPath(fileName);
|
||||
const fileFromCache = sourceFileLike.get(path);
|
||||
if (fileFromCache !== undefined) return fileFromCache ? fileFromCache : undefined;
|
||||
|
||||
if (!host.readFile || host.fileExists && !host.fileExists(path)) {
|
||||
sourceFileLike.set(path, false);
|
||||
return undefined;
|
||||
}
|
||||
return sourcemappedFileCache.get(path);
|
||||
|
||||
// And failing that, check the disk
|
||||
const text = host.readFile(path);
|
||||
const file = text ? createSourceFileLike(text) : false;
|
||||
sourceFileLike.set(path, file);
|
||||
return file ? file : undefined;
|
||||
}
|
||||
|
||||
// This can be called from source mapper in either source program or program that includes generated file
|
||||
function getSourceFileLike(fileName: string) {
|
||||
return !host.getSourceFileLike ?
|
||||
getSourceFile(fileName) || getOrCreateSourceFileLike(fileName) :
|
||||
host.getSourceFileLike(fileName);
|
||||
}
|
||||
|
||||
function toLineColumnOffset(fileName: string, position: number): LineAndCharacter {
|
||||
const file = getFile(fileName)!; // TODO: GH#18217
|
||||
const file = getSourceFileLike(fileName)!; // TODO: GH#18217
|
||||
return file.getLineAndCharacterOfPosition(position);
|
||||
}
|
||||
|
||||
function clearCache(): void {
|
||||
sourcemappedFileCache = createSourceFileLikeCache(host);
|
||||
sourceFileLike.clear();
|
||||
documentPositionMappers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
interface SourceFileLikeCache {
|
||||
get(path: Path): SourceFileLike | undefined;
|
||||
/**
|
||||
* string | undefined to contents of map file to create DocumentPositionMapper from it
|
||||
* DocumentPositionMapper | false to give back cached DocumentPositionMapper
|
||||
*/
|
||||
export type ReadMapFile = (mapFileName: string, mapFileNameFromDts: string | undefined) => string | undefined | DocumentPositionMapper | false;
|
||||
|
||||
export function getDocumentPositionMapper(
|
||||
host: DocumentPositionMapperHost,
|
||||
generatedFileName: string,
|
||||
generatedFileLineInfo: LineInfo,
|
||||
readMapFile: ReadMapFile) {
|
||||
let mapFileName = tryGetSourceMappingURL(generatedFileLineInfo);
|
||||
if (mapFileName) {
|
||||
const match = base64UrlRegExp.exec(mapFileName);
|
||||
if (match) {
|
||||
if (match[1]) {
|
||||
const base64Object = match[1];
|
||||
return convertDocumentToSourceMapper(host, base64decode(sys, base64Object), generatedFileName);
|
||||
}
|
||||
// Not a data URL we can parse, skip it
|
||||
mapFileName = undefined;
|
||||
}
|
||||
}
|
||||
const possibleMapLocations: string[] = [];
|
||||
if (mapFileName) {
|
||||
possibleMapLocations.push(mapFileName);
|
||||
}
|
||||
possibleMapLocations.push(generatedFileName + ".map");
|
||||
const originalMapFileName = mapFileName && getNormalizedAbsolutePath(mapFileName, getDirectoryPath(generatedFileName));
|
||||
for (const location of possibleMapLocations) {
|
||||
const mapFileName = getNormalizedAbsolutePath(location, getDirectoryPath(generatedFileName));
|
||||
const mapFileContents = readMapFile(mapFileName, originalMapFileName);
|
||||
if (isString(mapFileContents)) {
|
||||
return convertDocumentToSourceMapper(host, mapFileContents, mapFileName);
|
||||
}
|
||||
if (mapFileContents !== undefined) {
|
||||
return mapFileContents || undefined;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function createSourceFileLikeCache(host: { readFile?: (path: string) => string | undefined, fileExists?: (path: string) => boolean }): SourceFileLikeCache {
|
||||
const cached = createMap<SourceFileLike>();
|
||||
function convertDocumentToSourceMapper(host: DocumentPositionMapperHost, contents: string, mapFileName: string) {
|
||||
const map = tryParseRawSourceMap(contents);
|
||||
if (!map || !map.sources || !map.file || !map.mappings) {
|
||||
// obviously invalid map
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return createDocumentPositionMapper(host, map, mapFileName);
|
||||
}
|
||||
|
||||
function createSourceFileLike(text: string, lineMap?: SourceFileLike["lineMap"]): SourceFileLike {
|
||||
return {
|
||||
get(path: Path) {
|
||||
if (cached.has(path)) {
|
||||
return cached.get(path);
|
||||
}
|
||||
if (!host.fileExists || !host.readFile || !host.fileExists(path)) return;
|
||||
// And failing that, check the disk
|
||||
const text = host.readFile(path)!; // TODO: GH#18217
|
||||
const file = {
|
||||
text,
|
||||
lineMap: undefined,
|
||||
getLineAndCharacterOfPosition(pos: number) {
|
||||
return computeLineAndCharacterOfPosition(getLineStarts(this), pos);
|
||||
}
|
||||
} as SourceFileLike;
|
||||
cached.set(path, file);
|
||||
return file;
|
||||
text,
|
||||
lineMap,
|
||||
getLineAndCharacterOfPosition(pos: number) {
|
||||
return computeLineAndCharacterOfPosition(getLineStarts(this), pos);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -281,33 +281,26 @@ namespace ts.Completions.StringCompletions {
|
||||
* Takes a script path and returns paths for all potential folders that could be merged with its
|
||||
* containing folder via the "rootDirs" compiler option
|
||||
*/
|
||||
function getBaseDirectoriesFromRootDirs(rootDirs: string[], basePath: string, scriptPath: string, ignoreCase: boolean): string[] {
|
||||
function getBaseDirectoriesFromRootDirs(rootDirs: string[], basePath: string, scriptDirectory: string, ignoreCase: boolean): ReadonlyArray<string> {
|
||||
// Make all paths absolute/normalized if they are not already
|
||||
rootDirs = rootDirs.map(rootDirectory => normalizePath(isRootedDiskPath(rootDirectory) ? rootDirectory : combinePaths(basePath, rootDirectory)));
|
||||
|
||||
// Determine the path to the directory containing the script relative to the root directory it is contained within
|
||||
const relativeDirectory = firstDefined(rootDirs, rootDirectory =>
|
||||
containsPath(rootDirectory, scriptPath, basePath, ignoreCase) ? scriptPath.substr(rootDirectory.length) : undefined)!; // TODO: GH#18217
|
||||
containsPath(rootDirectory, scriptDirectory, basePath, ignoreCase) ? scriptDirectory.substr(rootDirectory.length) : undefined)!; // TODO: GH#18217
|
||||
|
||||
// Now find a path for each potential directory that is to be merged with the one containing the script
|
||||
return deduplicate<string>(
|
||||
rootDirs.map(rootDirectory => combinePaths(rootDirectory, relativeDirectory)),
|
||||
[...rootDirs.map(rootDirectory => combinePaths(rootDirectory, relativeDirectory)), scriptDirectory],
|
||||
equateStringsCaseSensitive,
|
||||
compareStringsCaseSensitive);
|
||||
}
|
||||
|
||||
function getCompletionEntriesForDirectoryFragmentWithRootDirs(rootDirs: string[], fragment: string, scriptPath: string, extensionOptions: ExtensionOptions, compilerOptions: CompilerOptions, host: LanguageServiceHost, exclude?: string): NameAndKind[] {
|
||||
function getCompletionEntriesForDirectoryFragmentWithRootDirs(rootDirs: string[], fragment: string, scriptDirectory: string, extensionOptions: ExtensionOptions, compilerOptions: CompilerOptions, host: LanguageServiceHost, exclude: string): ReadonlyArray<NameAndKind> {
|
||||
const basePath = compilerOptions.project || host.getCurrentDirectory();
|
||||
const ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
|
||||
const baseDirectories = getBaseDirectoriesFromRootDirs(rootDirs, basePath, scriptPath, ignoreCase);
|
||||
|
||||
const result: NameAndKind[] = [];
|
||||
|
||||
for (const baseDirectory of baseDirectories) {
|
||||
getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensionOptions, host, exclude, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
const baseDirectories = getBaseDirectoriesFromRootDirs(rootDirs, basePath, scriptDirectory, ignoreCase);
|
||||
return flatMap(baseDirectories, baseDirectory => getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensionOptions, host, exclude));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
const visitedNestedConvertibleFunctions = createMap<true>();
|
||||
|
||||
export function computeSuggestionDiagnostics(sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken): DiagnosticWithLocation[] {
|
||||
program.getSemanticDiagnostics(sourceFile, cancellationToken);
|
||||
const diags: DiagnosticWithLocation[] = [];
|
||||
@@ -13,6 +15,7 @@ namespace ts {
|
||||
|
||||
const isJsFile = isSourceFileJS(sourceFile);
|
||||
|
||||
visitedNestedConvertibleFunctions.clear();
|
||||
check(sourceFile);
|
||||
|
||||
if (getAllowSyntheticDefaultImports(program.getCompilerOptions())) {
|
||||
@@ -114,17 +117,22 @@ namespace ts {
|
||||
}
|
||||
|
||||
function addConvertToAsyncFunctionDiagnostics(node: FunctionLikeDeclaration, checker: TypeChecker, diags: Push<DiagnosticWithLocation>): void {
|
||||
if (!isAsyncFunction(node) &&
|
||||
node.body &&
|
||||
isBlock(node.body) &&
|
||||
hasReturnStatementWithPromiseHandler(node.body) &&
|
||||
returnsPromise(node, checker)) {
|
||||
// need to check function before checking map so that deeper levels of nested callbacks are checked
|
||||
if (isConvertibleFunction(node, checker) && !visitedNestedConvertibleFunctions.has(getKeyFromNode(node))) {
|
||||
diags.push(createDiagnosticForNode(
|
||||
!node.name && isVariableDeclaration(node.parent) && isIdentifier(node.parent.name) ? node.parent.name : node,
|
||||
Diagnostics.This_may_be_converted_to_an_async_function));
|
||||
}
|
||||
}
|
||||
|
||||
function isConvertibleFunction(node: FunctionLikeDeclaration, checker: TypeChecker) {
|
||||
return !isAsyncFunction(node) &&
|
||||
node.body &&
|
||||
isBlock(node.body) &&
|
||||
hasReturnStatementWithPromiseHandler(node.body) &&
|
||||
returnsPromise(node, checker);
|
||||
}
|
||||
|
||||
function returnsPromise(node: FunctionLikeDeclaration, checker: TypeChecker): boolean {
|
||||
const functionType = checker.getTypeAtLocation(node);
|
||||
const callSignatures = checker.getSignaturesOfType(functionType, SignatureKind.Call);
|
||||
@@ -169,14 +177,20 @@ namespace ts {
|
||||
// should be kept up to date with getTransformationBody in convertToAsyncFunction.ts
|
||||
function isFixablePromiseArgument(arg: Expression): boolean {
|
||||
switch (arg.kind) {
|
||||
case SyntaxKind.NullKeyword:
|
||||
case SyntaxKind.Identifier: // identifier includes undefined
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
visitedNestedConvertibleFunctions.set(getKeyFromNode(arg as FunctionLikeDeclaration), true);
|
||||
/* falls through */
|
||||
case SyntaxKind.NullKeyword:
|
||||
case SyntaxKind.Identifier: // identifier includes undefined
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function getKeyFromNode(exp: FunctionLikeDeclaration) {
|
||||
return `${exp.pos.toString()}:${exp.end.toString()}`;
|
||||
}
|
||||
}
|
||||
|
||||
+22
-27
@@ -228,9 +228,8 @@ namespace ts.textChanges {
|
||||
/** Public for tests only. Other callers should use `ChangeTracker.with`. */
|
||||
constructor(private readonly newLineCharacter: string, private readonly formatContext: formatting.FormatContext) {}
|
||||
|
||||
public deleteRange(sourceFile: SourceFile, range: TextRange) {
|
||||
public deleteRange(sourceFile: SourceFile, range: TextRange): void {
|
||||
this.changes.push({ kind: ChangeKind.Remove, sourceFile, range });
|
||||
return this;
|
||||
}
|
||||
|
||||
delete(sourceFile: SourceFile, node: Node | NodeArray<TypeParameterDeclaration>): void {
|
||||
@@ -241,11 +240,10 @@ namespace ts.textChanges {
|
||||
this.deleteRange(sourceFile, { pos: modifier.getStart(sourceFile), end: skipTrivia(sourceFile.text, modifier.end, /*stopAfterLineBreak*/ true) });
|
||||
}
|
||||
|
||||
public deleteNodeRange(sourceFile: SourceFile, startNode: Node, endNode: Node, options: ConfigurableStartEnd = {}) {
|
||||
public deleteNodeRange(sourceFile: SourceFile, startNode: Node, endNode: Node, options: ConfigurableStartEnd = {}): void {
|
||||
const startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.FullStart);
|
||||
const endPosition = getAdjustedEndPosition(sourceFile, endNode, options);
|
||||
this.deleteRange(sourceFile, { pos: startPosition, end: endPosition });
|
||||
return this;
|
||||
}
|
||||
|
||||
public deleteNodeRangeExcludingEnd(sourceFile: SourceFile, startNode: Node, afterEndNode: Node | undefined, options: ConfigurableStartEnd = {}): void {
|
||||
@@ -254,34 +252,32 @@ namespace ts.textChanges {
|
||||
this.deleteRange(sourceFile, { pos: startPosition, end: endPosition });
|
||||
}
|
||||
|
||||
public replaceRange(sourceFile: SourceFile, range: TextRange, newNode: Node, options: InsertNodeOptions = {}) {
|
||||
public replaceRange(sourceFile: SourceFile, range: TextRange, newNode: Node, options: InsertNodeOptions = {}): void {
|
||||
this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile, range, options, node: newNode });
|
||||
return this;
|
||||
}
|
||||
|
||||
public replaceNode(sourceFile: SourceFile, oldNode: Node, newNode: Node, options: ChangeNodeOptions = useNonAdjustedPositions) {
|
||||
return this.replaceRange(sourceFile, getAdjustedRange(sourceFile, oldNode, oldNode, options), newNode, options);
|
||||
public replaceNode(sourceFile: SourceFile, oldNode: Node, newNode: Node, options: ChangeNodeOptions = useNonAdjustedPositions): void {
|
||||
this.replaceRange(sourceFile, getAdjustedRange(sourceFile, oldNode, oldNode, options), newNode, options);
|
||||
}
|
||||
|
||||
public replaceNodeRange(sourceFile: SourceFile, startNode: Node, endNode: Node, newNode: Node, options: ChangeNodeOptions = useNonAdjustedPositions) {
|
||||
public replaceNodeRange(sourceFile: SourceFile, startNode: Node, endNode: Node, newNode: Node, options: ChangeNodeOptions = useNonAdjustedPositions): void {
|
||||
this.replaceRange(sourceFile, getAdjustedRange(sourceFile, startNode, endNode, options), newNode, options);
|
||||
}
|
||||
|
||||
private replaceRangeWithNodes(sourceFile: SourceFile, range: TextRange, newNodes: ReadonlyArray<Node>, options: ReplaceWithMultipleNodesOptions & ConfigurableStartEnd = {}) {
|
||||
private replaceRangeWithNodes(sourceFile: SourceFile, range: TextRange, newNodes: ReadonlyArray<Node>, options: ReplaceWithMultipleNodesOptions & ConfigurableStartEnd = {}): void {
|
||||
this.changes.push({ kind: ChangeKind.ReplaceWithMultipleNodes, sourceFile, range, options, nodes: newNodes });
|
||||
return this;
|
||||
}
|
||||
|
||||
public replaceNodeWithNodes(sourceFile: SourceFile, oldNode: Node, newNodes: ReadonlyArray<Node>, options: ChangeNodeOptions = useNonAdjustedPositions) {
|
||||
return this.replaceRangeWithNodes(sourceFile, getAdjustedRange(sourceFile, oldNode, oldNode, options), newNodes, options);
|
||||
public replaceNodeWithNodes(sourceFile: SourceFile, oldNode: Node, newNodes: ReadonlyArray<Node>, options: ChangeNodeOptions = useNonAdjustedPositions): void {
|
||||
this.replaceRangeWithNodes(sourceFile, getAdjustedRange(sourceFile, oldNode, oldNode, options), newNodes, options);
|
||||
}
|
||||
|
||||
public replaceNodeWithText(sourceFile: SourceFile, oldNode: Node, text: string): void {
|
||||
this.replaceRangeWithText(sourceFile, getAdjustedRange(sourceFile, oldNode, oldNode, useNonAdjustedPositions), text);
|
||||
}
|
||||
|
||||
public replaceNodeRangeWithNodes(sourceFile: SourceFile, startNode: Node, endNode: Node, newNodes: ReadonlyArray<Node>, options: ReplaceWithMultipleNodesOptions & ConfigurableStartEnd = useNonAdjustedPositions) {
|
||||
return this.replaceRangeWithNodes(sourceFile, getAdjustedRange(sourceFile, startNode, endNode, options), newNodes, options);
|
||||
public replaceNodeRangeWithNodes(sourceFile: SourceFile, startNode: Node, endNode: Node, newNodes: ReadonlyArray<Node>, options: ReplaceWithMultipleNodesOptions & ConfigurableStartEnd = useNonAdjustedPositions): void {
|
||||
this.replaceRangeWithNodes(sourceFile, getAdjustedRange(sourceFile, startNode, endNode, options), newNodes, options);
|
||||
}
|
||||
|
||||
private nextCommaToken(sourceFile: SourceFile, node: Node): Node | undefined {
|
||||
@@ -289,12 +285,12 @@ namespace ts.textChanges {
|
||||
return next && next.kind === SyntaxKind.CommaToken ? next : undefined;
|
||||
}
|
||||
|
||||
public replacePropertyAssignment(sourceFile: SourceFile, oldNode: PropertyAssignment, newNode: PropertyAssignment) {
|
||||
public replacePropertyAssignment(sourceFile: SourceFile, oldNode: PropertyAssignment, newNode: PropertyAssignment): void {
|
||||
const suffix = this.nextCommaToken(sourceFile, oldNode) ? "" : ("," + this.newLineCharacter);
|
||||
return this.replaceNode(sourceFile, oldNode, newNode, { suffix });
|
||||
this.replaceNode(sourceFile, oldNode, newNode, { suffix });
|
||||
}
|
||||
|
||||
public insertNodeAt(sourceFile: SourceFile, pos: number, newNode: Node, options: InsertNodeOptions = {}) {
|
||||
public insertNodeAt(sourceFile: SourceFile, pos: number, newNode: Node, options: InsertNodeOptions = {}): void {
|
||||
this.replaceRange(sourceFile, createRange(pos), newNode, options);
|
||||
}
|
||||
|
||||
@@ -310,7 +306,7 @@ namespace ts.textChanges {
|
||||
});
|
||||
}
|
||||
|
||||
public insertNodeBefore(sourceFile: SourceFile, before: Node, newNode: Node, blankLineBetween = false) {
|
||||
public insertNodeBefore(sourceFile: SourceFile, before: Node, newNode: Node, blankLineBetween = false): void {
|
||||
this.insertNodeAt(sourceFile, getAdjustedStartPosition(sourceFile, before, {}, Position.Start), newNode, this.getOptionsForInsertNodeBefore(before, blankLineBetween));
|
||||
}
|
||||
|
||||
@@ -343,7 +339,7 @@ namespace ts.textChanges {
|
||||
this.insertText(sourceFile, token.getStart(sourceFile), text);
|
||||
}
|
||||
|
||||
public insertJsdocCommentBefore(sourceFile: SourceFile, node: HasJSDoc, tag: JSDoc) {
|
||||
public insertJsdocCommentBefore(sourceFile: SourceFile, node: HasJSDoc, tag: JSDoc): void {
|
||||
const fnStart = node.getStart(sourceFile);
|
||||
if (node.jsDoc) {
|
||||
for (const jsdoc of node.jsDoc) {
|
||||
@@ -358,7 +354,7 @@ namespace ts.textChanges {
|
||||
this.insertNodeAt(sourceFile, fnStart, tag, { preserveLeadingWhitespace: false, suffix: this.newLineCharacter + indent });
|
||||
}
|
||||
|
||||
public replaceRangeWithText(sourceFile: SourceFile, range: TextRange, text: string) {
|
||||
public replaceRangeWithText(sourceFile: SourceFile, range: TextRange, text: string): void {
|
||||
this.changes.push({ kind: ChangeKind.Text, sourceFile, range, text });
|
||||
}
|
||||
|
||||
@@ -500,7 +496,7 @@ namespace ts.textChanges {
|
||||
return endPosition;
|
||||
}
|
||||
|
||||
private getInsertNodeAfterOptions(sourceFile: SourceFile, after: Node) {
|
||||
private getInsertNodeAfterOptions(sourceFile: SourceFile, after: Node): InsertNodeOptions {
|
||||
const options = this.getInsertNodeAfterOptionsWorker(after);
|
||||
return {
|
||||
...options,
|
||||
@@ -571,14 +567,14 @@ namespace ts.textChanges {
|
||||
* i.e. arguments in arguments lists, parameters in parameter lists etc.
|
||||
* Note that separators are part of the node in statements and class elements.
|
||||
*/
|
||||
public insertNodeInListAfter(sourceFile: SourceFile, after: Node, newNode: Node, containingList = formatting.SmartIndenter.getContainingList(after, sourceFile)) {
|
||||
public insertNodeInListAfter(sourceFile: SourceFile, after: Node, newNode: Node, containingList = formatting.SmartIndenter.getContainingList(after, sourceFile)): void {
|
||||
if (!containingList) {
|
||||
Debug.fail("node is not a list element");
|
||||
return this;
|
||||
return;
|
||||
}
|
||||
const index = indexOfNode(containingList, after);
|
||||
if (index < 0) {
|
||||
return this;
|
||||
return;
|
||||
}
|
||||
const end = after.getEnd();
|
||||
if (index !== containingList.length - 1) {
|
||||
@@ -680,7 +676,6 @@ namespace ts.textChanges {
|
||||
this.replaceRange(sourceFile, createRange(end), newNode, { prefix: `${tokenToString(separator)} ` });
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private finishClassesWithNodesInsertedAtStart(): void {
|
||||
@@ -734,7 +729,7 @@ namespace ts.textChanges {
|
||||
return changes;
|
||||
}
|
||||
|
||||
public createNewFile(oldFile: SourceFile | undefined, fileName: string, statements: ReadonlyArray<Statement>) {
|
||||
public createNewFile(oldFile: SourceFile | undefined, fileName: string, statements: ReadonlyArray<Statement>): void {
|
||||
this.newFiles.push({ oldFile, fileName, statements });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
"refactorProvider.ts",
|
||||
"codefixes/addConvertToUnknownForNonOverlappingTypes.ts",
|
||||
"codefixes/addMissingInvocationForDecorator.ts",
|
||||
"codefixes/addNameToNamelessParameter.ts",
|
||||
"codefixes/annotateWithTypeFromJSDoc.ts",
|
||||
"codefixes/inferFromUsage.ts",
|
||||
"codefixes/convertFunctionToEs6Class.ts",
|
||||
@@ -55,6 +56,7 @@
|
||||
"codefixes/importFixes.ts",
|
||||
"codefixes/fixSpelling.ts",
|
||||
"codefixes/fixAddMissingMember.ts",
|
||||
"codefixes/fixAddMissingNewOperator.ts",
|
||||
"codefixes/fixCannotFindModule.ts",
|
||||
"codefixes/fixClassDoesntImplementInheritedAbstractMember.ts",
|
||||
"codefixes/fixClassSuperMustPrecedeThisAccess.ts",
|
||||
|
||||
@@ -91,7 +91,6 @@ namespace ts {
|
||||
|
||||
export interface SourceFileLike {
|
||||
getLineAndCharacterOfPosition(pos: number): LineAndCharacter;
|
||||
/*@internal*/ sourceMapper?: DocumentPositionMapper;
|
||||
}
|
||||
|
||||
export interface SourceMapSource {
|
||||
@@ -233,6 +232,11 @@ namespace ts {
|
||||
installPackage?(options: InstallPackageOptions): Promise<ApplyCodeActionCommandResult>;
|
||||
/* @internal */ inspectValue?(options: InspectValueOptions): Promise<ValueInfo>;
|
||||
writeFile?(fileName: string, content: string): void;
|
||||
|
||||
/* @internal */
|
||||
getDocumentPositionMapper?(generatedFileName: string, sourceFileName?: string): DocumentPositionMapper | undefined;
|
||||
/* @internal */
|
||||
getSourceFileLike?(fileName: string): SourceFileLike | undefined;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -489,7 +493,7 @@ namespace ts {
|
||||
position: number;
|
||||
}
|
||||
|
||||
export class TextChange {
|
||||
export interface TextChange {
|
||||
span: TextSpan;
|
||||
newText: string;
|
||||
}
|
||||
|
||||
@@ -246,6 +246,10 @@ namespace ts {
|
||||
return isLabelOfLabeledStatement(node) || isJumpStatementTarget(node);
|
||||
}
|
||||
|
||||
export function isTagName(node: Node): boolean {
|
||||
return isJSDocTag(node.parent) && node.parent.tagName === node;
|
||||
}
|
||||
|
||||
export function isRightSideOfQualifiedName(node: Node) {
|
||||
return node.parent.kind === SyntaxKind.QualifiedName && (<QualifiedName>node.parent).right === node;
|
||||
}
|
||||
@@ -1212,6 +1216,7 @@ namespace ts {
|
||||
|
||||
export const typeKeywords: ReadonlyArray<SyntaxKind> = [
|
||||
SyntaxKind.AnyKeyword,
|
||||
SyntaxKind.BigIntKeyword,
|
||||
SyntaxKind.BooleanKeyword,
|
||||
SyntaxKind.FalseKeyword,
|
||||
SyntaxKind.KeyOfKeyword,
|
||||
@@ -1277,11 +1282,11 @@ namespace ts {
|
||||
return !!compilerOptions.module || compilerOptions.target! >= ScriptTarget.ES2015 || !!compilerOptions.noEmit;
|
||||
}
|
||||
|
||||
export function hostUsesCaseSensitiveFileNames(host: LanguageServiceHost): boolean {
|
||||
export function hostUsesCaseSensitiveFileNames(host: { useCaseSensitiveFileNames?(): boolean; }): boolean {
|
||||
return host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : false;
|
||||
}
|
||||
|
||||
export function hostGetCanonicalFileName(host: LanguageServiceHost): GetCanonicalFileName {
|
||||
export function hostGetCanonicalFileName(host: { useCaseSensitiveFileNames?(): boolean; }): GetCanonicalFileName {
|
||||
return createGetCanonicalFileName(hostUsesCaseSensitiveFileNames(host));
|
||||
}
|
||||
|
||||
@@ -1628,9 +1633,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function isImportOrExportSpecifierName(location: Node): location is Identifier {
|
||||
return !!location.parent &&
|
||||
(location.parent.kind === SyntaxKind.ImportSpecifier || location.parent.kind === SyntaxKind.ExportSpecifier) &&
|
||||
(<ImportOrExportSpecifier>location.parent).propertyName === location;
|
||||
return !!location.parent && isImportOrExportSpecifier(location.parent) && location.parent.propertyName === location;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,7 +13,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
private testSuiteName: TestRunnerKind;
|
||||
private emit: boolean;
|
||||
|
||||
public options: string;
|
||||
public options: string | undefined;
|
||||
|
||||
constructor(public testType: CompilerTestType) {
|
||||
super();
|
||||
|
||||
@@ -21,6 +21,8 @@ class FourSlashRunner extends RunnerBase {
|
||||
this.basePath = "tests/cases/fourslash/server";
|
||||
this.testSuiteName = "fourslash-server";
|
||||
break;
|
||||
default:
|
||||
throw ts.Debug.assertNever(testType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,9 +28,9 @@ namespace Harness.Parallel.Host {
|
||||
let totalCost = 0;
|
||||
|
||||
class RemoteSuite extends Mocha.Suite {
|
||||
suites: RemoteSuite[];
|
||||
suites!: RemoteSuite[];
|
||||
suiteMap = ts.createMap<RemoteSuite>();
|
||||
tests: RemoteTest[];
|
||||
tests!: RemoteTest[];
|
||||
constructor(title: string) {
|
||||
super(title);
|
||||
this.pending = false;
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace project {
|
||||
|
||||
class ProjectCompilerHost extends fakes.CompilerHost {
|
||||
private _testCase: ProjectRunnerTestCase & ts.CompilerOptions;
|
||||
private _projectParseConfigHost: ProjectParseConfigHost;
|
||||
private _projectParseConfigHost: ProjectParseConfigHost | undefined;
|
||||
|
||||
constructor(sys: fakes.System | vfs.FileSystem, compilerOptions: ts.CompilerOptions, _testCaseJustName: string, testCase: ProjectRunnerTestCase & ts.CompilerOptions, _moduleKind: ts.ModuleKind) {
|
||||
super(sys, compilerOptions);
|
||||
|
||||
+143
-100
@@ -1,100 +1,143 @@
|
||||
{
|
||||
"extends": "../tsconfig-base",
|
||||
"compilerOptions": {
|
||||
"outFile": "../../built/local/run.js",
|
||||
"composite": false,
|
||||
"declaration": false,
|
||||
"declarationMap": false,
|
||||
"types": [
|
||||
"node", "mocha", "chai"
|
||||
],
|
||||
"lib": [
|
||||
"es6",
|
||||
"scripthost"
|
||||
]
|
||||
},
|
||||
"references": [
|
||||
{ "path": "../compiler", "prepend": true },
|
||||
{ "path": "../services", "prepend": true },
|
||||
{ "path": "../jsTyping", "prepend": true },
|
||||
{ "path": "../server", "prepend": true },
|
||||
{ "path": "../typingsInstallerCore", "prepend": true },
|
||||
{ "path": "../harness", "prepend": true }
|
||||
],
|
||||
|
||||
"files": [
|
||||
"fourslashRunner.ts",
|
||||
"compilerRunner.ts",
|
||||
"projectsRunner.ts",
|
||||
"rwcRunner.ts",
|
||||
"externalCompileRunner.ts",
|
||||
"test262Runner.ts",
|
||||
|
||||
"parallel/host.ts",
|
||||
"parallel/worker.ts",
|
||||
"parallel/shared.ts",
|
||||
|
||||
"runner.ts",
|
||||
|
||||
"unittests/extractTestHelpers.ts",
|
||||
"unittests/tsserverProjectSystem.ts",
|
||||
"unittests/typingsInstaller.ts",
|
||||
|
||||
"unittests/asserts.ts",
|
||||
"unittests/base64.ts",
|
||||
"unittests/builder.ts",
|
||||
"unittests/cancellableLanguageServiceOperations.ts",
|
||||
"unittests/commandLineParsing.ts",
|
||||
"unittests/comments.ts",
|
||||
"unittests/compileOnSave.ts",
|
||||
"unittests/compilerCore.ts",
|
||||
"unittests/configurationExtension.ts",
|
||||
"unittests/convertCompilerOptionsFromJson.ts",
|
||||
"unittests/convertToAsyncFunction.ts",
|
||||
"unittests/convertToBase64.ts",
|
||||
"unittests/convertTypeAcquisitionFromJson.ts",
|
||||
"unittests/customTransforms.ts",
|
||||
"unittests/extractConstants.ts",
|
||||
"unittests/extractFunctions.ts",
|
||||
"unittests/extractRanges.ts",
|
||||
"unittests/factory.ts",
|
||||
"unittests/hostNewLineSupport.ts",
|
||||
"unittests/incrementalParser.ts",
|
||||
"unittests/initializeTSConfig.ts",
|
||||
"unittests/jsDocParsing.ts",
|
||||
"unittests/languageService.ts",
|
||||
"unittests/matchFiles.ts",
|
||||
"unittests/moduleResolution.ts",
|
||||
"unittests/organizeImports.ts",
|
||||
"unittests/parsePseudoBigInt.ts",
|
||||
"unittests/paths.ts",
|
||||
"unittests/printer.ts",
|
||||
"unittests/programMissingFiles.ts",
|
||||
"unittests/programNoParseFalsyFileNames.ts",
|
||||
"unittests/projectErrors.ts",
|
||||
"unittests/projectReferences.ts",
|
||||
"unittests/publicApi.ts",
|
||||
"unittests/reuseProgramStructure.ts",
|
||||
"unittests/session.ts",
|
||||
"unittests/semver.ts",
|
||||
"unittests/showConfig.ts",
|
||||
"unittests/symbolWalker.ts",
|
||||
"unittests/telemetry.ts",
|
||||
"unittests/textChanges.ts",
|
||||
"unittests/textStorage.ts",
|
||||
"unittests/transform.ts",
|
||||
"unittests/transpile.ts",
|
||||
"unittests/tsbuild.ts",
|
||||
"unittests/tsbuildWatchMode.ts",
|
||||
"unittests/tsconfigParsing.ts",
|
||||
"unittests/tscWatchMode.ts",
|
||||
"unittests/versionCache.ts",
|
||||
"unittests/evaluation/asyncArrow.ts",
|
||||
"unittests/evaluation/asyncGenerator.ts",
|
||||
"unittests/evaluation/forAwaitOf.ts",
|
||||
"unittests/services/colorization.ts",
|
||||
"unittests/services/documentRegistry.ts",
|
||||
"unittests/services/patternMatcher.ts",
|
||||
"unittests/services/preProcessFile.ts"
|
||||
]
|
||||
}
|
||||
{
|
||||
"extends": "../tsconfig-base",
|
||||
"compilerOptions": {
|
||||
"outFile": "../../built/local/run.js",
|
||||
"composite": false,
|
||||
"declaration": false,
|
||||
"declarationMap": false,
|
||||
"types": [
|
||||
"node", "mocha", "chai"
|
||||
],
|
||||
"lib": [
|
||||
"es6",
|
||||
"scripthost"
|
||||
]
|
||||
},
|
||||
"references": [
|
||||
{ "path": "../compiler", "prepend": true },
|
||||
{ "path": "../services", "prepend": true },
|
||||
{ "path": "../jsTyping", "prepend": true },
|
||||
{ "path": "../server", "prepend": true },
|
||||
{ "path": "../typingsInstallerCore", "prepend": true },
|
||||
{ "path": "../harness", "prepend": true }
|
||||
],
|
||||
|
||||
"files": [
|
||||
"fourslashRunner.ts",
|
||||
"compilerRunner.ts",
|
||||
"projectsRunner.ts",
|
||||
"rwcRunner.ts",
|
||||
"externalCompileRunner.ts",
|
||||
"test262Runner.ts",
|
||||
|
||||
"parallel/host.ts",
|
||||
"parallel/worker.ts",
|
||||
"parallel/shared.ts",
|
||||
|
||||
"runner.ts",
|
||||
|
||||
"unittests/services/extract/helpers.ts",
|
||||
"unittests/tscWatch/helpers.ts",
|
||||
"unittests/tsserver/helpers.ts",
|
||||
|
||||
"unittests/asserts.ts",
|
||||
"unittests/base64.ts",
|
||||
"unittests/builder.ts",
|
||||
"unittests/compilerCore.ts",
|
||||
"unittests/convertToBase64.ts",
|
||||
"unittests/customTransforms.ts",
|
||||
"unittests/factory.ts",
|
||||
"unittests/incrementalParser.ts",
|
||||
"unittests/jsDocParsing.ts",
|
||||
"unittests/moduleResolution.ts",
|
||||
"unittests/parsePseudoBigInt.ts",
|
||||
"unittests/paths.ts",
|
||||
"unittests/printer.ts",
|
||||
"unittests/programApi.ts",
|
||||
"unittests/publicApi.ts",
|
||||
"unittests/reuseProgramStructure.ts",
|
||||
"unittests/semver.ts",
|
||||
"unittests/transform.ts",
|
||||
"unittests/tsbuild.ts",
|
||||
"unittests/tsbuildWatchMode.ts",
|
||||
"unittests/config/commandLineParsing.ts",
|
||||
"unittests/config/configurationExtension.ts",
|
||||
"unittests/config/convertCompilerOptionsFromJson.ts",
|
||||
"unittests/config/convertTypeAcquisitionFromJson.ts",
|
||||
"unittests/config/initializeTSConfig.ts",
|
||||
"unittests/config/matchFiles.ts",
|
||||
"unittests/config/projectReferences.ts",
|
||||
"unittests/config/showConfig.ts",
|
||||
"unittests/config/tsconfigParsing.ts",
|
||||
"unittests/evaluation/asyncArrow.ts",
|
||||
"unittests/evaluation/asyncGenerator.ts",
|
||||
"unittests/evaluation/forAwaitOf.ts",
|
||||
"unittests/services/cancellableLanguageServiceOperations.ts",
|
||||
"unittests/services/colorization.ts",
|
||||
"unittests/services/convertToAsyncFunction.ts",
|
||||
"unittests/services/documentRegistry.ts",
|
||||
"unittests/services/extract/constants.ts",
|
||||
"unittests/services/extract/functions.ts",
|
||||
"unittests/services/extract/symbolWalker.ts",
|
||||
"unittests/services/extract/ranges.ts",
|
||||
"unittests/services/hostNewLineSupport.ts",
|
||||
"unittests/services/languageService.ts",
|
||||
"unittests/services/organizeImports.ts",
|
||||
"unittests/services/patternMatcher.ts",
|
||||
"unittests/services/preProcessFile.ts",
|
||||
"unittests/services/textChanges.ts",
|
||||
"unittests/services/transpile.ts",
|
||||
"unittests/tscWatch/consoleClearing.ts",
|
||||
"unittests/tscWatch/emit.ts",
|
||||
"unittests/tscWatch/programUpdates.ts",
|
||||
"unittests/tscWatch/resolutionCache.ts",
|
||||
"unittests/tscWatch/watchEnvironment.ts",
|
||||
"unittests/tscWatch/watchApi.ts",
|
||||
"unittests/tsserver/cachingFileSystemInformation.ts",
|
||||
"unittests/tsserver/cancellationToken.ts",
|
||||
"unittests/tsserver/compileOnSave.ts",
|
||||
"unittests/tsserver/completions.ts",
|
||||
"unittests/tsserver/configFileSearch.ts",
|
||||
"unittests/tsserver/configuredProjects.ts",
|
||||
"unittests/tsserver/declarationFileMaps.ts",
|
||||
"unittests/tsserver/documentRegistry.ts",
|
||||
"unittests/tsserver/duplicatePackages.ts",
|
||||
"unittests/tsserver/events/largeFileReferenced.ts",
|
||||
"unittests/tsserver/events/projectLanguageServiceState.ts",
|
||||
"unittests/tsserver/events/projectLoading.ts",
|
||||
"unittests/tsserver/events/projectUpdatedInBackground.ts",
|
||||
"unittests/tsserver/events/surveyReady.ts",
|
||||
"unittests/tsserver/externalProjects.ts",
|
||||
"unittests/tsserver/forceConsistentCasingInFileNames.ts",
|
||||
"unittests/tsserver/formatSettings.ts",
|
||||
"unittests/tsserver/getApplicableRefactors.ts",
|
||||
"unittests/tsserver/getEditsForFileRename.ts",
|
||||
"unittests/tsserver/importHelpers.ts",
|
||||
"unittests/tsserver/inferredProjects.ts",
|
||||
"unittests/tsserver/languageService.ts",
|
||||
"unittests/tsserver/maxNodeModuleJsDepth.ts",
|
||||
"unittests/tsserver/metadataInResponse.ts",
|
||||
"unittests/tsserver/navTo.ts",
|
||||
"unittests/tsserver/occurences.ts",
|
||||
"unittests/tsserver/openFile.ts",
|
||||
"unittests/tsserver/projectErrors.ts",
|
||||
"unittests/tsserver/projectReferences.ts",
|
||||
"unittests/tsserver/projects.ts",
|
||||
"unittests/tsserver/refactors.ts",
|
||||
"unittests/tsserver/reload.ts",
|
||||
"unittests/tsserver/rename.ts",
|
||||
"unittests/tsserver/resolutionCache.ts",
|
||||
"unittests/tsserver/session.ts",
|
||||
"unittests/tsserver/skipLibCheck.ts",
|
||||
"unittests/tsserver/symLinks.ts",
|
||||
"unittests/tsserver/syntaxOperations.ts",
|
||||
"unittests/tsserver/textStorage.ts",
|
||||
"unittests/tsserver/telemetry.ts",
|
||||
"unittests/tsserver/typeAquisition.ts",
|
||||
"unittests/tsserver/typeReferenceDirectives.ts",
|
||||
"unittests/tsserver/typingsInstaller.ts",
|
||||
"unittests/tsserver/untitledFiles.ts",
|
||||
"unittests/tsserver/versionCache.ts",
|
||||
"unittests/tsserver/watchEnvironment.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
namespace ts {
|
||||
describe("assert", () => {
|
||||
describe("unittests:: assert", () => {
|
||||
it("deepEqual", () => {
|
||||
assert.throws(() => assert.deepEqual(createNodeArray([createIdentifier("A")]), createNodeArray([createIdentifier("B")])));
|
||||
assert.throws(() => assert.deepEqual(createNodeArray([], /*hasTrailingComma*/ true), createNodeArray([], /*hasTrailingComma*/ false)));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
namespace ts {
|
||||
describe("base64", () => {
|
||||
describe("unittests:: base64", () => {
|
||||
describe("base64decode", () => {
|
||||
it("can decode input strings correctly without needing a host implementation", () => {
|
||||
const tests = [
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
namespace ts {
|
||||
describe("builder", () => {
|
||||
describe("unittests:: builder", () => {
|
||||
it("emits dependent files", () => {
|
||||
const files: NamedSourceText[] = [
|
||||
{ name: "/a.ts", text: SourceText.New("", 'import { b } from "./b";', "") },
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
namespace ts {
|
||||
describe("compilerCore", () => {
|
||||
describe("unittests:: compilerCore", () => {
|
||||
describe("equalOwnProperties", () => {
|
||||
it("correctly equates objects", () => {
|
||||
assert.isTrue(equalOwnProperties({}, {}));
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
namespace ts {
|
||||
describe("parseCommandLine", () => {
|
||||
describe("unittests:: config:: commandLineParsing:: parseCommandLine", () => {
|
||||
|
||||
function assertParseResult(commandLine: string[], expectedParsedCommandLine: ParsedCommandLine) {
|
||||
const parsed = parseCommandLine(commandLine);
|
||||
@@ -367,7 +367,7 @@ namespace ts {
|
||||
});
|
||||
});
|
||||
|
||||
describe("parseBuildOptions", () => {
|
||||
describe("unittests:: config:: commandLineParsing:: parseBuildOptions", () => {
|
||||
function assertParseResult(commandLine: string[], expectedParsedBuildCommand: ParsedBuildCommand) {
|
||||
const parsed = parseBuildCommand(commandLine);
|
||||
const parsedBuildOptions = JSON.stringify(parsed.buildOptions);
|
||||
+1
-1
@@ -208,7 +208,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
describe("configurationExtension", () => {
|
||||
describe("unittests:: config:: configurationExtension", () => {
|
||||
forEach<[string, string, fakes.ParseConfigHost], void>([
|
||||
["under a case insensitive host", caseInsensitiveBasePath, caseInsensitiveHost],
|
||||
["under a case sensitive host", caseSensitiveBasePath, caseSensitiveHost]
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
namespace ts {
|
||||
describe("convertCompilerOptionsFromJson", () => {
|
||||
describe("unittests:: config:: convertCompilerOptionsFromJson", () => {
|
||||
const formatDiagnosticHost: FormatDiagnosticsHost = {
|
||||
getCurrentDirectory: () => "/apath/",
|
||||
getCanonicalFileName: createGetCanonicalFileName(/*useCaseSensitiveFileNames*/ true),
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
namespace ts {
|
||||
interface ExpectedResult { typeAcquisition: TypeAcquisition; errors: Diagnostic[]; }
|
||||
describe("convertTypeAcquisitionFromJson", () => {
|
||||
describe("unittests:: config:: convertTypeAcquisitionFromJson", () => {
|
||||
function assertTypeAcquisition(json: any, configFileName: string, expectedResult: ExpectedResult) {
|
||||
assertTypeAcquisitionWithJson(json, configFileName, expectedResult);
|
||||
assertTypeAcquisitionWithJsonNode(json, configFileName, expectedResult);
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
namespace ts {
|
||||
describe("initTSConfig", () => {
|
||||
describe("unittests:: config:: initTSConfig", () => {
|
||||
function initTSConfigCorrectly(name: string, commandLinesArgs: string[]) {
|
||||
describe(name, () => {
|
||||
const commandLine = parseCommandLine(commandLinesArgs);
|
||||
@@ -30,4 +30,4 @@ namespace ts {
|
||||
|
||||
initTSConfigCorrectly("Initialized TSConfig with advanced options", ["--init", "--declaration", "--declarationDir", "lib", "--skipLibCheck", "--noErrorTruncation"]);
|
||||
});
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -143,7 +143,7 @@ namespace ts {
|
||||
return createFileDiagnostic(file, start, length, diagnosticMessage, arg0);
|
||||
}
|
||||
|
||||
describe("matchFiles", () => {
|
||||
describe("unittests:: config:: matchFiles", () => {
|
||||
it("with defaults", () => {
|
||||
const json = {};
|
||||
const expected: ParsedCommandLine = {
|
||||
+6
-6
@@ -96,7 +96,7 @@ namespace ts {
|
||||
checkResult(prog, host);
|
||||
}
|
||||
|
||||
describe("project-references meta check", () => {
|
||||
describe("unittests:: config:: project-references meta check", () => {
|
||||
it("default setup was created correctly", () => {
|
||||
const spec: TestSpecification = {
|
||||
"/primary": {
|
||||
@@ -118,7 +118,7 @@ namespace ts {
|
||||
/**
|
||||
* Validate that we enforce the basic settings constraints for referenced projects
|
||||
*/
|
||||
describe("project-references constraint checking for settings", () => {
|
||||
describe("unittests:: config:: project-references constraint checking for settings", () => {
|
||||
it("errors when declaration = false", () => {
|
||||
const spec: TestSpecification = {
|
||||
"/primary": {
|
||||
@@ -248,7 +248,7 @@ namespace ts {
|
||||
/**
|
||||
* Path mapping behavior
|
||||
*/
|
||||
describe("project-references path mapping", () => {
|
||||
describe("unittests:: config:: project-references path mapping", () => {
|
||||
it("redirects to the output .d.ts file", () => {
|
||||
const spec: TestSpecification = {
|
||||
"/alpha": {
|
||||
@@ -268,7 +268,7 @@ namespace ts {
|
||||
});
|
||||
});
|
||||
|
||||
describe("project-references nice-behavior", () => {
|
||||
describe("unittests:: config:: project-references nice-behavior", () => {
|
||||
it("issues a nice error when the input file is missing", () => {
|
||||
const spec: TestSpecification = {
|
||||
"/alpha": {
|
||||
@@ -289,7 +289,7 @@ namespace ts {
|
||||
/**
|
||||
* 'composite' behavior
|
||||
*/
|
||||
describe("project-references behavior changes under composite: true", () => {
|
||||
describe("unittests:: config:: project-references behavior changes under composite: true", () => {
|
||||
it("doesn't infer the rootDir from source paths", () => {
|
||||
const spec: TestSpecification = {
|
||||
"/alpha": {
|
||||
@@ -308,7 +308,7 @@ namespace ts {
|
||||
});
|
||||
});
|
||||
|
||||
describe("errors when a file in a composite project occurs outside the root", () => {
|
||||
describe("unittests:: config:: project-references errors when a file in a composite project occurs outside the root", () => {
|
||||
it("Errors when a file is outside the rootdir", () => {
|
||||
const spec: TestSpecification = {
|
||||
"/alpha": {
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user