mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into strictParameter
This commit is contained in:
+3
-1
@@ -74,4 +74,6 @@ tests/cases/user/*/**/*.d.ts
|
||||
!tests/cases/user/bignumber.js/
|
||||
!tests/cases/user/discord.js/
|
||||
tests/baselines/reference/dt
|
||||
.failed-tests
|
||||
.failed-tests
|
||||
TEST-results.xml
|
||||
package-lock.json
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
[](https://gitter.im/Microsoft/TypeScript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
[TypeScript](https://www.typescriptlang.org/) is a language for application-scale JavaScript. TypeScript adds optional types, classes, and modules to JavaScript. TypeScript supports tools for large-scale JavaScript applications for any browser, for any host, on any OS. TypeScript compiles to readable, standards-based JavaScript. Try it out at the [playground](https://www.typescriptlang.org/play/), and stay up to date via [our blog](https://blogs.msdn.microsoft.com/typescript) and [Twitter account](https://twitter.com/typescriptlang).
|
||||
[TypeScript](https://www.typescriptlang.org/) is a language for application-scale JavaScript. TypeScript adds optional types to JavaScript that support tools for large-scale JavaScript applications for any browser, for any host, on any OS. TypeScript compiles to readable, standards-based JavaScript. Try it out at the [playground](https://www.typescriptlang.org/play/), and stay up to date via [our blog](https://blogs.msdn.microsoft.com/typescript) and [Twitter account](https://twitter.com/typescriptlang).
|
||||
|
||||
## Installing
|
||||
|
||||
|
||||
@@ -164,5 +164,30 @@ For purposes of this definition, the normative portions of the Specification sha
|
||||
I am encouraged to provide a contact from which licensing information can be obtained and other relevant licensing information. Any such information will be made publicly available.
|
||||
10.8. You or Your. “You,” “you,” or “your” means any person or entity who exercises copyright or patent rights granted under this Agreement, and any person that person or entity controls.
|
||||
|
||||
-------------------------------------------------------------------------------------
|
||||
|
||||
------------------- WebGL -----------------------------
|
||||
Copyright (c) 2018 The Khronos Group Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and/or associated documentation files (the
|
||||
"Materials"), to deal in the Materials without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
permit persons to whom the Materials are furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Materials.
|
||||
|
||||
THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
------------------------------------------------------
|
||||
|
||||
------------- End of ThirdPartyNotices ------------------------------------------- */
|
||||
|
||||
|
||||
@@ -49,8 +49,8 @@
|
||||
"A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged_2434": "Eine Namespacedeklaration darf nicht vor der Klasse oder Funktion positioniert werden, mit der sie zusammengeführt wird.",
|
||||
"A_namespace_declaration_is_only_allowed_in_a_namespace_or_module_1235": "Eine Namespacedeklaration ist nur in einem Namespace oder Modul zulässig.",
|
||||
"A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_7038": "Ein Import im Namespacestil kann nicht aufgerufen oder erstellt werden und verursacht zur Laufzeit einen Fehler.",
|
||||
"A_non_dry_build_would_build_project_0_6357": "Bei einem Build mit dem Flag \"-dry\" würde das Projekt \"{0}\" erstellt.",
|
||||
"A_non_dry_build_would_delete_the_following_files_Colon_0_6356": "Bei einem Build mit dem Flag \"-dry\" würden die folgenden Dateien gelöscht: {0}",
|
||||
"A_non_dry_build_would_build_project_0_6357": "Bei einem Build ohne das Flag \"-dry\" würde das Projekt \"{0}\" erstellt.",
|
||||
"A_non_dry_build_would_delete_the_following_files_Colon_0_6356": "Bei einem Build ohne das Flag \"-dry\" würden die folgenden Dateien gelöscht: {0}",
|
||||
"A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation_2371": "Ein Parameterinitialisierer ist nur in einer Funktions- oder Konstruktorimplementierung zulässig.",
|
||||
"A_parameter_property_cannot_be_declared_using_a_rest_parameter_1317": "Eine Parametereigenschaft darf nicht mithilfe eines rest-Parameters deklariert werden.",
|
||||
"A_parameter_property_is_only_allowed_in_a_constructor_implementation_2369": "Eine Parametereigenschaft ist nur in einer Konstruktorimplementierung zulässig.",
|
||||
|
||||
@@ -267,6 +267,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_label_is_not_allowed_here_1344" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['A label is not allowed here.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_memb_2651" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums.]]></Val>
|
||||
@@ -645,6 +651,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Add_default_import_0_to_existing_import_declaration_from_1_90033" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add default import '{0}' to existing import declaration from "{1}"]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Add_definite_assignment_assertion_to_property_0_95020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add definite assignment assertion to property '{0}']]></Val>
|
||||
@@ -777,6 +789,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";All_type_parameters_are_unused_6205" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[All type parameters are unused]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";All_variables_are_unused_6199" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[All variables are unused.]]></Val>
|
||||
@@ -849,6 +867,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";An_arrow_function_cannot_have_a_this_parameter_2730" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[An arrow function cannot have a 'this' parameter.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_de_2705" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option.]]></Val>
|
||||
@@ -921,6 +945,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";An_expression_of_type_void_cannot_be_tested_for_truthiness_1345" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[An expression of type 'void' cannot be tested for truthiness]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive_1198" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[An extended Unicode escape value must be between 0x0 and 0x10FFFF inclusive.]]></Val>
|
||||
@@ -1341,6 +1371,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension_2732" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Cannot find module '{0}'. Consider using '--resolveJsonModule' to import module with '.json' extension]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Cannot_find_name_0_2304" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Cannot find name '{0}'.]]></Val>
|
||||
@@ -1749,6 +1785,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Conversion_of_type_0_to_type_1_may_be_a_mistake_because_neither_type_sufficiently_overlaps_with_the__2352" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Conversion of type '{0}' to type '{1}' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Convert_0_to_mapped_object_type_95055" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Convert '{0}' to mapped object type]]></Val>
|
||||
@@ -1767,6 +1809,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Convert_all_to_async_functions_95066" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Convert all to async functions]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Convert_all_to_default_imports_95035" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Convert all to default imports]]></Val>
|
||||
@@ -1821,6 +1869,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Convert_to_async_function_95065" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Convert to async function]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Convert_to_default_import_95013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Convert to default import]]></Val>
|
||||
@@ -2855,7 +2909,7 @@
|
||||
</Item>
|
||||
<Item ItemId=";If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_S_7040" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[If the '{0}' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/{0}`]]></Val>
|
||||
<Val><![CDATA[If the '{0}' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/{1}`]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -2895,6 +2949,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Implicit_conversion_of_a_symbol_to_a_string_will_fail_at_runtime_Consider_wrapping_this_expression_i_2731" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Implicit conversion of a 'symbol' to a 'string' will fail at runtime. Consider wrapping this expression in 'String(...)'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_module_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import '{0}' from module "{1}"]]></Val>
|
||||
@@ -2925,6 +2985,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Import_default_0_from_module_1_90032" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import default '{0}' from module "{1}"]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Import_emit_helpers_from_tslib_6139" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import emit helpers from 'tslib'.]]></Val>
|
||||
@@ -3531,6 +3597,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Module_0_was_resolved_to_1_but_resolveJsonModule_is_not_used_7042" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Module '{0}' was resolved to '{1}', but '--resolveJsonModule' is not used.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Module_Resolution_Options_6174" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Module Resolution Options]]></Val>
|
||||
@@ -3615,6 +3687,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";No_overload_expects_0_arguments_but_overloads_do_exist_that_expect_either_1_or_2_arguments_2575" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[No overload expects {0} arguments, but overloads do exist that expect either {1} or {2} arguments.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2_2515" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Non-abstract class '{0}' does not implement inherited abstract member '{1}' from class '{2}'.]]></Val>
|
||||
@@ -3831,6 +3909,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs_5071" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy_5070" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy.]]></Val>
|
||||
@@ -4245,6 +4329,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Property_0_is_a_static_member_of_type_1_2576" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Property '{0}' is a static member of type '{1}']]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Property_0_is_declared_but_its_value_is_never_read_6138" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Property '{0}' is declared but its value is never read.]]></Val>
|
||||
@@ -4521,6 +4611,18 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Remove_template_tag_90011" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove template tag]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Remove_type_parameters_90012" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove type parameters]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Remove_unreachable_code_95050" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remove unreachable code]]></Val>
|
||||
@@ -4539,12 +4641,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Replace_all_unused_infer_with_unknown_90031" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Replace all unused 'infer' with 'unknown']]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Replace_import_with_0_95015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Replace import with '{0}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Replace_infer_0_with_unknown_90030" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Replace 'infer {0}' with 'unknown']]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Report_error_when_not_all_code_paths_in_function_return_a_value_6075" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Report error when not all code paths in function return a value.]]></Val>
|
||||
@@ -4671,6 +4785,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Return_type_annotation_circularly_references_itself_2577" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Return type annotation circularly references itself.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4046" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Return type of call signature from exported interface has or is using name '{0}' from private module '{1}'.]]></Val>
|
||||
@@ -5169,6 +5289,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";The_containing_arrow_function_captures_the_global_value_of_this_which_implicitly_has_type_any_7041" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[The containing arrow function captures the global value of 'this' which implicitly has type 'any'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";The_containing_function_or_module_body_is_too_large_for_control_flow_analysis_2563" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[The containing function or module body is too large for control flow analysis.]]></Val>
|
||||
@@ -5409,6 +5535,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";The_type_of_a_function_declaration_must_match_the_function_s_signature_8030" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[The type of a function declaration must match the function's signature.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";The_type_returned_by_the_next_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value__2547" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[The type returned by the 'next()' method of an async iterator must be a promise for a type with a 'value' property.]]></Val>
|
||||
@@ -5451,6 +5583,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_may_be_converted_to_an_async_function_80006" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This may be converted to an async function.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found_2354" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This syntax requires an imported helper but module '{0}' cannot be found.]]></Val>
|
||||
@@ -5475,9 +5613,9 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Try_npm_install_types_Slash_0_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_mod_7035" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Try_npm_install_types_Slash_1_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_mod_7035" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Try `npm install @types/{0}` if it exists or add a new declaration (.d.ts) file containing `declare module '{0}';`]]></Val>
|
||||
<Val><![CDATA[Try `npm install @types/{1}` if it exists or add a new declaration (.d.ts) file containing `declare module '{0}';`]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -5499,12 +5637,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_cannot_be_converted_to_type_1_2352" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' cannot be converted to type '{1}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_cannot_be_used_as_an_index_type_2538" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' cannot be used as an index type.]]></Val>
|
||||
@@ -6141,6 +6273,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_is_declared_here_2728" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' is declared here.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?]]></Val>
|
||||
@@ -6279,12 +6417,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_was_declared_here_2728" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' was declared here.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type_7010" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}', which lacks return-type annotation, implicitly has an '{1}' return type.]]></Val>
|
||||
|
||||
Vendored
+3078
-2611
File diff suppressed because it is too large
Load Diff
Vendored
+32
-4
@@ -51,10 +51,13 @@ interface DOMStringList {
|
||||
|
||||
interface DOMTokenList {
|
||||
[Symbol.iterator](): IterableIterator<string>;
|
||||
entries(): IterableIterator<[number, string]>;
|
||||
keys(): IterableIterator<number>;
|
||||
values(): IterableIterator<string>;
|
||||
}
|
||||
|
||||
interface DataTransferItemList {
|
||||
[Symbol.iterator](): IterableIterator<File>;
|
||||
[Symbol.iterator](): IterableIterator<DataTransferItem>;
|
||||
}
|
||||
|
||||
interface FileList {
|
||||
@@ -87,9 +90,10 @@ interface HTMLCollectionBase {
|
||||
|
||||
interface HTMLCollectionOf<T extends Element> {
|
||||
[Symbol.iterator](): IterableIterator<T>;
|
||||
entries(): IterableIterator<[number, T]>;
|
||||
keys(): IterableIterator<number>;
|
||||
values(): IterableIterator<T>;
|
||||
}
|
||||
|
||||
interface HTMLFormElement {
|
||||
[Symbol.iterator](): IterableIterator<Element>;
|
||||
}
|
||||
|
||||
interface HTMLSelectElement {
|
||||
@@ -167,10 +171,34 @@ interface PluginArray {
|
||||
interface RTCStatsReport extends ReadonlyMap<string, any> {
|
||||
}
|
||||
|
||||
interface SVGLengthList {
|
||||
[Symbol.iterator](): IterableIterator<SVGLength>;
|
||||
}
|
||||
|
||||
interface SVGNumberList {
|
||||
[Symbol.iterator](): IterableIterator<SVGNumber>;
|
||||
}
|
||||
|
||||
interface SVGStringList {
|
||||
[Symbol.iterator](): IterableIterator<string>;
|
||||
}
|
||||
|
||||
interface SourceBufferList {
|
||||
[Symbol.iterator](): IterableIterator<SourceBuffer>;
|
||||
}
|
||||
|
||||
interface SpeechGrammarList {
|
||||
[Symbol.iterator](): IterableIterator<SpeechGrammar>;
|
||||
}
|
||||
|
||||
interface SpeechRecognitionResult {
|
||||
[Symbol.iterator](): IterableIterator<SpeechRecognitionAlternative>;
|
||||
}
|
||||
|
||||
interface SpeechRecognitionResultList {
|
||||
[Symbol.iterator](): IterableIterator<SpeechRecognitionResult>;
|
||||
}
|
||||
|
||||
interface StyleSheetList {
|
||||
[Symbol.iterator](): IterableIterator<StyleSheet>;
|
||||
}
|
||||
|
||||
Vendored
+4
-4
@@ -1145,15 +1145,15 @@ interface Array<T> {
|
||||
* Returns a string representation of an array. The elements are converted to string using their toLocalString methods.
|
||||
*/
|
||||
toLocaleString(): string;
|
||||
/**
|
||||
* Removes the last element from an array and returns it.
|
||||
*/
|
||||
pop(): T | undefined;
|
||||
/**
|
||||
* Appends new elements to an array, and returns the new length of the array.
|
||||
* @param items New elements of the Array.
|
||||
*/
|
||||
push(...items: T[]): number;
|
||||
/**
|
||||
* Removes the last element from an array and returns it.
|
||||
*/
|
||||
pop(): T | undefined;
|
||||
/**
|
||||
* Combines two or more arrays.
|
||||
* @param items Additional items to add to the end of array1.
|
||||
|
||||
Vendored
+467
-81
@@ -27,6 +27,33 @@ interface AddEventListenerOptions extends EventListenerOptions {
|
||||
passive?: boolean;
|
||||
}
|
||||
|
||||
interface AesCbcParams extends Algorithm {
|
||||
iv: Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | DataView | ArrayBuffer;
|
||||
}
|
||||
|
||||
interface AesCtrParams extends Algorithm {
|
||||
counter: Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | DataView | ArrayBuffer;
|
||||
length: number;
|
||||
}
|
||||
|
||||
interface AesDerivedKeyParams extends Algorithm {
|
||||
length: number;
|
||||
}
|
||||
|
||||
interface AesGcmParams extends Algorithm {
|
||||
additionalData?: Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | DataView | ArrayBuffer;
|
||||
iv: Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | DataView | ArrayBuffer;
|
||||
tagLength?: number;
|
||||
}
|
||||
|
||||
interface AesKeyAlgorithm extends KeyAlgorithm {
|
||||
length: number;
|
||||
}
|
||||
|
||||
interface AesKeyGenParams extends Algorithm {
|
||||
length: number;
|
||||
}
|
||||
|
||||
interface Algorithm {
|
||||
name: string;
|
||||
}
|
||||
@@ -53,6 +80,15 @@ interface CloseEventInit extends EventInit {
|
||||
wasClean?: boolean;
|
||||
}
|
||||
|
||||
interface CryptoKeyPair {
|
||||
privateKey?: CryptoKey;
|
||||
publicKey?: CryptoKey;
|
||||
}
|
||||
|
||||
interface CustomEventInit<T = any> extends EventInit {
|
||||
detail?: T;
|
||||
}
|
||||
|
||||
interface DOMMatrix2DInit {
|
||||
a?: number;
|
||||
b?: number;
|
||||
@@ -103,6 +139,22 @@ interface DOMRectInit {
|
||||
y?: number;
|
||||
}
|
||||
|
||||
interface EcKeyGenParams extends Algorithm {
|
||||
namedCurve: NamedCurve;
|
||||
}
|
||||
|
||||
interface EcKeyImportParams extends Algorithm {
|
||||
namedCurve: NamedCurve;
|
||||
}
|
||||
|
||||
interface EcdhKeyDeriveParams extends Algorithm {
|
||||
public: CryptoKey;
|
||||
}
|
||||
|
||||
interface EcdsaParams extends Algorithm {
|
||||
hash: HashAlgorithmIdentifier;
|
||||
}
|
||||
|
||||
interface ErrorEventInit extends EventInit {
|
||||
colno?: number;
|
||||
error?: any;
|
||||
@@ -129,12 +181,12 @@ interface ExtendableMessageEventInit extends ExtendableEventInit {
|
||||
lastEventId?: string;
|
||||
origin?: string;
|
||||
ports?: MessagePort[];
|
||||
source?: Client | ServiceWorker | MessagePort;
|
||||
source?: Client | ServiceWorker | MessagePort | null;
|
||||
}
|
||||
|
||||
interface FetchEventInit extends ExtendableEventInit {
|
||||
clientId?: string;
|
||||
preloadResponse: Promise<any>;
|
||||
preloadResponse?: Promise<any>;
|
||||
request: Request;
|
||||
resultingClientId?: string;
|
||||
targetClientId?: string;
|
||||
@@ -148,6 +200,16 @@ interface GetNotificationOptions {
|
||||
tag?: string;
|
||||
}
|
||||
|
||||
interface HmacImportParams extends Algorithm {
|
||||
hash: HashAlgorithmIdentifier;
|
||||
length?: number;
|
||||
}
|
||||
|
||||
interface HmacKeyGenParams extends Algorithm {
|
||||
hash: HashAlgorithmIdentifier;
|
||||
length?: number;
|
||||
}
|
||||
|
||||
interface IDBIndexParameters {
|
||||
multiEntry?: boolean;
|
||||
unique?: boolean;
|
||||
@@ -155,7 +217,7 @@ interface IDBIndexParameters {
|
||||
|
||||
interface IDBObjectStoreParameters {
|
||||
autoIncrement?: boolean;
|
||||
keyPath?: string | string[];
|
||||
keyPath?: string | string[] | null;
|
||||
}
|
||||
|
||||
interface IDBVersionChangeEventInit extends EventInit {
|
||||
@@ -163,17 +225,37 @@ interface IDBVersionChangeEventInit extends EventInit {
|
||||
oldVersion?: number;
|
||||
}
|
||||
|
||||
interface JsonWebKey {
|
||||
alg?: string;
|
||||
crv?: string;
|
||||
d?: string;
|
||||
dp?: string;
|
||||
dq?: string;
|
||||
e?: string;
|
||||
ext?: boolean;
|
||||
k?: string;
|
||||
key_ops?: string[];
|
||||
kty?: string;
|
||||
n?: string;
|
||||
oth?: RsaOtherPrimesInfo[];
|
||||
p?: string;
|
||||
q?: string;
|
||||
qi?: string;
|
||||
use?: string;
|
||||
x?: string;
|
||||
y?: string;
|
||||
}
|
||||
|
||||
interface KeyAlgorithm {
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface MessageEventInit extends EventInit {
|
||||
channel?: string;
|
||||
data?: any;
|
||||
lastEventId?: string;
|
||||
origin?: string;
|
||||
ports?: MessagePort[];
|
||||
source?: object | null;
|
||||
source?: MessageEventSource | null;
|
||||
}
|
||||
|
||||
interface NavigationPreloadState {
|
||||
@@ -209,6 +291,12 @@ interface NotificationOptions {
|
||||
vibrate?: VibratePattern;
|
||||
}
|
||||
|
||||
interface Pbkdf2Params extends Algorithm {
|
||||
hash: HashAlgorithmIdentifier;
|
||||
iterations: number;
|
||||
salt: Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | DataView | ArrayBuffer;
|
||||
}
|
||||
|
||||
interface PerformanceObserverInit {
|
||||
buffered?: boolean;
|
||||
entryTypes: string[];
|
||||
@@ -241,7 +329,7 @@ interface PushSubscriptionJSON {
|
||||
}
|
||||
|
||||
interface PushSubscriptionOptionsInit {
|
||||
applicationServerKey?: BufferSource | string;
|
||||
applicationServerKey?: BufferSource | string | null;
|
||||
userVisibleOnly?: boolean;
|
||||
}
|
||||
|
||||
@@ -263,7 +351,7 @@ interface RequestInit {
|
||||
redirect?: RequestRedirect;
|
||||
referrer?: string;
|
||||
referrerPolicy?: ReferrerPolicy;
|
||||
signal?: object | null;
|
||||
signal?: AbortSignal | null;
|
||||
window?: any;
|
||||
}
|
||||
|
||||
@@ -273,6 +361,33 @@ interface ResponseInit {
|
||||
statusText?: string;
|
||||
}
|
||||
|
||||
interface RsaHashedImportParams extends Algorithm {
|
||||
hash: HashAlgorithmIdentifier;
|
||||
}
|
||||
|
||||
interface RsaHashedKeyGenParams extends RsaKeyGenParams {
|
||||
hash: HashAlgorithmIdentifier;
|
||||
}
|
||||
|
||||
interface RsaKeyGenParams extends Algorithm {
|
||||
modulusLength: number;
|
||||
publicExponent: BigInteger;
|
||||
}
|
||||
|
||||
interface RsaOaepParams extends Algorithm {
|
||||
label?: Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | DataView | ArrayBuffer;
|
||||
}
|
||||
|
||||
interface RsaOtherPrimesInfo {
|
||||
d?: string;
|
||||
r?: string;
|
||||
t?: string;
|
||||
}
|
||||
|
||||
interface RsaPssParams extends Algorithm {
|
||||
saltLength: number;
|
||||
}
|
||||
|
||||
interface StorageEstimate {
|
||||
quota?: number;
|
||||
usage?: number;
|
||||
@@ -296,6 +411,45 @@ interface EventListener {
|
||||
(evt: Event): void;
|
||||
}
|
||||
|
||||
interface AbortController {
|
||||
/**
|
||||
* Returns the AbortSignal object associated with this object.
|
||||
*/
|
||||
readonly signal: AbortSignal;
|
||||
/**
|
||||
* Invoking this method will set this object's AbortSignal's aborted flag and
|
||||
* signal to any observers that the associated activity is to be aborted.
|
||||
*/
|
||||
abort(): void;
|
||||
}
|
||||
|
||||
declare var AbortController: {
|
||||
prototype: AbortController;
|
||||
new(): AbortController;
|
||||
};
|
||||
|
||||
interface AbortSignalEventMap {
|
||||
"abort": ProgressEvent;
|
||||
}
|
||||
|
||||
interface AbortSignal extends EventTarget {
|
||||
/**
|
||||
* Returns true if this AbortSignal's AbortController has signaled to abort, and false
|
||||
* otherwise.
|
||||
*/
|
||||
readonly aborted: boolean;
|
||||
onabort: ((this: AbortSignal, ev: ProgressEvent) => any) | null;
|
||||
addEventListener<K extends keyof AbortSignalEventMap>(type: K, listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof AbortSignalEventMap>(type: K, listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var AbortSignal: {
|
||||
prototype: AbortSignal;
|
||||
new(): AbortSignal;
|
||||
};
|
||||
|
||||
interface AbstractWorkerEventMap {
|
||||
"error": ErrorEvent;
|
||||
}
|
||||
@@ -401,11 +555,52 @@ declare var CacheStorage: {
|
||||
new(): CacheStorage;
|
||||
};
|
||||
|
||||
interface CanvasGradient {
|
||||
/**
|
||||
* Adds a color stop with the given color to the gradient at the given offset. 0.0 is the offset
|
||||
* at one end of the gradient, 1.0 is the offset at the other end.
|
||||
* Throws an "IndexSizeError" DOMException if the offset
|
||||
* is out of range. Throws a "SyntaxError" DOMException if
|
||||
* the color cannot be parsed.
|
||||
*/
|
||||
addColorStop(offset: number, color: string): void;
|
||||
}
|
||||
|
||||
declare var CanvasGradient: {
|
||||
prototype: CanvasGradient;
|
||||
new(): CanvasGradient;
|
||||
};
|
||||
|
||||
interface CanvasPath {
|
||||
arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean): void;
|
||||
arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void;
|
||||
bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void;
|
||||
closePath(): void;
|
||||
ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, anticlockwise?: boolean): void;
|
||||
lineTo(x: number, y: number): void;
|
||||
moveTo(x: number, y: number): void;
|
||||
quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void;
|
||||
rect(x: number, y: number, w: number, h: number): void;
|
||||
}
|
||||
|
||||
interface CanvasPattern {
|
||||
/**
|
||||
* Sets the transformation matrix that will be used when rendering the pattern during a fill or
|
||||
* stroke painting operation.
|
||||
*/
|
||||
setTransform(transform?: DOMMatrix2DInit): void;
|
||||
}
|
||||
|
||||
declare var CanvasPattern: {
|
||||
prototype: CanvasPattern;
|
||||
new(): CanvasPattern;
|
||||
};
|
||||
|
||||
interface Client {
|
||||
readonly id: string;
|
||||
readonly type: ClientTypes;
|
||||
readonly url: string;
|
||||
postMessage(message: any, transfer?: any[]): void;
|
||||
postMessage(message: any, transfer?: Transferable[]): void;
|
||||
}
|
||||
|
||||
declare var Client: {
|
||||
@@ -463,10 +658,8 @@ interface Console {
|
||||
info(message?: any, ...optionalParams: any[]): void;
|
||||
log(message?: any, ...optionalParams: any[]): void;
|
||||
markTimeline(label?: string): void;
|
||||
msIsIndependentlyComposed(element: object): boolean;
|
||||
profile(reportName?: string): void;
|
||||
profileEnd(): void;
|
||||
select(element: object): void;
|
||||
profileEnd(reportName?: string): void;
|
||||
table(...tabularData: any[]): void;
|
||||
time(label?: string): void;
|
||||
timeEnd(label?: string): void;
|
||||
@@ -482,11 +675,21 @@ declare var Console: {
|
||||
new(): Console;
|
||||
};
|
||||
|
||||
interface Crypto {
|
||||
readonly subtle: SubtleCrypto;
|
||||
getRandomValues<T extends Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | DataView | null>(array: T): T;
|
||||
}
|
||||
|
||||
declare var Crypto: {
|
||||
prototype: Crypto;
|
||||
new(): Crypto;
|
||||
};
|
||||
|
||||
interface CryptoKey {
|
||||
readonly algorithm: KeyAlgorithm;
|
||||
readonly extractable: boolean;
|
||||
readonly type: string;
|
||||
readonly usages: string[];
|
||||
readonly type: KeyType;
|
||||
readonly usages: KeyUsage[];
|
||||
}
|
||||
|
||||
declare var CryptoKey: {
|
||||
@@ -494,6 +697,20 @@ declare var CryptoKey: {
|
||||
new(): CryptoKey;
|
||||
};
|
||||
|
||||
interface CustomEvent<T = any> extends Event {
|
||||
/**
|
||||
* Returns any custom data event was created with.
|
||||
* Typically used for synthetic events.
|
||||
*/
|
||||
readonly detail: T;
|
||||
initCustomEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, detailArg: T): void;
|
||||
}
|
||||
|
||||
declare var CustomEvent: {
|
||||
prototype: CustomEvent;
|
||||
new<T>(typeArg: string, eventInitDict?: CustomEventInit<T>): CustomEvent<T>;
|
||||
};
|
||||
|
||||
interface DOMException {
|
||||
readonly code: number;
|
||||
readonly message: string;
|
||||
@@ -754,7 +971,7 @@ interface DedicatedWorkerGlobalScopeEventMap extends WorkerGlobalScopeEventMap {
|
||||
interface DedicatedWorkerGlobalScope extends WorkerGlobalScope {
|
||||
onmessage: ((this: DedicatedWorkerGlobalScope, ev: MessageEvent) => any) | null;
|
||||
close(): void;
|
||||
postMessage(message: any, transfer?: any[]): void;
|
||||
postMessage(message: any, transfer?: Transferable[]): void;
|
||||
addEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
@@ -791,32 +1008,65 @@ interface ErrorEvent extends Event {
|
||||
readonly filename: string;
|
||||
readonly lineno: number;
|
||||
readonly message: string;
|
||||
initErrorEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, messageArg: string, filenameArg: string, linenoArg: number): void;
|
||||
}
|
||||
|
||||
declare var ErrorEvent: {
|
||||
prototype: ErrorEvent;
|
||||
new(typeArg: string, eventInitDict?: ErrorEventInit): ErrorEvent;
|
||||
new(type: string, eventInitDict?: ErrorEventInit): ErrorEvent;
|
||||
};
|
||||
|
||||
interface Event {
|
||||
/**
|
||||
* Returns true or false depending on how event was initialized. True if event goes through its target's ancestors in reverse tree order, and false otherwise.
|
||||
*/
|
||||
readonly bubbles: boolean;
|
||||
cancelBubble: boolean;
|
||||
readonly cancelable: boolean;
|
||||
/**
|
||||
* Returns true or false depending on how event was initialized. True if event invokes listeners past a ShadowRoot node that is the root of its target, and false otherwise.
|
||||
*/
|
||||
readonly composed: boolean;
|
||||
/**
|
||||
* Returns the object whose event listener's callback is currently being
|
||||
* invoked.
|
||||
*/
|
||||
readonly currentTarget: EventTarget | null;
|
||||
readonly defaultPrevented: boolean;
|
||||
readonly eventPhase: number;
|
||||
/**
|
||||
* Returns true if event was dispatched by the user agent, and
|
||||
* false otherwise.
|
||||
*/
|
||||
readonly isTrusted: boolean;
|
||||
returnValue: boolean;
|
||||
readonly srcElement: object | null;
|
||||
/**
|
||||
* Returns the object to which event is dispatched (its target).
|
||||
*/
|
||||
readonly target: EventTarget | null;
|
||||
/**
|
||||
* Returns the event's timestamp as the number of milliseconds measured relative to
|
||||
* the time origin.
|
||||
*/
|
||||
readonly timeStamp: number;
|
||||
/**
|
||||
* Returns the type of event, e.g.
|
||||
* "click", "hashchange", or
|
||||
* "submit".
|
||||
*/
|
||||
readonly type: string;
|
||||
deepPath(): EventTarget[];
|
||||
composedPath(): EventTarget[];
|
||||
initEvent(type: string, bubbles?: boolean, cancelable?: boolean): void;
|
||||
preventDefault(): void;
|
||||
/**
|
||||
* Invoking this method prevents event from reaching
|
||||
* any registered event listeners after the current one finishes running and, when dispatched in a tree, also prevents event from reaching any
|
||||
* other objects.
|
||||
*/
|
||||
stopImmediatePropagation(): void;
|
||||
/**
|
||||
* When dispatched in a tree, invoking this method prevents event from reaching any objects other than the current object.
|
||||
*/
|
||||
stopPropagation(): void;
|
||||
readonly AT_TARGET: number;
|
||||
readonly BUBBLING_PHASE: number;
|
||||
@@ -826,7 +1076,7 @@ interface Event {
|
||||
|
||||
declare var Event: {
|
||||
prototype: Event;
|
||||
new(typeArg: string, eventInitDict?: EventInit): Event;
|
||||
new(type: string, eventInitDict?: EventInit): Event;
|
||||
readonly AT_TARGET: number;
|
||||
readonly BUBBLING_PHASE: number;
|
||||
readonly CAPTURING_PHASE: number;
|
||||
@@ -860,9 +1110,26 @@ interface EventSourceInit {
|
||||
}
|
||||
|
||||
interface EventTarget {
|
||||
/**
|
||||
* Appends an event listener for events whose type attribute value is type. The callback argument sets the callback that will be invoked when the event is dispatched.
|
||||
* The options argument sets listener-specific options. For compatibility this can be a
|
||||
* boolean, in which case the method behaves exactly as if the value was specified as options's capture.
|
||||
* When set to true, options's capture prevents callback from being invoked when the event's eventPhase attribute value is BUBBLING_PHASE. When false (or not present), callback will not be invoked when event's eventPhase attribute value is CAPTURING_PHASE. Either way, callback will be invoked if event's eventPhase attribute value is AT_TARGET.
|
||||
* When set to true, options's passive indicates that the callback will not cancel the event by invoking preventDefault(). This is used to enable performance optimizations described in §2.8 Observing event listeners.
|
||||
* When set to true, options's once indicates that the callback will only be invoked once after which the event listener will
|
||||
* be removed.
|
||||
* The event listener is appended to target's event listener list and is not appended if it has the same type, callback, and capture.
|
||||
*/
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject | null, options?: boolean | AddEventListenerOptions): void;
|
||||
dispatchEvent(evt: Event): boolean;
|
||||
removeEventListener(type: string, listener?: EventListenerOrEventListenerObject | null, options?: EventListenerOptions | boolean): void;
|
||||
/**
|
||||
* Dispatches a synthetic event event to target and returns true
|
||||
* if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise.
|
||||
*/
|
||||
dispatchEvent(event: Event): boolean;
|
||||
/**
|
||||
* Removes the event listener in target's event listener list with the same type, callback, and options.
|
||||
*/
|
||||
removeEventListener(type: string, callback: EventListenerOrEventListenerObject | null, options?: EventListenerOptions | boolean): void;
|
||||
}
|
||||
|
||||
declare var EventTarget: {
|
||||
@@ -992,11 +1259,11 @@ interface FormData {
|
||||
|
||||
declare var FormData: {
|
||||
prototype: FormData;
|
||||
new(form?: object): FormData;
|
||||
new(): FormData;
|
||||
};
|
||||
|
||||
interface GlobalFetch {
|
||||
fetch(input?: Request | string, init?: RequestInit): Promise<Response>;
|
||||
fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
|
||||
}
|
||||
|
||||
interface Headers {
|
||||
@@ -1061,13 +1328,13 @@ interface IDBCursor {
|
||||
* Delete the record pointed at by the cursor with a new value.
|
||||
* If successful, request's result will be undefined.
|
||||
*/
|
||||
delete(): IDBRequest;
|
||||
delete(): IDBRequest<undefined>;
|
||||
/**
|
||||
* Updated the record pointed at by the cursor with a new value.
|
||||
* Throws a "DataError" DOMException if the effective object store uses in-line keys and the key would have changed.
|
||||
* If successful, request's result will be the record's key.
|
||||
*/
|
||||
update(value: any): IDBRequest;
|
||||
update(value: any): IDBRequest<IDBValidKey>;
|
||||
}
|
||||
|
||||
declare var IDBCursor: {
|
||||
@@ -1189,40 +1456,40 @@ interface IDBIndex {
|
||||
* If successful, request's result will be the
|
||||
* count.
|
||||
*/
|
||||
count(key?: IDBValidKey | IDBKeyRange): IDBRequest;
|
||||
count(key?: IDBValidKey | IDBKeyRange): IDBRequest<number>;
|
||||
/**
|
||||
* Retrieves the value of the first record matching the
|
||||
* given key or key range in query.
|
||||
* If successful, request's result will be the value, or undefined if there was no matching record.
|
||||
*/
|
||||
get(key: IDBValidKey | IDBKeyRange): IDBRequest;
|
||||
get(key: IDBValidKey | IDBKeyRange): IDBRequest<any | undefined>;
|
||||
/**
|
||||
* Retrieves the values of the records matching the given key or key range in query (up to count if given).
|
||||
* If successful, request's result will be an Array of the values.
|
||||
*/
|
||||
getAll(query?: IDBValidKey | IDBKeyRange, count?: number): IDBRequest;
|
||||
getAll(query?: IDBValidKey | IDBKeyRange, count?: number): IDBRequest<any[]>;
|
||||
/**
|
||||
* Retrieves the keys of records matching the given key or key range in query (up to count if given).
|
||||
* If successful, request's result will be an Array of the keys.
|
||||
*/
|
||||
getAllKeys(query?: IDBValidKey | IDBKeyRange, count?: number): IDBRequest;
|
||||
getAllKeys(query?: IDBValidKey | IDBKeyRange, count?: number): IDBRequest<IDBValidKey[]>;
|
||||
/**
|
||||
* Retrieves the key of the first record matching the
|
||||
* given key or key range in query.
|
||||
* If successful, request's result will be the key, or undefined if there was no matching record.
|
||||
*/
|
||||
getKey(key: IDBValidKey | IDBKeyRange): IDBRequest;
|
||||
getKey(key: IDBValidKey | IDBKeyRange): IDBRequest<IDBValidKey | undefined>;
|
||||
/**
|
||||
* Opens a cursor over the records matching query,
|
||||
* ordered by direction. If query is null, all records in index are matched.
|
||||
* If successful, request's result will be an IDBCursorWithValue, or null if there were no matching records.
|
||||
*/
|
||||
openCursor(range?: IDBValidKey | IDBKeyRange, direction?: IDBCursorDirection): IDBRequest;
|
||||
openCursor(range?: IDBValidKey | IDBKeyRange, direction?: IDBCursorDirection): IDBRequest<IDBCursorWithValue | null>;
|
||||
/**
|
||||
* Opens a cursor with key only flag set over the records matching query, ordered by direction. If query is null, all records in index are matched.
|
||||
* If successful, request's result will be an IDBCursor, or null if there were no matching records.
|
||||
*/
|
||||
openKeyCursor(range?: IDBValidKey | IDBKeyRange, direction?: IDBCursorDirection): IDBRequest;
|
||||
openKeyCursor(range?: IDBValidKey | IDBKeyRange, direction?: IDBCursorDirection): IDBRequest<IDBCursor | null>;
|
||||
}
|
||||
|
||||
declare var IDBIndex: {
|
||||
@@ -1301,19 +1568,19 @@ interface IDBObjectStore {
|
||||
* Returns the associated transaction.
|
||||
*/
|
||||
readonly transaction: IDBTransaction;
|
||||
add(value: any, key?: IDBValidKey | IDBKeyRange): IDBRequest;
|
||||
add(value: any, key?: IDBValidKey | IDBKeyRange): IDBRequest<IDBValidKey>;
|
||||
/**
|
||||
* Deletes all records in store.
|
||||
* If successful, request's result will
|
||||
* be undefined.
|
||||
*/
|
||||
clear(): IDBRequest;
|
||||
clear(): IDBRequest<undefined>;
|
||||
/**
|
||||
* Retrieves the number of records matching the
|
||||
* given key or key range in query.
|
||||
* If successful, request's result will be the count.
|
||||
*/
|
||||
count(key?: IDBValidKey | IDBKeyRange): IDBRequest;
|
||||
count(key?: IDBValidKey | IDBKeyRange): IDBRequest<number>;
|
||||
/**
|
||||
* Creates a new index in store with the given name, keyPath and options and returns a new IDBIndex. If the keyPath and options define constraints that cannot be
|
||||
* satisfied with the data already in store the upgrade
|
||||
@@ -1328,7 +1595,7 @@ interface IDBObjectStore {
|
||||
* If successful, request's result will
|
||||
* be undefined.
|
||||
*/
|
||||
delete(key: IDBValidKey | IDBKeyRange): IDBRequest;
|
||||
delete(key: IDBValidKey | IDBKeyRange): IDBRequest<undefined>;
|
||||
/**
|
||||
* Deletes the index in store with the given name.
|
||||
* Throws an "InvalidStateError" DOMException if not called within an upgrade
|
||||
@@ -1340,41 +1607,41 @@ interface IDBObjectStore {
|
||||
* given key or key range in query.
|
||||
* If successful, request's result will be the value, or undefined if there was no matching record.
|
||||
*/
|
||||
get(query: IDBValidKey | IDBKeyRange): IDBRequest;
|
||||
get(query: IDBValidKey | IDBKeyRange): IDBRequest<any | undefined>;
|
||||
/**
|
||||
* Retrieves the values of the records matching the
|
||||
* given key or key range in query (up to count if given).
|
||||
* If successful, request's result will
|
||||
* be an Array of the values.
|
||||
*/
|
||||
getAll(query?: IDBValidKey | IDBKeyRange, count?: number): IDBRequest;
|
||||
getAll(query?: IDBValidKey | IDBKeyRange, count?: number): IDBRequest<any[]>;
|
||||
/**
|
||||
* Retrieves the keys of records matching the
|
||||
* given key or key range in query (up to count if given).
|
||||
* If successful, request's result will
|
||||
* be an Array of the keys.
|
||||
*/
|
||||
getAllKeys(query?: IDBValidKey | IDBKeyRange, count?: number): IDBRequest;
|
||||
getAllKeys(query?: IDBValidKey | IDBKeyRange, count?: number): IDBRequest<IDBValidKey[]>;
|
||||
/**
|
||||
* Retrieves the key of the first record matching the
|
||||
* given key or key range in query.
|
||||
* If successful, request's result will be the key, or undefined if there was no matching record.
|
||||
*/
|
||||
getKey(query: IDBValidKey | IDBKeyRange): IDBRequest;
|
||||
getKey(query: IDBValidKey | IDBKeyRange): IDBRequest<IDBValidKey | undefined>;
|
||||
index(name: string): IDBIndex;
|
||||
/**
|
||||
* Opens a cursor over the records matching query,
|
||||
* ordered by direction. If query is null, all records in store are matched.
|
||||
* If successful, request's result will be an IDBCursorWithValue pointing at the first matching record, or null if there were no matching records.
|
||||
*/
|
||||
openCursor(range?: IDBValidKey | IDBKeyRange, direction?: IDBCursorDirection): IDBRequest;
|
||||
openCursor(range?: IDBValidKey | IDBKeyRange, direction?: IDBCursorDirection): IDBRequest<IDBCursorWithValue | null>;
|
||||
/**
|
||||
* Opens a cursor with key only flag set over the records matching query, ordered by direction. If query is null, all records in store are matched.
|
||||
* If successful, request's result will be an IDBCursor pointing at the first matching record, or
|
||||
* null if there were no matching records.
|
||||
*/
|
||||
openKeyCursor(query?: IDBValidKey | IDBKeyRange, direction?: IDBCursorDirection): IDBRequest;
|
||||
put(value: any, key?: IDBValidKey | IDBKeyRange): IDBRequest;
|
||||
openKeyCursor(query?: IDBValidKey | IDBKeyRange, direction?: IDBCursorDirection): IDBRequest<IDBCursor | null>;
|
||||
put(value: any, key?: IDBValidKey | IDBKeyRange): IDBRequest<IDBValidKey>;
|
||||
}
|
||||
|
||||
declare var IDBObjectStore: {
|
||||
@@ -1387,7 +1654,7 @@ interface IDBOpenDBRequestEventMap extends IDBRequestEventMap {
|
||||
"upgradeneeded": IDBVersionChangeEvent;
|
||||
}
|
||||
|
||||
interface IDBOpenDBRequest extends IDBRequest {
|
||||
interface IDBOpenDBRequest extends IDBRequest<IDBDatabase> {
|
||||
onblocked: ((this: IDBOpenDBRequest, ev: Event) => any) | null;
|
||||
onupgradeneeded: ((this: IDBOpenDBRequest, ev: IDBVersionChangeEvent) => any) | null;
|
||||
addEventListener<K extends keyof IDBOpenDBRequestEventMap>(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
@@ -1406,14 +1673,14 @@ interface IDBRequestEventMap {
|
||||
"success": Event;
|
||||
}
|
||||
|
||||
interface IDBRequest extends EventTarget {
|
||||
interface IDBRequest<T = any> extends EventTarget {
|
||||
/**
|
||||
* When a request is completed, returns the error (a DOMException), or null if the request succeeded. Throws
|
||||
* a "InvalidStateError" DOMException if the request is still pending.
|
||||
*/
|
||||
readonly error: DOMException | null;
|
||||
onerror: ((this: IDBRequest, ev: Event) => any) | null;
|
||||
onsuccess: ((this: IDBRequest, ev: Event) => any) | null;
|
||||
onerror: ((this: IDBRequest<T>, ev: Event) => any) | null;
|
||||
onsuccess: ((this: IDBRequest<T>, ev: Event) => any) | null;
|
||||
/**
|
||||
* Returns "pending" until a request is complete,
|
||||
* then returns "done".
|
||||
@@ -1424,7 +1691,7 @@ interface IDBRequest extends EventTarget {
|
||||
* or undefined if the request failed. Throws a
|
||||
* "InvalidStateError" DOMException if the request is still pending.
|
||||
*/
|
||||
readonly result: any;
|
||||
readonly result: T;
|
||||
/**
|
||||
* Returns the IDBObjectStore, IDBIndex, or IDBCursor the request was made against, or null if is was an open
|
||||
* request.
|
||||
@@ -1435,9 +1702,9 @@ interface IDBRequest extends EventTarget {
|
||||
* If this as an open request, then it returns an upgrade transaction while it is running, or null otherwise.
|
||||
*/
|
||||
readonly transaction: IDBTransaction | null;
|
||||
addEventListener<K extends keyof IDBRequestEventMap>(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof IDBRequestEventMap>(type: K, listener: (this: IDBRequest<T>, ev: IDBRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof IDBRequestEventMap>(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof IDBRequestEventMap>(type: K, listener: (this: IDBRequest<T>, ev: IDBRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
@@ -1508,11 +1775,27 @@ declare var IDBVersionChangeEvent: {
|
||||
};
|
||||
|
||||
interface ImageBitmap {
|
||||
/**
|
||||
* Returns the intrinsic height of the image, in CSS
|
||||
* pixels.
|
||||
*/
|
||||
readonly height: number;
|
||||
/**
|
||||
* Returns the intrinsic width of the image, in CSS
|
||||
* pixels.
|
||||
*/
|
||||
readonly width: number;
|
||||
/**
|
||||
* Releases imageBitmap's underlying bitmap data.
|
||||
*/
|
||||
close(): void;
|
||||
}
|
||||
|
||||
declare var ImageBitmap: {
|
||||
prototype: ImageBitmap;
|
||||
new(): ImageBitmap;
|
||||
};
|
||||
|
||||
interface ImageBitmapOptions {
|
||||
colorSpaceConversion?: "none" | "default";
|
||||
imageOrientation?: "none" | "flipY";
|
||||
@@ -1523,6 +1806,17 @@ interface ImageBitmapOptions {
|
||||
}
|
||||
|
||||
interface ImageData {
|
||||
/**
|
||||
* Returns the one-dimensional array containing the data in RGBA order, as integers in the
|
||||
* range 0 to 255.
|
||||
*/
|
||||
readonly data: Uint8ClampedArray;
|
||||
/**
|
||||
* Returns the actual dimensions of the data in the ImageData object, in
|
||||
* pixels.
|
||||
*/
|
||||
readonly height: number;
|
||||
readonly width: number;
|
||||
}
|
||||
|
||||
declare var ImageData: {
|
||||
@@ -1542,11 +1836,31 @@ declare var MessageChannel: {
|
||||
};
|
||||
|
||||
interface MessageEvent extends Event {
|
||||
/**
|
||||
* Returns the data of the message.
|
||||
*/
|
||||
readonly data: any;
|
||||
/**
|
||||
* Returns the last event ID string, for
|
||||
* server-sent events.
|
||||
*/
|
||||
readonly lastEventId: string;
|
||||
/**
|
||||
* Returns the origin of the message, for server-sent events and
|
||||
* cross-document messaging.
|
||||
*/
|
||||
readonly origin: string;
|
||||
/**
|
||||
* Returns the MessagePort array sent with the message, for cross-document
|
||||
* messaging and channel messaging.
|
||||
*/
|
||||
readonly ports: ReadonlyArray<MessagePort>;
|
||||
readonly source: MessageEventSource;
|
||||
initMessageEvent(type: string, bubbles: boolean, cancelable: boolean, data: any, origin: string, lastEventId: string, source: object): void;
|
||||
/**
|
||||
* Returns the WindowProxy of the source window, for cross-document
|
||||
* messaging, and the MessagePort being attached, in the connect event fired at
|
||||
* SharedWorkerGlobalScope objects.
|
||||
*/
|
||||
readonly source: MessageEventSource | null;
|
||||
}
|
||||
|
||||
declare var MessageEvent: {
|
||||
@@ -1573,7 +1887,7 @@ interface MessagePort extends EventTarget {
|
||||
* transfer contains duplicate objects or port, or if message
|
||||
* could not be cloned.
|
||||
*/
|
||||
postMessage(message: any, transfer?: any[]): void;
|
||||
postMessage(message: any, transfer?: Transferable[]): void;
|
||||
/**
|
||||
* Begins dispatching messages received on the port.
|
||||
*/
|
||||
@@ -1680,6 +1994,15 @@ declare var NotificationEvent: {
|
||||
new(type: string, eventInitDict: NotificationEventInit): NotificationEvent;
|
||||
};
|
||||
|
||||
interface Path2D extends CanvasPath {
|
||||
addPath(path: Path2D, transform?: DOMMatrix2DInit): void;
|
||||
}
|
||||
|
||||
declare var Path2D: {
|
||||
prototype: Path2D;
|
||||
new(path?: Path2D | string): Path2D;
|
||||
};
|
||||
|
||||
interface PerformanceEventMap {
|
||||
"resourcetimingbufferfull": Event;
|
||||
}
|
||||
@@ -1798,7 +2121,7 @@ declare var ProgressEvent: {
|
||||
};
|
||||
|
||||
interface PromiseRejectionEvent extends Event {
|
||||
readonly promise: PromiseLike<any>;
|
||||
readonly promise: Promise<any>;
|
||||
readonly reason: any;
|
||||
}
|
||||
|
||||
@@ -1968,7 +2291,7 @@ interface Request extends Body {
|
||||
* Returns the signal associated with request, which is an AbortSignal object indicating whether or not request has been aborted, and its abort
|
||||
* event handler.
|
||||
*/
|
||||
readonly signal: object;
|
||||
readonly signal: AbortSignal;
|
||||
/**
|
||||
* Returns the URL of request as a string.
|
||||
*/
|
||||
@@ -2008,7 +2331,7 @@ interface ServiceWorker extends EventTarget, AbstractWorker {
|
||||
onstatechange: ((this: ServiceWorker, ev: Event) => any) | null;
|
||||
readonly scriptURL: string;
|
||||
readonly state: ServiceWorkerState;
|
||||
postMessage(message: any, transfer?: any[]): void;
|
||||
postMessage(message: any, transfer?: Transferable[]): void;
|
||||
addEventListener<K extends keyof ServiceWorkerEventMap>(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof ServiceWorkerEventMap>(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
@@ -2124,6 +2447,32 @@ declare var StorageManager: {
|
||||
new(): StorageManager;
|
||||
};
|
||||
|
||||
interface SubtleCrypto {
|
||||
decrypt(algorithm: string | RsaOaepParams | AesCtrParams | AesCbcParams | AesCmacParams | AesGcmParams | AesCfbParams, key: CryptoKey, data: Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | DataView | ArrayBuffer): PromiseLike<ArrayBuffer>;
|
||||
deriveBits(algorithm: string | EcdhKeyDeriveParams | DhKeyDeriveParams | ConcatParams | HkdfCtrParams | Pbkdf2Params, baseKey: CryptoKey, length: number): PromiseLike<ArrayBuffer>;
|
||||
deriveKey(algorithm: string | EcdhKeyDeriveParams | DhKeyDeriveParams | ConcatParams | HkdfCtrParams | Pbkdf2Params, baseKey: CryptoKey, derivedKeyType: string | AesDerivedKeyParams | HmacImportParams | ConcatParams | HkdfCtrParams | Pbkdf2Params, extractable: boolean, keyUsages: string[]): PromiseLike<CryptoKey>;
|
||||
digest(algorithm: string | Algorithm, data: Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | DataView | ArrayBuffer): PromiseLike<ArrayBuffer>;
|
||||
encrypt(algorithm: string | RsaOaepParams | AesCtrParams | AesCbcParams | AesCmacParams | AesGcmParams | AesCfbParams, key: CryptoKey, data: Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | DataView | ArrayBuffer): PromiseLike<ArrayBuffer>;
|
||||
exportKey(format: "jwk", key: CryptoKey): PromiseLike<JsonWebKey>;
|
||||
exportKey(format: "raw" | "pkcs8" | "spki", key: CryptoKey): PromiseLike<ArrayBuffer>;
|
||||
exportKey(format: string, key: CryptoKey): PromiseLike<JsonWebKey | ArrayBuffer>;
|
||||
generateKey(algorithm: string, extractable: boolean, keyUsages: string[]): PromiseLike<CryptoKeyPair | CryptoKey>;
|
||||
generateKey(algorithm: RsaHashedKeyGenParams | EcKeyGenParams | DhKeyGenParams, extractable: boolean, keyUsages: string[]): PromiseLike<CryptoKeyPair>;
|
||||
generateKey(algorithm: AesKeyGenParams | HmacKeyGenParams | Pbkdf2Params, extractable: boolean, keyUsages: string[]): PromiseLike<CryptoKey>;
|
||||
importKey(format: "jwk", keyData: JsonWebKey, algorithm: string | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | DhImportKeyParams | AesKeyAlgorithm, extractable: boolean, keyUsages: string[]): PromiseLike<CryptoKey>;
|
||||
importKey(format: "raw" | "pkcs8" | "spki", keyData: Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | DataView | ArrayBuffer, algorithm: string | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | DhImportKeyParams | AesKeyAlgorithm, extractable: boolean, keyUsages: string[]): PromiseLike<CryptoKey>;
|
||||
importKey(format: string, keyData: JsonWebKey | Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | DataView | ArrayBuffer, algorithm: string | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | DhImportKeyParams | AesKeyAlgorithm, extractable: boolean, keyUsages: string[]): PromiseLike<CryptoKey>;
|
||||
sign(algorithm: string | RsaPssParams | EcdsaParams | AesCmacParams, key: CryptoKey, data: Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | DataView | ArrayBuffer): PromiseLike<ArrayBuffer>;
|
||||
unwrapKey(format: string, wrappedKey: Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | DataView | ArrayBuffer, unwrappingKey: CryptoKey, unwrapAlgorithm: string | Algorithm, unwrappedKeyAlgorithm: string | Algorithm, extractable: boolean, keyUsages: string[]): PromiseLike<CryptoKey>;
|
||||
verify(algorithm: string | RsaPssParams | EcdsaParams | AesCmacParams, key: CryptoKey, signature: Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | DataView | ArrayBuffer, data: Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | DataView | ArrayBuffer): PromiseLike<boolean>;
|
||||
wrapKey(format: string, key: CryptoKey, wrappingKey: CryptoKey, wrapAlgorithm: string | Algorithm): PromiseLike<ArrayBuffer>;
|
||||
}
|
||||
|
||||
declare var SubtleCrypto: {
|
||||
prototype: SubtleCrypto;
|
||||
new(): SubtleCrypto;
|
||||
};
|
||||
|
||||
interface SyncEvent extends ExtendableEvent {
|
||||
readonly lastChance: boolean;
|
||||
readonly tag: string;
|
||||
@@ -2313,13 +2662,31 @@ interface WindowConsole {
|
||||
readonly console: Console;
|
||||
}
|
||||
|
||||
interface WindowOrWorkerGlobalScope {
|
||||
readonly caches: CacheStorage;
|
||||
readonly crypto: Crypto;
|
||||
readonly indexedDB: IDBFactory;
|
||||
readonly origin: string;
|
||||
readonly performance: Performance;
|
||||
atob(data: string): string;
|
||||
btoa(data: string): string;
|
||||
clearInterval(handle?: number): void;
|
||||
clearTimeout(handle?: number): void;
|
||||
createImageBitmap(image: ImageBitmapSource): Promise<ImageBitmap>;
|
||||
createImageBitmap(image: ImageBitmapSource, sx: number, sy: number, sw: number, sh: number): Promise<ImageBitmap>;
|
||||
fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
|
||||
queueMicrotask(callback: Function): void;
|
||||
setInterval(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
|
||||
setTimeout(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
|
||||
}
|
||||
|
||||
interface WorkerEventMap extends AbstractWorkerEventMap {
|
||||
"message": MessageEvent;
|
||||
}
|
||||
|
||||
interface Worker extends EventTarget, AbstractWorker {
|
||||
onmessage: ((this: Worker, ev: MessageEvent) => any) | null;
|
||||
postMessage(message: any, transfer?: any[]): void;
|
||||
postMessage(message: any, transfer?: Transferable[]): void;
|
||||
terminate(): void;
|
||||
addEventListener<K extends keyof WorkerEventMap>(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
@@ -2336,15 +2703,13 @@ interface WorkerGlobalScopeEventMap {
|
||||
"error": ErrorEvent;
|
||||
}
|
||||
|
||||
interface WorkerGlobalScope extends EventTarget, WorkerUtils, WindowConsole, GlobalFetch {
|
||||
interface WorkerGlobalScope extends EventTarget, WorkerUtils, WindowConsole, GlobalFetch, WindowOrWorkerGlobalScope {
|
||||
readonly caches: CacheStorage;
|
||||
readonly isSecureContext: boolean;
|
||||
readonly location: WorkerLocation;
|
||||
onerror: ((this: WorkerGlobalScope, ev: ErrorEvent) => any) | null;
|
||||
readonly performance: Performance;
|
||||
readonly self: WorkerGlobalScope;
|
||||
createImageBitmap(image: ImageBitmap | ImageData | Blob, options?: ImageBitmapOptions): Promise<ImageBitmap>;
|
||||
createImageBitmap(image: ImageBitmap | ImageData | Blob, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise<ImageBitmap>;
|
||||
msWriteProfilerMark(profilerMarkName: string): void;
|
||||
addEventListener<K extends keyof WorkerGlobalScopeEventMap>(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
@@ -2388,13 +2753,7 @@ interface WorkerUtils extends WindowBase64 {
|
||||
readonly indexedDB: IDBFactory;
|
||||
readonly msIndexedDB: IDBFactory;
|
||||
readonly navigator: WorkerNavigator;
|
||||
clearImmediate(handle: number): void;
|
||||
clearInterval(handle: number): void;
|
||||
clearTimeout(handle: number): void;
|
||||
importScripts(...urls: string[]): void;
|
||||
setImmediate(handler: any, ...args: any[]): number;
|
||||
setInterval(handler: any, timeout?: any, ...args: any[]): number;
|
||||
setTimeout(handler: any, timeout?: any, ...args: any[]): number;
|
||||
}
|
||||
|
||||
interface XMLHttpRequestEventMap extends XMLHttpRequestEventTargetEventMap {
|
||||
@@ -2478,7 +2837,7 @@ interface XMLHttpRequest extends XMLHttpRequestEventTarget {
|
||||
* Initiates the request. The optional argument provides the request body. The argument is ignored if request method is GET or HEAD.
|
||||
* Throws an "InvalidStateError" DOMException if either state is not opened or the send() flag is set.
|
||||
*/
|
||||
send(body?: object | BodyInit): void;
|
||||
send(body?: BodyInit | null): void;
|
||||
/**
|
||||
* Combines a header in author request headers.
|
||||
* Throws an "InvalidStateError" DOMException if either state is not opened or the send() flag is set.
|
||||
@@ -2560,31 +2919,47 @@ interface PerformanceObserverCallback {
|
||||
|
||||
declare var onmessage: ((this: DedicatedWorkerGlobalScope, ev: MessageEvent) => any) | null;
|
||||
declare function close(): void;
|
||||
declare function postMessage(message: any, transfer?: any[]): void;
|
||||
declare function dispatchEvent(evt: Event): boolean;
|
||||
declare function postMessage(message: any, transfer?: Transferable[]): void;
|
||||
/**
|
||||
* Dispatches a synthetic event event to target and returns true
|
||||
* if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise.
|
||||
*/
|
||||
declare function dispatchEvent(event: Event): boolean;
|
||||
declare var caches: CacheStorage;
|
||||
declare var isSecureContext: boolean;
|
||||
declare var location: WorkerLocation;
|
||||
declare var onerror: ((this: DedicatedWorkerGlobalScope, ev: ErrorEvent) => any) | null;
|
||||
declare var performance: Performance;
|
||||
declare var self: WorkerGlobalScope;
|
||||
declare function createImageBitmap(image: ImageBitmap | ImageData | Blob, options?: ImageBitmapOptions): Promise<ImageBitmap>;
|
||||
declare function createImageBitmap(image: ImageBitmap | ImageData | Blob, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise<ImageBitmap>;
|
||||
declare function msWriteProfilerMark(profilerMarkName: string): void;
|
||||
declare function dispatchEvent(evt: Event): boolean;
|
||||
/**
|
||||
* Dispatches a synthetic event event to target and returns true
|
||||
* if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise.
|
||||
*/
|
||||
declare function dispatchEvent(event: Event): boolean;
|
||||
declare var indexedDB: IDBFactory;
|
||||
declare var msIndexedDB: IDBFactory;
|
||||
declare var navigator: WorkerNavigator;
|
||||
declare function clearImmediate(handle: number): void;
|
||||
declare function clearInterval(handle: number): void;
|
||||
declare function clearTimeout(handle: number): void;
|
||||
declare function setImmediate(handler: any, ...args: any[]): number;
|
||||
declare function setInterval(handler: any, timeout?: any, ...args: any[]): number;
|
||||
declare function setTimeout(handler: any, timeout?: any, ...args: any[]): number;
|
||||
declare function importScripts(...urls: string[]): void;
|
||||
declare function atob(encodedString: string): string;
|
||||
declare function btoa(rawString: string): string;
|
||||
declare var console: Console;
|
||||
declare function fetch(input?: Request | string, init?: RequestInit): Promise<Response>;
|
||||
declare function fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
|
||||
declare var caches: CacheStorage;
|
||||
declare var crypto: Crypto;
|
||||
declare var indexedDB: IDBFactory;
|
||||
declare var origin: string;
|
||||
declare var performance: Performance;
|
||||
declare function atob(data: string): string;
|
||||
declare function btoa(data: string): string;
|
||||
declare function clearInterval(handle?: number): void;
|
||||
declare function clearTimeout(handle?: number): void;
|
||||
declare function createImageBitmap(image: ImageBitmapSource): Promise<ImageBitmap>;
|
||||
declare function createImageBitmap(image: ImageBitmapSource, sx: number, sy: number, sw: number, sh: number): Promise<ImageBitmap>;
|
||||
declare function fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
|
||||
declare function queueMicrotask(callback: Function): void;
|
||||
declare function setInterval(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
|
||||
declare function setTimeout(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
|
||||
declare function addEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
declare function removeEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
@@ -2594,19 +2969,30 @@ type HeadersInit = Headers | string[][] | Record<string, string>;
|
||||
type BodyInit = Blob | BufferSource | FormData | URLSearchParams | ReadableStream | string;
|
||||
type RequestInfo = Request | string;
|
||||
type DOMHighResTimeStamp = number;
|
||||
type CanvasImageSource = ImageBitmap;
|
||||
type MessageEventSource = MessagePort | ServiceWorker;
|
||||
type ImageBitmapSource = CanvasImageSource | Blob | ImageData;
|
||||
type TimerHandler = string | Function;
|
||||
type PerformanceEntryList = PerformanceEntry[];
|
||||
type PushMessageDataInit = BufferSource | string;
|
||||
type VibratePattern = number | number[];
|
||||
type AlgorithmIdentifier = string | Algorithm;
|
||||
type HashAlgorithmIdentifier = AlgorithmIdentifier;
|
||||
type BigInteger = Uint8Array;
|
||||
type NamedCurve = string;
|
||||
type BufferSource = ArrayBufferView | ArrayBuffer;
|
||||
type DOMTimeStamp = number;
|
||||
type FormDataEntryValue = File | string;
|
||||
type IDBValidKey = number | string | Date | BufferSource | IDBArrayKey;
|
||||
type MessageEventSource = object | MessagePort | ServiceWorker;
|
||||
type Transferable = ArrayBuffer | MessagePort | ImageBitmap;
|
||||
type BinaryType = "blob" | "arraybuffer";
|
||||
type ClientTypes = "window" | "worker" | "sharedworker" | "all";
|
||||
type IDBCursorDirection = "next" | "nextunique" | "prev" | "prevunique";
|
||||
type IDBRequestReadyState = "pending" | "done";
|
||||
type IDBTransactionMode = "readonly" | "readwrite" | "versionchange";
|
||||
type KeyFormat = "raw" | "spki" | "pkcs8" | "jwk";
|
||||
type KeyType = "public" | "private" | "secret";
|
||||
type KeyUsage = "encrypt" | "decrypt" | "sign" | "verify" | "deriveKey" | "deriveBits" | "wrapKey" | "unwrapKey";
|
||||
type NotificationDirection = "auto" | "ltr" | "rtl";
|
||||
type NotificationPermission = "default" | "denied" | "granted";
|
||||
type PushEncryptionKeyName = "p256dh" | "auth";
|
||||
@@ -2620,6 +3006,6 @@ type RequestRedirect = "follow" | "error" | "manual";
|
||||
type ResponseType = "basic" | "cors" | "default" | "error" | "opaque" | "opaqueredirect";
|
||||
type ServiceWorkerState = "installing" | "installed" | "activating" | "activated" | "redundant";
|
||||
type ServiceWorkerUpdateViaCache = "imports" | "all" | "none";
|
||||
type VisibilityState = "hidden" | "visible" | "prerender" | "unloaded";
|
||||
type VisibilityState = "hidden" | "visible" | "prerender";
|
||||
type WorkerType = "classic" | "module";
|
||||
type XMLHttpRequestResponseType = "" | "arraybuffer" | "blob" | "document" | "json" | "text";
|
||||
type XMLHttpRequestResponseType = "" | "arraybuffer" | "blob" | "document" | "json" | "text";
|
||||
|
||||
Vendored
+26
-1
@@ -519,7 +519,7 @@ declare namespace ts.server.protocol {
|
||||
/**
|
||||
* Errorcodes we want to get the fixes for.
|
||||
*/
|
||||
errorCodes?: ReadonlyArray<number>;
|
||||
errorCodes: ReadonlyArray<number>;
|
||||
}
|
||||
interface GetCombinedCodeFixRequestArgs {
|
||||
scope: GetCombinedCodeFixScope;
|
||||
@@ -591,6 +591,12 @@ declare namespace ts.server.protocol {
|
||||
interface DefinitionRequest extends FileLocationRequest {
|
||||
command: CommandTypes.Definition;
|
||||
}
|
||||
interface DefinitionAndBoundSpanRequest extends FileLocationRequest {
|
||||
readonly command: CommandTypes.DefinitionAndBoundSpan;
|
||||
}
|
||||
interface DefinitionAndBoundSpanResponse extends Response {
|
||||
readonly body: DefinitionInfoAndBoundSpan;
|
||||
}
|
||||
/**
|
||||
* Go to type request; value of command field is
|
||||
* "typeDefinition". Return response giving the file locations that
|
||||
@@ -1879,6 +1885,25 @@ declare namespace ts.server.protocol {
|
||||
*/
|
||||
openFiles: string[];
|
||||
}
|
||||
type LargeFileReferencedEventName = "largeFileReferenced";
|
||||
interface LargeFileReferencedEvent extends Event {
|
||||
event: LargeFileReferencedEventName;
|
||||
body: LargeFileReferencedEventBody;
|
||||
}
|
||||
interface LargeFileReferencedEventBody {
|
||||
/**
|
||||
* name of the large file being loaded
|
||||
*/
|
||||
file: string;
|
||||
/**
|
||||
* size of the file
|
||||
*/
|
||||
fileSize: number;
|
||||
/**
|
||||
* max file size allowed on the server
|
||||
*/
|
||||
maxFileSize: number;
|
||||
}
|
||||
/**
|
||||
* Arguments for reload request.
|
||||
*/
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
"A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged_2434": "Uma declaração de namespace não pode estar localizada antes de uma classe ou função com a qual ela é mesclada.",
|
||||
"A_namespace_declaration_is_only_allowed_in_a_namespace_or_module_1235": "Uma declaração de namespace só é permitida e um namespace ou módulo.",
|
||||
"A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_7038": "Uma importação de estilo do namespace não pode ser chamada nem construída e causará uma falha no tempo de execução.",
|
||||
"A_non_dry_build_would_build_project_0_6357": "Um build não -dry compilaria o projeto '{0}'",
|
||||
"A_non_dry_build_would_build_project_0_6357": "Um build não -dry criaria o projeto '{0}'",
|
||||
"A_non_dry_build_would_delete_the_following_files_Colon_0_6356": "Um build não -dry excluiria os seguintes arquivos: {0}",
|
||||
"A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation_2371": "Um inicializador de parâmetro só é permitido em uma implementação de função ou de construtor.",
|
||||
"A_parameter_property_cannot_be_declared_using_a_rest_parameter_1317": "Uma propriedade de parâmetro não pode ser declarada usando um parâmetro rest.",
|
||||
|
||||
+2580
-1537
File diff suppressed because it is too large
Load Diff
+4949
-2943
File diff suppressed because it is too large
Load Diff
Vendored
+1571
-6942
File diff suppressed because it is too large
Load Diff
+14777
-10435
File diff suppressed because it is too large
Load Diff
Vendored
+138
-44
@@ -13,9 +13,8 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
declare namespace ts {
|
||||
const versionMajorMinor = "3.0";
|
||||
const versionMajorMinor = "3.1";
|
||||
/** The version of the TypeScript compiler release */
|
||||
const version: string;
|
||||
}
|
||||
@@ -369,20 +368,21 @@ declare namespace ts {
|
||||
JSDocAugmentsTag = 293,
|
||||
JSDocClassTag = 294,
|
||||
JSDocCallbackTag = 295,
|
||||
JSDocParameterTag = 296,
|
||||
JSDocReturnTag = 297,
|
||||
JSDocThisTag = 298,
|
||||
JSDocTypeTag = 299,
|
||||
JSDocTemplateTag = 300,
|
||||
JSDocTypedefTag = 301,
|
||||
JSDocPropertyTag = 302,
|
||||
SyntaxList = 303,
|
||||
NotEmittedStatement = 304,
|
||||
PartiallyEmittedExpression = 305,
|
||||
CommaListExpression = 306,
|
||||
MergeDeclarationMarker = 307,
|
||||
EndOfDeclarationMarker = 308,
|
||||
Count = 309,
|
||||
JSDocEnumTag = 296,
|
||||
JSDocParameterTag = 297,
|
||||
JSDocReturnTag = 298,
|
||||
JSDocThisTag = 299,
|
||||
JSDocTypeTag = 300,
|
||||
JSDocTemplateTag = 301,
|
||||
JSDocTypedefTag = 302,
|
||||
JSDocPropertyTag = 303,
|
||||
SyntaxList = 304,
|
||||
NotEmittedStatement = 305,
|
||||
PartiallyEmittedExpression = 306,
|
||||
CommaListExpression = 307,
|
||||
MergeDeclarationMarker = 308,
|
||||
EndOfDeclarationMarker = 309,
|
||||
Count = 310,
|
||||
FirstAssignment = 58,
|
||||
LastAssignment = 70,
|
||||
FirstCompoundAssignment = 59,
|
||||
@@ -409,9 +409,9 @@ declare namespace ts {
|
||||
LastBinaryOperator = 70,
|
||||
FirstNode = 146,
|
||||
FirstJSDocNode = 281,
|
||||
LastJSDocNode = 302,
|
||||
LastJSDocNode = 303,
|
||||
FirstJSDocTagNode = 292,
|
||||
LastJSDocTagNode = 302
|
||||
LastJSDocTagNode = 303
|
||||
}
|
||||
enum NodeFlags {
|
||||
None = 0,
|
||||
@@ -480,7 +480,7 @@ declare namespace ts {
|
||||
}
|
||||
interface JSDocContainer {
|
||||
}
|
||||
type HasJSDoc = ParameterDeclaration | CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | PropertySignature | ArrowFunction | ParenthesizedExpression | SpreadAssignment | ShorthandPropertyAssignment | PropertyAssignment | FunctionExpression | LabeledStatement | ExpressionStatement | VariableStatement | FunctionDeclaration | ConstructorDeclaration | MethodDeclaration | PropertyDeclaration | AccessorDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | EnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | EndOfFileToken;
|
||||
type HasJSDoc = ParameterDeclaration | CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | PropertySignature | ArrowFunction | ParenthesizedExpression | SpreadAssignment | ShorthandPropertyAssignment | PropertyAssignment | FunctionExpression | LabeledStatement | ExpressionStatement | VariableStatement | FunctionDeclaration | ConstructorDeclaration | MethodDeclaration | PropertyDeclaration | AccessorDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | EnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | ExportDeclaration | EndOfFileToken;
|
||||
type HasType = SignatureDeclaration | VariableDeclaration | ParameterDeclaration | PropertySignature | PropertyDeclaration | TypePredicateNode | ParenthesizedTypeNode | TypeOperatorNode | MappedTypeNode | AssertionExpression | TypeAliasDeclaration | JSDocTypeExpression | JSDocNonNullableType | JSDocNullableType | JSDocOptionalType | JSDocVariadicType;
|
||||
type HasInitializer = HasExpressionInitializer | ForStatement | ForInStatement | ForOfStatement | JsxAttribute;
|
||||
type HasExpressionInitializer = VariableDeclaration | ParameterDeclaration | BindingElement | PropertySignature | PropertyDeclaration | PropertyAssignment | EnumMember;
|
||||
@@ -546,8 +546,9 @@ declare namespace ts {
|
||||
}
|
||||
interface TypeParameterDeclaration extends NamedDeclaration {
|
||||
kind: SyntaxKind.TypeParameter;
|
||||
parent: DeclarationWithTypeParameters | InferTypeNode;
|
||||
parent: DeclarationWithTypeParameterChildren | InferTypeNode;
|
||||
name: Identifier;
|
||||
/** Note: Consider calling `getEffectiveConstraintOfTypeParameter` */
|
||||
constraint?: TypeNode;
|
||||
default?: TypeNode;
|
||||
expression?: Expression;
|
||||
@@ -617,6 +618,7 @@ declare namespace ts {
|
||||
_objectLiteralBrandBrand: any;
|
||||
name?: PropertyName;
|
||||
}
|
||||
/** Unlike ObjectLiteralElement, excludes JSXAttribute and JSXSpreadAttribute. */
|
||||
type ObjectLiteralElementLike = PropertyAssignment | ShorthandPropertyAssignment | SpreadAssignment | MethodDeclaration | AccessorDeclaration;
|
||||
interface PropertyAssignment extends ObjectLiteralElement, JSDocContainer {
|
||||
parent: ObjectLiteralExpression;
|
||||
@@ -750,7 +752,7 @@ declare namespace ts {
|
||||
}
|
||||
interface TypePredicateNode extends TypeNode {
|
||||
kind: SyntaxKind.TypePredicate;
|
||||
parent: SignatureDeclaration;
|
||||
parent: SignatureDeclaration | JSDocTypeExpression;
|
||||
parameterName: Identifier | ThisTypeNode;
|
||||
type: TypeNode;
|
||||
}
|
||||
@@ -1318,7 +1320,8 @@ declare namespace ts {
|
||||
block: Block;
|
||||
}
|
||||
type ObjectTypeDeclaration = ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode;
|
||||
type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature;
|
||||
type DeclarationWithTypeParameters = DeclarationWithTypeParameterChildren | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature;
|
||||
type DeclarationWithTypeParameterChildren = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag;
|
||||
interface ClassLikeDeclarationBase extends NamedDeclaration, JSDocContainer {
|
||||
kind: SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression;
|
||||
name?: Identifier;
|
||||
@@ -1437,7 +1440,7 @@ declare namespace ts {
|
||||
kind: SyntaxKind.NamespaceExportDeclaration;
|
||||
name: Identifier;
|
||||
}
|
||||
interface ExportDeclaration extends DeclarationStatement {
|
||||
interface ExportDeclaration extends DeclarationStatement, JSDocContainer {
|
||||
kind: SyntaxKind.ExportDeclaration;
|
||||
parent: SourceFile | ModuleBlock;
|
||||
/** Will not be assigned in the case of `export * from "foo";` */
|
||||
@@ -1556,12 +1559,17 @@ declare namespace ts {
|
||||
interface JSDocClassTag extends JSDocTag {
|
||||
kind: SyntaxKind.JSDocClassTag;
|
||||
}
|
||||
interface JSDocEnumTag extends JSDocTag {
|
||||
kind: SyntaxKind.JSDocEnumTag;
|
||||
typeExpression?: JSDocTypeExpression;
|
||||
}
|
||||
interface JSDocThisTag extends JSDocTag {
|
||||
kind: SyntaxKind.JSDocThisTag;
|
||||
typeExpression?: JSDocTypeExpression;
|
||||
}
|
||||
interface JSDocTemplateTag extends JSDocTag {
|
||||
kind: SyntaxKind.JSDocTemplateTag;
|
||||
constraint: TypeNode | undefined;
|
||||
typeParameters: NodeArray<TypeParameterDeclaration>;
|
||||
}
|
||||
interface JSDocReturnTag extends JSDocTag {
|
||||
@@ -1902,7 +1910,7 @@ declare namespace ts {
|
||||
*/
|
||||
getExportSymbolOfSymbol(symbol: Symbol): Symbol;
|
||||
getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol | undefined;
|
||||
getTypeAtLocation(node: Node): Type | undefined;
|
||||
getTypeAtLocation(node: Node): Type;
|
||||
getTypeFromTypeNode(node: TypeNode): Type;
|
||||
signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string;
|
||||
typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string;
|
||||
@@ -1934,9 +1942,6 @@ declare namespace ts {
|
||||
getAmbientModules(): Symbol[];
|
||||
tryGetMemberInModuleExports(memberName: string, moduleSymbol: Symbol): Symbol | undefined;
|
||||
getApparentType(type: Type): Type;
|
||||
getSuggestionForNonexistentProperty(name: Identifier | string, containingType: Type): string | undefined;
|
||||
getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string | undefined;
|
||||
getSuggestionForNonexistentModule(node: Identifier, target: Symbol): string | undefined;
|
||||
getBaseConstraintOfType(type: Type): Type | undefined;
|
||||
getDefaultFromTypeParameter(type: Type): Type | undefined;
|
||||
/**
|
||||
@@ -2052,6 +2057,7 @@ declare namespace ts {
|
||||
Optional = 16777216,
|
||||
Transient = 33554432,
|
||||
JSContainer = 67108864,
|
||||
ModuleExports = 134217728,
|
||||
Enum = 384,
|
||||
Variable = 3,
|
||||
Value = 67216319,
|
||||
@@ -2079,8 +2085,6 @@ declare namespace ts {
|
||||
AliasExcludes = 2097152,
|
||||
ModuleMember = 2623475,
|
||||
ExportHasLocal = 944,
|
||||
HasExports = 1955,
|
||||
HasMembers = 6240,
|
||||
BlockScoped = 418,
|
||||
PropertyOrAccessor = 98308,
|
||||
ClassMember = 106500
|
||||
@@ -2110,7 +2114,8 @@ declare namespace ts {
|
||||
Computed = "__computed",
|
||||
Resolving = "__resolving__",
|
||||
ExportEquals = "export=",
|
||||
Default = "default"
|
||||
Default = "default",
|
||||
This = "this"
|
||||
}
|
||||
/**
|
||||
* This represents a string whose leading underscore have been escaped by adding extra leading underscores.
|
||||
@@ -2228,6 +2233,7 @@ declare namespace ts {
|
||||
ReverseMapped = 2048,
|
||||
JsxAttributes = 4096,
|
||||
MarkerType = 8192,
|
||||
JSLiteral = 16384,
|
||||
ClassOrInterface = 3
|
||||
}
|
||||
interface ObjectType extends Type {
|
||||
@@ -2486,6 +2492,7 @@ declare namespace ts {
|
||||
strictFunctionTypes?: boolean;
|
||||
strictNullChecks?: boolean;
|
||||
strictPropertyInitialization?: boolean;
|
||||
stripInternal?: boolean;
|
||||
suppressExcessPropertyErrors?: boolean;
|
||||
suppressImplicitAnyIndexErrors?: boolean;
|
||||
target?: ScriptTarget;
|
||||
@@ -2587,7 +2594,7 @@ declare namespace ts {
|
||||
}
|
||||
interface UpToDateHost {
|
||||
fileExists(fileName: string): boolean;
|
||||
getModifiedTime(fileName: string): Date;
|
||||
getModifiedTime(fileName: string): Date | undefined;
|
||||
getUnchangedTime?(fileName: string): Date | undefined;
|
||||
getLastStatus?(fileName: string): UpToDateStatus | undefined;
|
||||
setLastStatus?(fileName: string, status: UpToDateStatus): void;
|
||||
@@ -2691,7 +2698,7 @@ declare namespace ts {
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
getEnvironmentVariable?(name: string): string | undefined;
|
||||
createHash?(data: string): string;
|
||||
getModifiedTime?(fileName: string): Date;
|
||||
getModifiedTime?(fileName: string): Date | undefined;
|
||||
setModifiedTime?(fileName: string, date: Date): void;
|
||||
deleteFile?(fileName: string): void;
|
||||
}
|
||||
@@ -3028,7 +3035,7 @@ declare namespace ts {
|
||||
getCurrentDirectory(): string;
|
||||
getDirectories(path: string): string[];
|
||||
readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];
|
||||
getModifiedTime?(path: string): Date;
|
||||
getModifiedTime?(path: string): Date | undefined;
|
||||
setModifiedTime?(path: string, time: Date): void;
|
||||
deleteFile?(path: string): void;
|
||||
/**
|
||||
@@ -3186,6 +3193,8 @@ declare namespace ts {
|
||||
* @returns The original parse tree node if found; otherwise, undefined.
|
||||
*/
|
||||
function getParseTreeNode<T extends Node>(node: Node | undefined, nodeTest?: (node: Node) => node is T): T | undefined;
|
||||
/** Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__' */
|
||||
function escapeLeadingUnderscores(identifier: string): __String;
|
||||
/**
|
||||
* Remove extra underscore from escaped identifier text content.
|
||||
*
|
||||
@@ -3222,6 +3231,8 @@ declare namespace ts {
|
||||
function getJSDocAugmentsTag(node: Node): JSDocAugmentsTag | undefined;
|
||||
/** Gets the JSDoc class tag for the node if present */
|
||||
function getJSDocClassTag(node: Node): JSDocClassTag | undefined;
|
||||
/** Gets the JSDoc enum tag for the node if present */
|
||||
function getJSDocEnumTag(node: Node): JSDocEnumTag | undefined;
|
||||
/** Gets the JSDoc this tag for the node if present */
|
||||
function getJSDocThisTag(node: Node): JSDocThisTag | undefined;
|
||||
/** Gets the JSDoc return tag for the node if present */
|
||||
@@ -3243,16 +3254,22 @@ declare namespace ts {
|
||||
*/
|
||||
function getJSDocType(node: Node): TypeNode | undefined;
|
||||
/**
|
||||
* Gets the return type node for the node if provided via JSDoc's return tag.
|
||||
* Gets the return type node for the node if provided via JSDoc return tag or type tag.
|
||||
*
|
||||
* @remarks `getJSDocReturnTag` just gets the whole JSDoc tag. This function
|
||||
* gets the type from inside the braces.
|
||||
* gets the type from inside the braces, after the fat arrow, etc.
|
||||
*/
|
||||
function getJSDocReturnType(node: Node): TypeNode | undefined;
|
||||
/** Get all JSDoc tags related to a node, including those on parent nodes. */
|
||||
function getJSDocTags(node: Node): ReadonlyArray<JSDocTag>;
|
||||
/** Gets all JSDoc tags of a specified kind, or undefined if not present. */
|
||||
function getAllJSDocTagsOfKind(node: Node, kind: SyntaxKind): ReadonlyArray<JSDocTag>;
|
||||
/**
|
||||
* Gets the effective type parameters. If the node was parsed in a
|
||||
* JavaScript file, gets the type parameters from the `@template` tag from JSDoc.
|
||||
*/
|
||||
function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters): ReadonlyArray<TypeParameterDeclaration>;
|
||||
function getEffectiveConstraintOfTypeParameter(node: TypeParameterDeclaration): TypeNode | undefined;
|
||||
}
|
||||
declare namespace ts {
|
||||
function isNumericLiteral(node: Node): node is NumericLiteral;
|
||||
@@ -3409,6 +3426,7 @@ declare namespace ts {
|
||||
function isJSDoc(node: Node): node is JSDoc;
|
||||
function isJSDocAugmentsTag(node: Node): node is JSDocAugmentsTag;
|
||||
function isJSDocClassTag(node: Node): node is JSDocClassTag;
|
||||
function isJSDocEnumTag(node: Node): node is JSDocEnumTag;
|
||||
function isJSDocThisTag(node: Node): node is JSDocThisTag;
|
||||
function isJSDocParameterTag(node: Node): node is JSDocParameterTag;
|
||||
function isJSDocReturnTag(node: Node): node is JSDocReturnTag;
|
||||
@@ -3732,9 +3750,9 @@ declare namespace ts {
|
||||
function updateCall(node: CallExpression, expression: Expression, typeArguments: ReadonlyArray<TypeNode> | undefined, argumentsArray: ReadonlyArray<Expression>): CallExpression;
|
||||
function createNew(expression: Expression, typeArguments: ReadonlyArray<TypeNode> | undefined, argumentsArray: ReadonlyArray<Expression> | undefined): NewExpression;
|
||||
function updateNew(node: NewExpression, expression: Expression, typeArguments: ReadonlyArray<TypeNode> | undefined, argumentsArray: ReadonlyArray<Expression> | undefined): NewExpression;
|
||||
function createTaggedTemplate(tag: Expression, template: TemplateLiteral): TaggedTemplateExpression;
|
||||
/** @deprecated */ function createTaggedTemplate(tag: Expression, template: TemplateLiteral): TaggedTemplateExpression;
|
||||
function createTaggedTemplate(tag: Expression, typeArguments: ReadonlyArray<TypeNode> | undefined, template: TemplateLiteral): TaggedTemplateExpression;
|
||||
function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral): TaggedTemplateExpression;
|
||||
/** @deprecated */ function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral): TaggedTemplateExpression;
|
||||
function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: ReadonlyArray<TypeNode> | undefined, template: TemplateLiteral): TaggedTemplateExpression;
|
||||
function createTypeAssertion(type: TypeNode, expression: Expression): TypeAssertion;
|
||||
function updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression): TypeAssertion;
|
||||
@@ -3743,7 +3761,6 @@ declare namespace ts {
|
||||
function createFunctionExpression(modifiers: ReadonlyArray<Modifier> | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined, parameters: ReadonlyArray<ParameterDeclaration> | undefined, type: TypeNode | undefined, body: Block): FunctionExpression;
|
||||
function updateFunctionExpression(node: FunctionExpression, modifiers: ReadonlyArray<Modifier> | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined, parameters: ReadonlyArray<ParameterDeclaration>, type: TypeNode | undefined, body: Block): FunctionExpression;
|
||||
function createArrowFunction(modifiers: ReadonlyArray<Modifier> | undefined, typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined, parameters: ReadonlyArray<ParameterDeclaration>, type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken | undefined, body: ConciseBody): ArrowFunction;
|
||||
/** @deprecated */ function updateArrowFunction(node: ArrowFunction, modifiers: ReadonlyArray<Modifier> | undefined, typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined, parameters: ReadonlyArray<ParameterDeclaration>, type: TypeNode | undefined, body: ConciseBody): ArrowFunction;
|
||||
function updateArrowFunction(node: ArrowFunction, modifiers: ReadonlyArray<Modifier> | undefined, typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined, parameters: ReadonlyArray<ParameterDeclaration>, type: TypeNode | undefined, equalsGreaterThanToken: Token<SyntaxKind.EqualsGreaterThanToken>, body: ConciseBody): ArrowFunction;
|
||||
function createDelete(expression: Expression): DeleteExpression;
|
||||
function updateDelete(node: DeleteExpression, expression: Expression): DeleteExpression;
|
||||
@@ -3759,9 +3776,8 @@ declare namespace ts {
|
||||
function updatePostfix(node: PostfixUnaryExpression, operand: Expression): PostfixUnaryExpression;
|
||||
function createBinary(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression): BinaryExpression;
|
||||
function updateBinary(node: BinaryExpression, left: Expression, right: Expression, operator?: BinaryOperator | BinaryOperatorToken): BinaryExpression;
|
||||
function createConditional(condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression;
|
||||
/** @deprecated */ function createConditional(condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression;
|
||||
function createConditional(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression;
|
||||
/** @deprecated */ function updateConditional(node: ConditionalExpression, condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression;
|
||||
function updateConditional(node: ConditionalExpression, condition: Expression, questionToken: Token<SyntaxKind.QuestionToken>, whenTrue: Expression, colonToken: Token<SyntaxKind.ColonToken>, whenFalse: Expression): ConditionalExpression;
|
||||
function createTemplateExpression(head: TemplateHead, templateSpans: ReadonlyArray<TemplateSpan>): TemplateExpression;
|
||||
function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: ReadonlyArray<TemplateSpan>): TemplateExpression;
|
||||
@@ -4155,10 +4171,14 @@ declare namespace ts {
|
||||
* @returns A 'Program' object.
|
||||
*/
|
||||
function createProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): Program;
|
||||
interface ResolveProjectReferencePathHost {
|
||||
fileExists(fileName: string): boolean;
|
||||
}
|
||||
/**
|
||||
* Returns the target config filename of a project reference
|
||||
* Returns the target config filename of a project reference.
|
||||
* Note: The file might not exist.
|
||||
*/
|
||||
function resolveProjectReferencePath(host: CompilerHost | UpToDateHost, ref: ProjectReference): ResolvedConfigFileName;
|
||||
function resolveProjectReferencePath(host: ResolveProjectReferencePathHost, ref: ProjectReference): ResolvedConfigFileName;
|
||||
}
|
||||
declare namespace ts {
|
||||
interface EmitOutput {
|
||||
@@ -4577,6 +4597,80 @@ declare namespace ts {
|
||||
function getAllProjectOutputs(project: ParsedCommandLine): ReadonlyArray<string>;
|
||||
function formatUpToDateStatus<T>(configFileName: string, status: UpToDateStatus, relName: (fileName: string) => string, formatMessage: (message: DiagnosticMessage, ...args: string[]) => T): T | undefined;
|
||||
}
|
||||
declare namespace ts.server {
|
||||
type ActionSet = "action::set";
|
||||
type ActionInvalidate = "action::invalidate";
|
||||
type ActionPackageInstalled = "action::packageInstalled";
|
||||
type EventTypesRegistry = "event::typesRegistry";
|
||||
type EventBeginInstallTypes = "event::beginInstallTypes";
|
||||
type EventEndInstallTypes = "event::endInstallTypes";
|
||||
type EventInitializationFailed = "event::initializationFailed";
|
||||
interface SortedReadonlyArray<T> extends ReadonlyArray<T> {
|
||||
" __sortedArrayBrand": any;
|
||||
}
|
||||
interface TypingInstallerResponse {
|
||||
readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | ActionPackageInstalled | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed;
|
||||
}
|
||||
interface TypingInstallerRequestWithProjectName {
|
||||
readonly projectName: string;
|
||||
}
|
||||
interface DiscoverTypings extends TypingInstallerRequestWithProjectName {
|
||||
readonly fileNames: string[];
|
||||
readonly projectRootPath: Path;
|
||||
readonly compilerOptions: CompilerOptions;
|
||||
readonly typeAcquisition: TypeAcquisition;
|
||||
readonly unresolvedImports: SortedReadonlyArray<string>;
|
||||
readonly cachePath?: string;
|
||||
readonly kind: "discover";
|
||||
}
|
||||
interface CloseProject extends TypingInstallerRequestWithProjectName {
|
||||
readonly kind: "closeProject";
|
||||
}
|
||||
interface TypesRegistryRequest {
|
||||
readonly kind: "typesRegistry";
|
||||
}
|
||||
interface InstallPackageRequest extends TypingInstallerRequestWithProjectName {
|
||||
readonly kind: "installPackage";
|
||||
readonly fileName: Path;
|
||||
readonly packageName: string;
|
||||
readonly projectRootPath: Path;
|
||||
}
|
||||
interface PackageInstalledResponse extends ProjectResponse {
|
||||
readonly kind: ActionPackageInstalled;
|
||||
readonly success: boolean;
|
||||
readonly message: string;
|
||||
}
|
||||
interface InitializationFailedResponse extends TypingInstallerResponse {
|
||||
readonly kind: EventInitializationFailed;
|
||||
readonly message: string;
|
||||
}
|
||||
interface ProjectResponse extends TypingInstallerResponse {
|
||||
readonly projectName: string;
|
||||
}
|
||||
interface InvalidateCachedTypings extends ProjectResponse {
|
||||
readonly kind: ActionInvalidate;
|
||||
}
|
||||
interface InstallTypes extends ProjectResponse {
|
||||
readonly kind: EventBeginInstallTypes | EventEndInstallTypes;
|
||||
readonly eventId: number;
|
||||
readonly typingsInstallerVersion: string;
|
||||
readonly packagesToInstall: ReadonlyArray<string>;
|
||||
}
|
||||
interface BeginInstallTypes extends InstallTypes {
|
||||
readonly kind: EventBeginInstallTypes;
|
||||
}
|
||||
interface EndInstallTypes extends InstallTypes {
|
||||
readonly kind: EventEndInstallTypes;
|
||||
readonly installSuccess: boolean;
|
||||
}
|
||||
interface SetTypings extends ProjectResponse {
|
||||
readonly typeAcquisition: TypeAcquisition;
|
||||
readonly compilerOptions: CompilerOptions;
|
||||
readonly typings: string[];
|
||||
readonly unresolvedImports: SortedReadonlyArray<string>;
|
||||
readonly kind: ActionSet;
|
||||
}
|
||||
}
|
||||
declare namespace ts {
|
||||
interface Node {
|
||||
getSourceFile(): SourceFile;
|
||||
@@ -5581,5 +5675,5 @@ declare namespace ts {
|
||||
*/
|
||||
function transform<T extends Node>(source: T | T[], transformers: TransformerFactory<T>[], compilerOptions?: CompilerOptions): TransformationResult<T>;
|
||||
}
|
||||
//# sourceMappingURL=typescriptServices.d.ts.map
|
||||
export = ts
|
||||
|
||||
export = ts;
|
||||
+4470
-2653
File diff suppressed because it is too large
Load Diff
Vendored
+136
-43
@@ -13,9 +13,8 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
declare namespace ts {
|
||||
const versionMajorMinor = "3.0";
|
||||
const versionMajorMinor = "3.1";
|
||||
/** The version of the TypeScript compiler release */
|
||||
const version: string;
|
||||
}
|
||||
@@ -369,20 +368,21 @@ declare namespace ts {
|
||||
JSDocAugmentsTag = 293,
|
||||
JSDocClassTag = 294,
|
||||
JSDocCallbackTag = 295,
|
||||
JSDocParameterTag = 296,
|
||||
JSDocReturnTag = 297,
|
||||
JSDocThisTag = 298,
|
||||
JSDocTypeTag = 299,
|
||||
JSDocTemplateTag = 300,
|
||||
JSDocTypedefTag = 301,
|
||||
JSDocPropertyTag = 302,
|
||||
SyntaxList = 303,
|
||||
NotEmittedStatement = 304,
|
||||
PartiallyEmittedExpression = 305,
|
||||
CommaListExpression = 306,
|
||||
MergeDeclarationMarker = 307,
|
||||
EndOfDeclarationMarker = 308,
|
||||
Count = 309,
|
||||
JSDocEnumTag = 296,
|
||||
JSDocParameterTag = 297,
|
||||
JSDocReturnTag = 298,
|
||||
JSDocThisTag = 299,
|
||||
JSDocTypeTag = 300,
|
||||
JSDocTemplateTag = 301,
|
||||
JSDocTypedefTag = 302,
|
||||
JSDocPropertyTag = 303,
|
||||
SyntaxList = 304,
|
||||
NotEmittedStatement = 305,
|
||||
PartiallyEmittedExpression = 306,
|
||||
CommaListExpression = 307,
|
||||
MergeDeclarationMarker = 308,
|
||||
EndOfDeclarationMarker = 309,
|
||||
Count = 310,
|
||||
FirstAssignment = 58,
|
||||
LastAssignment = 70,
|
||||
FirstCompoundAssignment = 59,
|
||||
@@ -409,9 +409,9 @@ declare namespace ts {
|
||||
LastBinaryOperator = 70,
|
||||
FirstNode = 146,
|
||||
FirstJSDocNode = 281,
|
||||
LastJSDocNode = 302,
|
||||
LastJSDocNode = 303,
|
||||
FirstJSDocTagNode = 292,
|
||||
LastJSDocTagNode = 302
|
||||
LastJSDocTagNode = 303
|
||||
}
|
||||
enum NodeFlags {
|
||||
None = 0,
|
||||
@@ -480,7 +480,7 @@ declare namespace ts {
|
||||
}
|
||||
interface JSDocContainer {
|
||||
}
|
||||
type HasJSDoc = ParameterDeclaration | CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | PropertySignature | ArrowFunction | ParenthesizedExpression | SpreadAssignment | ShorthandPropertyAssignment | PropertyAssignment | FunctionExpression | LabeledStatement | ExpressionStatement | VariableStatement | FunctionDeclaration | ConstructorDeclaration | MethodDeclaration | PropertyDeclaration | AccessorDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | EnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | EndOfFileToken;
|
||||
type HasJSDoc = ParameterDeclaration | CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | PropertySignature | ArrowFunction | ParenthesizedExpression | SpreadAssignment | ShorthandPropertyAssignment | PropertyAssignment | FunctionExpression | LabeledStatement | ExpressionStatement | VariableStatement | FunctionDeclaration | ConstructorDeclaration | MethodDeclaration | PropertyDeclaration | AccessorDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | EnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | ExportDeclaration | EndOfFileToken;
|
||||
type HasType = SignatureDeclaration | VariableDeclaration | ParameterDeclaration | PropertySignature | PropertyDeclaration | TypePredicateNode | ParenthesizedTypeNode | TypeOperatorNode | MappedTypeNode | AssertionExpression | TypeAliasDeclaration | JSDocTypeExpression | JSDocNonNullableType | JSDocNullableType | JSDocOptionalType | JSDocVariadicType;
|
||||
type HasInitializer = HasExpressionInitializer | ForStatement | ForInStatement | ForOfStatement | JsxAttribute;
|
||||
type HasExpressionInitializer = VariableDeclaration | ParameterDeclaration | BindingElement | PropertySignature | PropertyDeclaration | PropertyAssignment | EnumMember;
|
||||
@@ -546,8 +546,9 @@ declare namespace ts {
|
||||
}
|
||||
interface TypeParameterDeclaration extends NamedDeclaration {
|
||||
kind: SyntaxKind.TypeParameter;
|
||||
parent: DeclarationWithTypeParameters | InferTypeNode;
|
||||
parent: DeclarationWithTypeParameterChildren | InferTypeNode;
|
||||
name: Identifier;
|
||||
/** Note: Consider calling `getEffectiveConstraintOfTypeParameter` */
|
||||
constraint?: TypeNode;
|
||||
default?: TypeNode;
|
||||
expression?: Expression;
|
||||
@@ -617,6 +618,7 @@ declare namespace ts {
|
||||
_objectLiteralBrandBrand: any;
|
||||
name?: PropertyName;
|
||||
}
|
||||
/** Unlike ObjectLiteralElement, excludes JSXAttribute and JSXSpreadAttribute. */
|
||||
type ObjectLiteralElementLike = PropertyAssignment | ShorthandPropertyAssignment | SpreadAssignment | MethodDeclaration | AccessorDeclaration;
|
||||
interface PropertyAssignment extends ObjectLiteralElement, JSDocContainer {
|
||||
parent: ObjectLiteralExpression;
|
||||
@@ -750,7 +752,7 @@ declare namespace ts {
|
||||
}
|
||||
interface TypePredicateNode extends TypeNode {
|
||||
kind: SyntaxKind.TypePredicate;
|
||||
parent: SignatureDeclaration;
|
||||
parent: SignatureDeclaration | JSDocTypeExpression;
|
||||
parameterName: Identifier | ThisTypeNode;
|
||||
type: TypeNode;
|
||||
}
|
||||
@@ -1318,7 +1320,8 @@ declare namespace ts {
|
||||
block: Block;
|
||||
}
|
||||
type ObjectTypeDeclaration = ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode;
|
||||
type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature;
|
||||
type DeclarationWithTypeParameters = DeclarationWithTypeParameterChildren | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature;
|
||||
type DeclarationWithTypeParameterChildren = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag;
|
||||
interface ClassLikeDeclarationBase extends NamedDeclaration, JSDocContainer {
|
||||
kind: SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression;
|
||||
name?: Identifier;
|
||||
@@ -1437,7 +1440,7 @@ declare namespace ts {
|
||||
kind: SyntaxKind.NamespaceExportDeclaration;
|
||||
name: Identifier;
|
||||
}
|
||||
interface ExportDeclaration extends DeclarationStatement {
|
||||
interface ExportDeclaration extends DeclarationStatement, JSDocContainer {
|
||||
kind: SyntaxKind.ExportDeclaration;
|
||||
parent: SourceFile | ModuleBlock;
|
||||
/** Will not be assigned in the case of `export * from "foo";` */
|
||||
@@ -1556,12 +1559,17 @@ declare namespace ts {
|
||||
interface JSDocClassTag extends JSDocTag {
|
||||
kind: SyntaxKind.JSDocClassTag;
|
||||
}
|
||||
interface JSDocEnumTag extends JSDocTag {
|
||||
kind: SyntaxKind.JSDocEnumTag;
|
||||
typeExpression?: JSDocTypeExpression;
|
||||
}
|
||||
interface JSDocThisTag extends JSDocTag {
|
||||
kind: SyntaxKind.JSDocThisTag;
|
||||
typeExpression?: JSDocTypeExpression;
|
||||
}
|
||||
interface JSDocTemplateTag extends JSDocTag {
|
||||
kind: SyntaxKind.JSDocTemplateTag;
|
||||
constraint: TypeNode | undefined;
|
||||
typeParameters: NodeArray<TypeParameterDeclaration>;
|
||||
}
|
||||
interface JSDocReturnTag extends JSDocTag {
|
||||
@@ -1902,7 +1910,7 @@ declare namespace ts {
|
||||
*/
|
||||
getExportSymbolOfSymbol(symbol: Symbol): Symbol;
|
||||
getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol | undefined;
|
||||
getTypeAtLocation(node: Node): Type | undefined;
|
||||
getTypeAtLocation(node: Node): Type;
|
||||
getTypeFromTypeNode(node: TypeNode): Type;
|
||||
signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string;
|
||||
typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string;
|
||||
@@ -1934,9 +1942,6 @@ declare namespace ts {
|
||||
getAmbientModules(): Symbol[];
|
||||
tryGetMemberInModuleExports(memberName: string, moduleSymbol: Symbol): Symbol | undefined;
|
||||
getApparentType(type: Type): Type;
|
||||
getSuggestionForNonexistentProperty(name: Identifier | string, containingType: Type): string | undefined;
|
||||
getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string | undefined;
|
||||
getSuggestionForNonexistentModule(node: Identifier, target: Symbol): string | undefined;
|
||||
getBaseConstraintOfType(type: Type): Type | undefined;
|
||||
getDefaultFromTypeParameter(type: Type): Type | undefined;
|
||||
/**
|
||||
@@ -2052,6 +2057,7 @@ declare namespace ts {
|
||||
Optional = 16777216,
|
||||
Transient = 33554432,
|
||||
JSContainer = 67108864,
|
||||
ModuleExports = 134217728,
|
||||
Enum = 384,
|
||||
Variable = 3,
|
||||
Value = 67216319,
|
||||
@@ -2079,8 +2085,6 @@ declare namespace ts {
|
||||
AliasExcludes = 2097152,
|
||||
ModuleMember = 2623475,
|
||||
ExportHasLocal = 944,
|
||||
HasExports = 1955,
|
||||
HasMembers = 6240,
|
||||
BlockScoped = 418,
|
||||
PropertyOrAccessor = 98308,
|
||||
ClassMember = 106500
|
||||
@@ -2110,7 +2114,8 @@ declare namespace ts {
|
||||
Computed = "__computed",
|
||||
Resolving = "__resolving__",
|
||||
ExportEquals = "export=",
|
||||
Default = "default"
|
||||
Default = "default",
|
||||
This = "this"
|
||||
}
|
||||
/**
|
||||
* This represents a string whose leading underscore have been escaped by adding extra leading underscores.
|
||||
@@ -2228,6 +2233,7 @@ declare namespace ts {
|
||||
ReverseMapped = 2048,
|
||||
JsxAttributes = 4096,
|
||||
MarkerType = 8192,
|
||||
JSLiteral = 16384,
|
||||
ClassOrInterface = 3
|
||||
}
|
||||
interface ObjectType extends Type {
|
||||
@@ -2486,6 +2492,7 @@ declare namespace ts {
|
||||
strictFunctionTypes?: boolean;
|
||||
strictNullChecks?: boolean;
|
||||
strictPropertyInitialization?: boolean;
|
||||
stripInternal?: boolean;
|
||||
suppressExcessPropertyErrors?: boolean;
|
||||
suppressImplicitAnyIndexErrors?: boolean;
|
||||
target?: ScriptTarget;
|
||||
@@ -2587,7 +2594,7 @@ declare namespace ts {
|
||||
}
|
||||
interface UpToDateHost {
|
||||
fileExists(fileName: string): boolean;
|
||||
getModifiedTime(fileName: string): Date;
|
||||
getModifiedTime(fileName: string): Date | undefined;
|
||||
getUnchangedTime?(fileName: string): Date | undefined;
|
||||
getLastStatus?(fileName: string): UpToDateStatus | undefined;
|
||||
setLastStatus?(fileName: string, status: UpToDateStatus): void;
|
||||
@@ -2691,7 +2698,7 @@ declare namespace ts {
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
getEnvironmentVariable?(name: string): string | undefined;
|
||||
createHash?(data: string): string;
|
||||
getModifiedTime?(fileName: string): Date;
|
||||
getModifiedTime?(fileName: string): Date | undefined;
|
||||
setModifiedTime?(fileName: string, date: Date): void;
|
||||
deleteFile?(fileName: string): void;
|
||||
}
|
||||
@@ -3028,7 +3035,7 @@ declare namespace ts {
|
||||
getCurrentDirectory(): string;
|
||||
getDirectories(path: string): string[];
|
||||
readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];
|
||||
getModifiedTime?(path: string): Date;
|
||||
getModifiedTime?(path: string): Date | undefined;
|
||||
setModifiedTime?(path: string, time: Date): void;
|
||||
deleteFile?(path: string): void;
|
||||
/**
|
||||
@@ -3186,6 +3193,8 @@ declare namespace ts {
|
||||
* @returns The original parse tree node if found; otherwise, undefined.
|
||||
*/
|
||||
function getParseTreeNode<T extends Node>(node: Node | undefined, nodeTest?: (node: Node) => node is T): T | undefined;
|
||||
/** Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__' */
|
||||
function escapeLeadingUnderscores(identifier: string): __String;
|
||||
/**
|
||||
* Remove extra underscore from escaped identifier text content.
|
||||
*
|
||||
@@ -3222,6 +3231,8 @@ declare namespace ts {
|
||||
function getJSDocAugmentsTag(node: Node): JSDocAugmentsTag | undefined;
|
||||
/** Gets the JSDoc class tag for the node if present */
|
||||
function getJSDocClassTag(node: Node): JSDocClassTag | undefined;
|
||||
/** Gets the JSDoc enum tag for the node if present */
|
||||
function getJSDocEnumTag(node: Node): JSDocEnumTag | undefined;
|
||||
/** Gets the JSDoc this tag for the node if present */
|
||||
function getJSDocThisTag(node: Node): JSDocThisTag | undefined;
|
||||
/** Gets the JSDoc return tag for the node if present */
|
||||
@@ -3243,16 +3254,22 @@ declare namespace ts {
|
||||
*/
|
||||
function getJSDocType(node: Node): TypeNode | undefined;
|
||||
/**
|
||||
* Gets the return type node for the node if provided via JSDoc's return tag.
|
||||
* Gets the return type node for the node if provided via JSDoc return tag or type tag.
|
||||
*
|
||||
* @remarks `getJSDocReturnTag` just gets the whole JSDoc tag. This function
|
||||
* gets the type from inside the braces.
|
||||
* gets the type from inside the braces, after the fat arrow, etc.
|
||||
*/
|
||||
function getJSDocReturnType(node: Node): TypeNode | undefined;
|
||||
/** Get all JSDoc tags related to a node, including those on parent nodes. */
|
||||
function getJSDocTags(node: Node): ReadonlyArray<JSDocTag>;
|
||||
/** Gets all JSDoc tags of a specified kind, or undefined if not present. */
|
||||
function getAllJSDocTagsOfKind(node: Node, kind: SyntaxKind): ReadonlyArray<JSDocTag>;
|
||||
/**
|
||||
* Gets the effective type parameters. If the node was parsed in a
|
||||
* JavaScript file, gets the type parameters from the `@template` tag from JSDoc.
|
||||
*/
|
||||
function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters): ReadonlyArray<TypeParameterDeclaration>;
|
||||
function getEffectiveConstraintOfTypeParameter(node: TypeParameterDeclaration): TypeNode | undefined;
|
||||
}
|
||||
declare namespace ts {
|
||||
function isNumericLiteral(node: Node): node is NumericLiteral;
|
||||
@@ -3409,6 +3426,7 @@ declare namespace ts {
|
||||
function isJSDoc(node: Node): node is JSDoc;
|
||||
function isJSDocAugmentsTag(node: Node): node is JSDocAugmentsTag;
|
||||
function isJSDocClassTag(node: Node): node is JSDocClassTag;
|
||||
function isJSDocEnumTag(node: Node): node is JSDocEnumTag;
|
||||
function isJSDocThisTag(node: Node): node is JSDocThisTag;
|
||||
function isJSDocParameterTag(node: Node): node is JSDocParameterTag;
|
||||
function isJSDocReturnTag(node: Node): node is JSDocReturnTag;
|
||||
@@ -3732,9 +3750,9 @@ declare namespace ts {
|
||||
function updateCall(node: CallExpression, expression: Expression, typeArguments: ReadonlyArray<TypeNode> | undefined, argumentsArray: ReadonlyArray<Expression>): CallExpression;
|
||||
function createNew(expression: Expression, typeArguments: ReadonlyArray<TypeNode> | undefined, argumentsArray: ReadonlyArray<Expression> | undefined): NewExpression;
|
||||
function updateNew(node: NewExpression, expression: Expression, typeArguments: ReadonlyArray<TypeNode> | undefined, argumentsArray: ReadonlyArray<Expression> | undefined): NewExpression;
|
||||
function createTaggedTemplate(tag: Expression, template: TemplateLiteral): TaggedTemplateExpression;
|
||||
/** @deprecated */ function createTaggedTemplate(tag: Expression, template: TemplateLiteral): TaggedTemplateExpression;
|
||||
function createTaggedTemplate(tag: Expression, typeArguments: ReadonlyArray<TypeNode> | undefined, template: TemplateLiteral): TaggedTemplateExpression;
|
||||
function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral): TaggedTemplateExpression;
|
||||
/** @deprecated */ function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral): TaggedTemplateExpression;
|
||||
function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: ReadonlyArray<TypeNode> | undefined, template: TemplateLiteral): TaggedTemplateExpression;
|
||||
function createTypeAssertion(type: TypeNode, expression: Expression): TypeAssertion;
|
||||
function updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression): TypeAssertion;
|
||||
@@ -3743,7 +3761,6 @@ declare namespace ts {
|
||||
function createFunctionExpression(modifiers: ReadonlyArray<Modifier> | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined, parameters: ReadonlyArray<ParameterDeclaration> | undefined, type: TypeNode | undefined, body: Block): FunctionExpression;
|
||||
function updateFunctionExpression(node: FunctionExpression, modifiers: ReadonlyArray<Modifier> | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined, parameters: ReadonlyArray<ParameterDeclaration>, type: TypeNode | undefined, body: Block): FunctionExpression;
|
||||
function createArrowFunction(modifiers: ReadonlyArray<Modifier> | undefined, typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined, parameters: ReadonlyArray<ParameterDeclaration>, type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken | undefined, body: ConciseBody): ArrowFunction;
|
||||
/** @deprecated */ function updateArrowFunction(node: ArrowFunction, modifiers: ReadonlyArray<Modifier> | undefined, typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined, parameters: ReadonlyArray<ParameterDeclaration>, type: TypeNode | undefined, body: ConciseBody): ArrowFunction;
|
||||
function updateArrowFunction(node: ArrowFunction, modifiers: ReadonlyArray<Modifier> | undefined, typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined, parameters: ReadonlyArray<ParameterDeclaration>, type: TypeNode | undefined, equalsGreaterThanToken: Token<SyntaxKind.EqualsGreaterThanToken>, body: ConciseBody): ArrowFunction;
|
||||
function createDelete(expression: Expression): DeleteExpression;
|
||||
function updateDelete(node: DeleteExpression, expression: Expression): DeleteExpression;
|
||||
@@ -3759,9 +3776,8 @@ declare namespace ts {
|
||||
function updatePostfix(node: PostfixUnaryExpression, operand: Expression): PostfixUnaryExpression;
|
||||
function createBinary(left: Expression, operator: BinaryOperator | BinaryOperatorToken, right: Expression): BinaryExpression;
|
||||
function updateBinary(node: BinaryExpression, left: Expression, right: Expression, operator?: BinaryOperator | BinaryOperatorToken): BinaryExpression;
|
||||
function createConditional(condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression;
|
||||
/** @deprecated */ function createConditional(condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression;
|
||||
function createConditional(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression;
|
||||
/** @deprecated */ function updateConditional(node: ConditionalExpression, condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression;
|
||||
function updateConditional(node: ConditionalExpression, condition: Expression, questionToken: Token<SyntaxKind.QuestionToken>, whenTrue: Expression, colonToken: Token<SyntaxKind.ColonToken>, whenFalse: Expression): ConditionalExpression;
|
||||
function createTemplateExpression(head: TemplateHead, templateSpans: ReadonlyArray<TemplateSpan>): TemplateExpression;
|
||||
function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: ReadonlyArray<TemplateSpan>): TemplateExpression;
|
||||
@@ -4155,10 +4171,14 @@ declare namespace ts {
|
||||
* @returns A 'Program' object.
|
||||
*/
|
||||
function createProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): Program;
|
||||
interface ResolveProjectReferencePathHost {
|
||||
fileExists(fileName: string): boolean;
|
||||
}
|
||||
/**
|
||||
* Returns the target config filename of a project reference
|
||||
* Returns the target config filename of a project reference.
|
||||
* Note: The file might not exist.
|
||||
*/
|
||||
function resolveProjectReferencePath(host: CompilerHost | UpToDateHost, ref: ProjectReference): ResolvedConfigFileName;
|
||||
function resolveProjectReferencePath(host: ResolveProjectReferencePathHost, ref: ProjectReference): ResolvedConfigFileName;
|
||||
}
|
||||
declare namespace ts {
|
||||
interface EmitOutput {
|
||||
@@ -4577,6 +4597,80 @@ declare namespace ts {
|
||||
function getAllProjectOutputs(project: ParsedCommandLine): ReadonlyArray<string>;
|
||||
function formatUpToDateStatus<T>(configFileName: string, status: UpToDateStatus, relName: (fileName: string) => string, formatMessage: (message: DiagnosticMessage, ...args: string[]) => T): T | undefined;
|
||||
}
|
||||
declare namespace ts.server {
|
||||
type ActionSet = "action::set";
|
||||
type ActionInvalidate = "action::invalidate";
|
||||
type ActionPackageInstalled = "action::packageInstalled";
|
||||
type EventTypesRegistry = "event::typesRegistry";
|
||||
type EventBeginInstallTypes = "event::beginInstallTypes";
|
||||
type EventEndInstallTypes = "event::endInstallTypes";
|
||||
type EventInitializationFailed = "event::initializationFailed";
|
||||
interface SortedReadonlyArray<T> extends ReadonlyArray<T> {
|
||||
" __sortedArrayBrand": any;
|
||||
}
|
||||
interface TypingInstallerResponse {
|
||||
readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | ActionPackageInstalled | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed;
|
||||
}
|
||||
interface TypingInstallerRequestWithProjectName {
|
||||
readonly projectName: string;
|
||||
}
|
||||
interface DiscoverTypings extends TypingInstallerRequestWithProjectName {
|
||||
readonly fileNames: string[];
|
||||
readonly projectRootPath: Path;
|
||||
readonly compilerOptions: CompilerOptions;
|
||||
readonly typeAcquisition: TypeAcquisition;
|
||||
readonly unresolvedImports: SortedReadonlyArray<string>;
|
||||
readonly cachePath?: string;
|
||||
readonly kind: "discover";
|
||||
}
|
||||
interface CloseProject extends TypingInstallerRequestWithProjectName {
|
||||
readonly kind: "closeProject";
|
||||
}
|
||||
interface TypesRegistryRequest {
|
||||
readonly kind: "typesRegistry";
|
||||
}
|
||||
interface InstallPackageRequest extends TypingInstallerRequestWithProjectName {
|
||||
readonly kind: "installPackage";
|
||||
readonly fileName: Path;
|
||||
readonly packageName: string;
|
||||
readonly projectRootPath: Path;
|
||||
}
|
||||
interface PackageInstalledResponse extends ProjectResponse {
|
||||
readonly kind: ActionPackageInstalled;
|
||||
readonly success: boolean;
|
||||
readonly message: string;
|
||||
}
|
||||
interface InitializationFailedResponse extends TypingInstallerResponse {
|
||||
readonly kind: EventInitializationFailed;
|
||||
readonly message: string;
|
||||
}
|
||||
interface ProjectResponse extends TypingInstallerResponse {
|
||||
readonly projectName: string;
|
||||
}
|
||||
interface InvalidateCachedTypings extends ProjectResponse {
|
||||
readonly kind: ActionInvalidate;
|
||||
}
|
||||
interface InstallTypes extends ProjectResponse {
|
||||
readonly kind: EventBeginInstallTypes | EventEndInstallTypes;
|
||||
readonly eventId: number;
|
||||
readonly typingsInstallerVersion: string;
|
||||
readonly packagesToInstall: ReadonlyArray<string>;
|
||||
}
|
||||
interface BeginInstallTypes extends InstallTypes {
|
||||
readonly kind: EventBeginInstallTypes;
|
||||
}
|
||||
interface EndInstallTypes extends InstallTypes {
|
||||
readonly kind: EventEndInstallTypes;
|
||||
readonly installSuccess: boolean;
|
||||
}
|
||||
interface SetTypings extends ProjectResponse {
|
||||
readonly typeAcquisition: TypeAcquisition;
|
||||
readonly compilerOptions: CompilerOptions;
|
||||
readonly typings: string[];
|
||||
readonly unresolvedImports: SortedReadonlyArray<string>;
|
||||
readonly kind: ActionSet;
|
||||
}
|
||||
}
|
||||
declare namespace ts {
|
||||
interface Node {
|
||||
getSourceFile(): SourceFile;
|
||||
@@ -5581,4 +5675,3 @@ declare namespace ts {
|
||||
*/
|
||||
function transform<T extends Node>(source: T | T[], transformers: TransformerFactory<T>[], compilerOptions?: CompilerOptions): TransformationResult<T>;
|
||||
}
|
||||
//# sourceMappingURL=typescriptServices.d.ts.map
|
||||
+4470
-2653
File diff suppressed because it is too large
Load Diff
+2907
-1764
File diff suppressed because it is too large
Load Diff
Generated
-6280
File diff suppressed because it is too large
Load Diff
@@ -140,7 +140,7 @@ function diagnosticFromJson(json, host) {
|
||||
category: json.category,
|
||||
code: json.code,
|
||||
source: json.source,
|
||||
relatedInformation: json.relatedInformation && json.relatedInformation.map(diagnosticRelatedInformationFromJson, host)
|
||||
relatedInformation: json.relatedInformation && json.relatedInformation.map(json => diagnosticRelatedInformationFromJson(json, host))
|
||||
});
|
||||
}
|
||||
exports.diagnosticFromJson = diagnosticFromJson;
|
||||
@@ -169,7 +169,9 @@ function diagnosticRelatedInformationFromJson(json, host) {
|
||||
file: json.file && sourceFileFromJson(json.file, host),
|
||||
start: json.start,
|
||||
length: json.length,
|
||||
messageText: json.messageText
|
||||
messageText: json.messageText,
|
||||
category: json.category,
|
||||
code: json.code
|
||||
};
|
||||
}
|
||||
exports.diagnosticRelatedInformationFromJson = diagnosticRelatedInformationFromJson;
|
||||
|
||||
@@ -55,13 +55,13 @@ function main(): void {
|
||||
function updateTsFile(tsFilePath: string, tsFileContents: string, majorMinor: string, patch: string, nightlyPatch: string): string {
|
||||
const majorMinorRgx = /export const versionMajorMinor = "(\d+\.\d+)"/;
|
||||
const majorMinorMatch = majorMinorRgx.exec(tsFileContents);
|
||||
assert(majorMinorMatch !== null, `The file seems to no longer have a string matching '${majorMinorRgx}'.`);
|
||||
assert(majorMinorMatch !== null, `The file '${tsFilePath}' seems to no longer have a string matching '${majorMinorRgx}'.`);
|
||||
const parsedMajorMinor = majorMinorMatch![1];
|
||||
assert(parsedMajorMinor === majorMinor, `versionMajorMinor does not match. ${tsFilePath}: '${parsedMajorMinor}'; package.json: '${majorMinor}'`);
|
||||
|
||||
const versionRgx = /export const version = `\$\{versionMajorMinor\}\.(\d)(-dev)?`;/;
|
||||
const patchMatch = versionRgx.exec(tsFileContents);
|
||||
assert(patchMatch !== null, "The file seems to no longer have a string matching " + versionRgx.toString());
|
||||
assert(patchMatch !== null, `The file '${tsFilePath}' seems to no longer have a string matching '${versionRgx.toString()}'.`);
|
||||
const parsedPatch = patchMatch![1];
|
||||
if (parsedPatch !== patch) {
|
||||
throw new Error(`patch does not match. ${tsFilePath}: '${parsedPatch}; package.json: '${patch}'`);
|
||||
|
||||
@@ -46,6 +46,9 @@ class FailedTestsReporter extends Mocha.reporters.Base {
|
||||
}
|
||||
|
||||
const newOptions = Object.assign({}, options, { reporterOptions: reporterOptions.reporterOptions || {} });
|
||||
if (reporterOptions.reporter === "xunit") {
|
||||
newOptions.reporterOptions.output = "TEST-results.xml";
|
||||
}
|
||||
this.reporter = new reporter(runner, newOptions);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ function padNum(number: number) {
|
||||
}
|
||||
|
||||
const userName = process.env.GH_USERNAME;
|
||||
const reviewers = ["weswigham", "sandersn", "mhegazy"]
|
||||
const reviewers = ["weswigham", "sandersn", "RyanCavanaugh"]
|
||||
const now = new Date();
|
||||
const branchName = `user-update-${now.getFullYear()}${padNum(now.getMonth())}${padNum(now.getDay())}`;
|
||||
const remoteUrl = `https://${process.argv[2]}@github.com/${userName}/TypeScript.git`;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"extends": "../tsconfig-base",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../built/local/",
|
||||
"rootDir": ".",
|
||||
"composite": false,
|
||||
"declaration": false,
|
||||
"declarationMap": false,
|
||||
|
||||
+13
-5
@@ -259,7 +259,7 @@ namespace ts {
|
||||
if (name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
const nameExpression = name.expression;
|
||||
// treat computed property names where expression is string/numeric literal as just string/numeric literal
|
||||
if (isStringOrNumericLiteral(nameExpression)) {
|
||||
if (isStringOrNumericLiteralLike(nameExpression)) {
|
||||
return escapeLeadingUnderscores(nameExpression.text);
|
||||
}
|
||||
|
||||
@@ -723,6 +723,7 @@ namespace ts {
|
||||
case SyntaxKind.Identifier:
|
||||
case SyntaxKind.ThisKeyword:
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
return isNarrowableReference(expr);
|
||||
case SyntaxKind.CallExpression:
|
||||
return hasNarrowableArgument(<CallExpression>expr);
|
||||
@@ -737,10 +738,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isNarrowableReference(expr: Expression): boolean {
|
||||
return expr.kind === SyntaxKind.Identifier ||
|
||||
expr.kind === SyntaxKind.ThisKeyword ||
|
||||
expr.kind === SyntaxKind.SuperKeyword ||
|
||||
expr.kind === SyntaxKind.PropertyAccessExpression && isNarrowableReference((<PropertyAccessExpression>expr).expression);
|
||||
return expr.kind === SyntaxKind.Identifier || expr.kind === SyntaxKind.ThisKeyword || expr.kind === SyntaxKind.SuperKeyword ||
|
||||
isPropertyAccessExpression(expr) && isNarrowableReference(expr.expression) ||
|
||||
isElementAccessExpression(expr) && expr.argumentExpression &&
|
||||
(isStringLiteral(expr.argumentExpression) || isNumericLiteral(expr.argumentExpression)) &&
|
||||
isNarrowableReference(expr.expression);
|
||||
}
|
||||
|
||||
function hasNarrowableArgument(expr: CallExpression) {
|
||||
@@ -2066,6 +2068,7 @@ namespace ts {
|
||||
}
|
||||
return checkStrictModeIdentifier(<Identifier>node);
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
if (currentFlow && isNarrowableReference(<Expression>node)) {
|
||||
node.flowNode = currentFlow;
|
||||
}
|
||||
@@ -2477,6 +2480,11 @@ namespace ts {
|
||||
|
||||
function bindSpecialPropertyAssignment(node: BinaryExpression) {
|
||||
const lhs = node.left as PropertyAccessEntityNameExpression;
|
||||
// Class declarations in Typescript do not allow property declarations
|
||||
const parentSymbol = lookupSymbolForPropertyAccess(lhs.expression);
|
||||
if (!isInJavaScriptFile(node) && !isFunctionSymbol(parentSymbol)) {
|
||||
return;
|
||||
}
|
||||
// Fix up parent pointers since we're going to use these nodes before we bind into them
|
||||
node.left.parent = node;
|
||||
node.right.parent = node;
|
||||
|
||||
+81
-7
@@ -30,10 +30,18 @@ namespace ts {
|
||||
* These will be commited whenever the iteration through affected files of current changed file is complete
|
||||
*/
|
||||
currentAffectedFilesSignatures: Map<string> | undefined;
|
||||
/**
|
||||
* Newly computed visible to outside referencedSet
|
||||
*/
|
||||
currentAffectedFilesExportedModulesMap: BuilderState.ComputingExportedModulesMap | undefined;
|
||||
/**
|
||||
* Already seen affected files
|
||||
*/
|
||||
seenAffectedFiles: Map<true> | undefined;
|
||||
/**
|
||||
* True if the semantic diagnostics were copied from the old state
|
||||
*/
|
||||
semanticDiagnosticsFromOldState?: Map<true>;
|
||||
/**
|
||||
* program corresponding to this state
|
||||
*/
|
||||
@@ -57,7 +65,8 @@ namespace ts {
|
||||
}
|
||||
state.changedFilesSet = createMap<true>();
|
||||
const useOldState = BuilderState.canReuseOldState(state.referencedMap, oldState);
|
||||
const canCopySemanticDiagnostics = useOldState && oldState!.semanticDiagnosticsPerFile && !!state.semanticDiagnosticsPerFile;
|
||||
const canCopySemanticDiagnostics = useOldState && oldState!.semanticDiagnosticsPerFile && !!state.semanticDiagnosticsPerFile &&
|
||||
!compilerOptionsAffectSemanticDiagnostics(compilerOptions, oldState!.program.getCompilerOptions());
|
||||
if (useOldState) {
|
||||
// Verify the sanity of old state
|
||||
if (!oldState!.currentChangedFilePath) {
|
||||
@@ -96,6 +105,10 @@ namespace ts {
|
||||
const diagnostics = oldState!.semanticDiagnosticsPerFile!.get(sourceFilePath);
|
||||
if (diagnostics) {
|
||||
state.semanticDiagnosticsPerFile!.set(sourceFilePath, diagnostics);
|
||||
if (!state.semanticDiagnosticsFromOldState) {
|
||||
state.semanticDiagnosticsFromOldState = createMap<true>();
|
||||
}
|
||||
state.semanticDiagnosticsFromOldState.set(sourceFilePath, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -120,17 +133,17 @@ namespace ts {
|
||||
while (true) {
|
||||
const { affectedFiles } = state;
|
||||
if (affectedFiles) {
|
||||
const { seenAffectedFiles, semanticDiagnosticsPerFile } = state;
|
||||
const seenAffectedFiles = state.seenAffectedFiles!;
|
||||
let affectedFilesIndex = state.affectedFilesIndex!; // TODO: GH#18217
|
||||
while (affectedFilesIndex < affectedFiles.length) {
|
||||
const affectedFile = affectedFiles[affectedFilesIndex];
|
||||
if (!seenAffectedFiles!.has(affectedFile.path)) {
|
||||
if (!seenAffectedFiles.has(affectedFile.path)) {
|
||||
// Set the next affected file as seen and remove the cached semantic diagnostics
|
||||
state.affectedFilesIndex = affectedFilesIndex;
|
||||
semanticDiagnosticsPerFile!.delete(affectedFile.path);
|
||||
cleanSemanticDiagnosticsOfAffectedFile(state, affectedFile);
|
||||
return affectedFile;
|
||||
}
|
||||
seenAffectedFiles!.set(affectedFile.path, true);
|
||||
seenAffectedFiles.set(affectedFile.path, true);
|
||||
affectedFilesIndex++;
|
||||
}
|
||||
|
||||
@@ -140,6 +153,7 @@ namespace ts {
|
||||
// Commit the changes in file signature
|
||||
BuilderState.updateSignaturesFromCache(state, state.currentAffectedFilesSignatures!);
|
||||
state.currentAffectedFilesSignatures!.clear();
|
||||
BuilderState.updateExportedFilesMapFromCache(state, state.currentAffectedFilesExportedModulesMap);
|
||||
state.affectedFiles = undefined;
|
||||
}
|
||||
|
||||
@@ -160,14 +174,74 @@ namespace ts {
|
||||
|
||||
// Get next batch of affected files
|
||||
state.currentAffectedFilesSignatures = state.currentAffectedFilesSignatures || createMap();
|
||||
state.affectedFiles = BuilderState.getFilesAffectedBy(state, state.program, nextKey.value as Path, cancellationToken, computeHash, state.currentAffectedFilesSignatures);
|
||||
if (state.exportedModulesMap) {
|
||||
state.currentAffectedFilesExportedModulesMap = state.currentAffectedFilesExportedModulesMap || createMap<BuilderState.ReferencedSet | false>();
|
||||
}
|
||||
state.affectedFiles = BuilderState.getFilesAffectedBy(state, state.program, nextKey.value as Path, cancellationToken, computeHash, state.currentAffectedFilesSignatures, state.currentAffectedFilesExportedModulesMap);
|
||||
state.currentChangedFilePath = nextKey.value as Path;
|
||||
state.semanticDiagnosticsPerFile!.delete(nextKey.value as Path);
|
||||
state.affectedFilesIndex = 0;
|
||||
state.seenAffectedFiles = state.seenAffectedFiles || createMap<true>();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the semantic diagnostics cached from old state for affected File and the files that are referencing modules that export entities from affected file
|
||||
*/
|
||||
function cleanSemanticDiagnosticsOfAffectedFile(state: BuilderProgramState, affectedFile: SourceFile) {
|
||||
if (removeSemanticDiagnosticsOf(state, affectedFile.path)) {
|
||||
// If there are no more diagnostics from old cache, done
|
||||
return;
|
||||
}
|
||||
|
||||
// If there was change in signature for the changed file,
|
||||
// then delete the semantic diagnostics for files that are affected by using exports of this module
|
||||
|
||||
if (!state.exportedModulesMap || state.affectedFiles!.length === 1 || !state.changedFilesSet.has(affectedFile.path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.assert(!!state.currentAffectedFilesExportedModulesMap);
|
||||
// Go through exported modules from cache first
|
||||
// If exported modules has path, all files referencing file exported from are affected
|
||||
if (forEachEntry(state.currentAffectedFilesExportedModulesMap!, (exportedModules, exportedFromPath) =>
|
||||
exportedModules &&
|
||||
exportedModules.has(affectedFile.path) &&
|
||||
removeSemanticDiagnosticsOfFilesReferencingPath(state, exportedFromPath as Path)
|
||||
)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If exported from path is not from cache and exported modules has path, all files referencing file exported from are affected
|
||||
forEachEntry(state.exportedModulesMap, (exportedModules, exportedFromPath) =>
|
||||
!state.currentAffectedFilesExportedModulesMap!.has(exportedFromPath) && // If we already iterated this through cache, ignore it
|
||||
exportedModules.has(affectedFile.path) &&
|
||||
removeSemanticDiagnosticsOfFilesReferencingPath(state, exportedFromPath as Path)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* removes the semantic diagnostics of files referencing referencedPath and
|
||||
* returns true if there are no more semantic diagnostics from old state
|
||||
*/
|
||||
function removeSemanticDiagnosticsOfFilesReferencingPath(state: BuilderProgramState, referencedPath: Path) {
|
||||
return forEachEntry(state.referencedMap!, (referencesInFile, filePath) =>
|
||||
referencesInFile.has(referencedPath) && removeSemanticDiagnosticsOf(state, filePath as Path)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes semantic diagnostics for path and
|
||||
* returns true if there are no more semantic diagnostics from the old state
|
||||
*/
|
||||
function removeSemanticDiagnosticsOf(state: BuilderProgramState, path: Path) {
|
||||
if (!state.semanticDiagnosticsFromOldState) {
|
||||
return false;
|
||||
}
|
||||
state.semanticDiagnosticsFromOldState.delete(path);
|
||||
state.semanticDiagnosticsPerFile!.delete(path);
|
||||
return !state.semanticDiagnosticsFromOldState.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called after completing operation on the next affected file.
|
||||
* The operations here are postponed to ensure that cancellation during the iteration is handled correctly
|
||||
|
||||
@@ -2,6 +2,7 @@ namespace ts {
|
||||
export interface EmitOutput {
|
||||
outputFiles: OutputFile[];
|
||||
emitSkipped: boolean;
|
||||
/* @internal */ exportedModulesFromDeclarationEmit?: ExportedModulesFromDeclarationEmit;
|
||||
}
|
||||
|
||||
export interface OutputFile {
|
||||
@@ -17,7 +18,7 @@ namespace ts {
|
||||
cancellationToken?: CancellationToken, customTransformers?: CustomTransformers): EmitOutput {
|
||||
const outputFiles: OutputFile[] = [];
|
||||
const emitResult = program.emit(sourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers);
|
||||
return { outputFiles, emitSkipped: emitResult.emitSkipped };
|
||||
return { outputFiles, emitSkipped: emitResult.emitSkipped, exportedModulesFromDeclarationEmit: emitResult.exportedModulesFromDeclarationEmit };
|
||||
|
||||
function writeFile(fileName: string, text: string, writeByteOrderMark: boolean) {
|
||||
outputFiles.push({ name: fileName, writeByteOrderMark, text });
|
||||
@@ -35,6 +36,11 @@ namespace ts {
|
||||
* Thus non undefined value indicates, module emit
|
||||
*/
|
||||
readonly referencedMap: ReadonlyMap<BuilderState.ReferencedSet> | undefined;
|
||||
/**
|
||||
* Contains the map of exported modules ReferencedSet=exorted module files from the file if module emit is enabled
|
||||
* Otherwise undefined
|
||||
*/
|
||||
readonly exportedModulesMap: Map<BuilderState.ReferencedSet> | undefined;
|
||||
/**
|
||||
* Map of files that have already called update signature.
|
||||
* That means hence forth these files are assumed to have
|
||||
@@ -70,6 +76,30 @@ namespace ts.BuilderState {
|
||||
*/
|
||||
export type ComputeHash = (data: string) => string;
|
||||
|
||||
/**
|
||||
* Exported modules to from declaration emit being computed.
|
||||
* This can contain false in the affected file path to specify that there are no exported module(types from other modules) for this file
|
||||
*/
|
||||
export type ComputingExportedModulesMap = Map<ReferencedSet | false>;
|
||||
|
||||
/**
|
||||
* Get the referencedFile from the imported module symbol
|
||||
*/
|
||||
function getReferencedFileFromImportedModuleSymbol(symbol: Symbol) {
|
||||
if (symbol.declarations && symbol.declarations[0]) {
|
||||
const declarationSourceFile = getSourceFileOfNode(symbol.declarations[0]);
|
||||
return declarationSourceFile && declarationSourceFile.path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the referencedFile from the import name node from file
|
||||
*/
|
||||
function getReferencedFileFromImportLiteral(checker: TypeChecker, importName: StringLiteralLike) {
|
||||
const symbol = checker.getSymbolAtLocation(importName);
|
||||
return symbol && getReferencedFileFromImportedModuleSymbol(symbol);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the referenced files for a file from the program with values for the keys as referenced file's path to be true
|
||||
*/
|
||||
@@ -82,12 +112,9 @@ namespace ts.BuilderState {
|
||||
if (sourceFile.imports && sourceFile.imports.length > 0) {
|
||||
const checker: TypeChecker = program.getTypeChecker();
|
||||
for (const importName of sourceFile.imports) {
|
||||
const symbol = checker.getSymbolAtLocation(importName);
|
||||
if (symbol && symbol.declarations && symbol.declarations[0]) {
|
||||
const declarationSourceFile = getSourceFileOfNode(symbol.declarations[0]);
|
||||
if (declarationSourceFile) {
|
||||
addReferencedFile(declarationSourceFile.path);
|
||||
}
|
||||
const declarationSourceFilePath = getReferencedFileFromImportLiteral(checker, importName);
|
||||
if (declarationSourceFilePath) {
|
||||
addReferencedFile(declarationSourceFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -137,6 +164,7 @@ namespace ts.BuilderState {
|
||||
export function create(newProgram: Program, getCanonicalFileName: GetCanonicalFileName, oldState?: Readonly<BuilderState>): BuilderState {
|
||||
const fileInfos = createMap<FileInfo>();
|
||||
const referencedMap = newProgram.getCompilerOptions().module !== ModuleKind.None ? createMap<ReferencedSet>() : undefined;
|
||||
const exportedModulesMap = referencedMap ? createMap<ReferencedSet>() : undefined;
|
||||
const hasCalledUpdateShapeSignature = createMap<true>();
|
||||
const useOldState = canReuseOldState(referencedMap, oldState);
|
||||
|
||||
@@ -149,6 +177,13 @@ namespace ts.BuilderState {
|
||||
if (newReferences) {
|
||||
referencedMap.set(sourceFile.path, newReferences);
|
||||
}
|
||||
// Copy old visible to outside files map
|
||||
if (useOldState) {
|
||||
const exportedModules = oldState!.exportedModulesMap!.get(sourceFile.path);
|
||||
if (exportedModules) {
|
||||
exportedModulesMap!.set(sourceFile.path, exportedModules);
|
||||
}
|
||||
}
|
||||
}
|
||||
fileInfos.set(sourceFile.path, { version, signature: oldInfo && oldInfo.signature });
|
||||
}
|
||||
@@ -156,6 +191,7 @@ namespace ts.BuilderState {
|
||||
return {
|
||||
fileInfos,
|
||||
referencedMap,
|
||||
exportedModulesMap,
|
||||
hasCalledUpdateShapeSignature,
|
||||
allFilesExcludingDefaultLibraryFile: undefined,
|
||||
allFileNames: undefined
|
||||
@@ -165,7 +201,7 @@ namespace ts.BuilderState {
|
||||
/**
|
||||
* Gets the files affected by the path from the program
|
||||
*/
|
||||
export function getFilesAffectedBy(state: BuilderState, programOfThisState: Program, path: Path, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash, cacheToUpdateSignature?: Map<string>): ReadonlyArray<SourceFile> {
|
||||
export function getFilesAffectedBy(state: BuilderState, programOfThisState: Program, path: Path, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash, cacheToUpdateSignature?: Map<string>, exportedModulesMapCache?: ComputingExportedModulesMap): ReadonlyArray<SourceFile> {
|
||||
// Since the operation could be cancelled, the signatures are always stored in the cache
|
||||
// They will be commited once it is safe to use them
|
||||
// eg when calling this api from tsserver, if there is no cancellation of the operation
|
||||
@@ -176,11 +212,11 @@ namespace ts.BuilderState {
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
if (!updateShapeSignature(state, programOfThisState, sourceFile, signatureCache, cancellationToken, computeHash)) {
|
||||
if (!updateShapeSignature(state, programOfThisState, sourceFile, signatureCache, cancellationToken, computeHash, exportedModulesMapCache)) {
|
||||
return [sourceFile];
|
||||
}
|
||||
|
||||
const result = (state.referencedMap ? getFilesAffectedByUpdatedShapeWhenModuleEmit : getFilesAffectedByUpdatedShapeWhenNonModuleEmit)(state, programOfThisState, sourceFile, signatureCache, cancellationToken, computeHash);
|
||||
const result = (state.referencedMap ? getFilesAffectedByUpdatedShapeWhenModuleEmit : getFilesAffectedByUpdatedShapeWhenNonModuleEmit)(state, programOfThisState, sourceFile, signatureCache, cancellationToken, computeHash, exportedModulesMapCache);
|
||||
if (!cacheToUpdateSignature) {
|
||||
// Commit all the signatures in the signature cache
|
||||
updateSignaturesFromCache(state, signatureCache);
|
||||
@@ -202,8 +238,9 @@ namespace ts.BuilderState {
|
||||
/**
|
||||
* Returns if the shape of the signature has changed since last emit
|
||||
*/
|
||||
function updateShapeSignature(state: Readonly<BuilderState>, programOfThisState: Program, sourceFile: SourceFile, cacheToUpdateSignature: Map<string>, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash) {
|
||||
function updateShapeSignature(state: Readonly<BuilderState>, programOfThisState: Program, sourceFile: SourceFile, cacheToUpdateSignature: Map<string>, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash, exportedModulesMapCache?: ComputingExportedModulesMap) {
|
||||
Debug.assert(!!sourceFile);
|
||||
Debug.assert(!exportedModulesMapCache || !!state.exportedModulesMap, "Compute visible to outside map only if visibleToOutsideReferencedMap present in the state");
|
||||
|
||||
// If we have cached the result for this file, that means hence forth we should assume file shape is uptodate
|
||||
if (state.hasCalledUpdateShapeSignature.has(sourceFile.path) || cacheToUpdateSignature.has(sourceFile.path)) {
|
||||
@@ -222,16 +259,61 @@ namespace ts.BuilderState {
|
||||
const emitOutput = getFileEmitOutput(programOfThisState, sourceFile, /*emitOnlyDtsFiles*/ true, cancellationToken);
|
||||
if (emitOutput.outputFiles && emitOutput.outputFiles.length > 0) {
|
||||
latestSignature = computeHash(emitOutput.outputFiles[0].text);
|
||||
if (exportedModulesMapCache && latestSignature !== prevSignature) {
|
||||
updateExportedModules(sourceFile, emitOutput.exportedModulesFromDeclarationEmit, exportedModulesMapCache);
|
||||
}
|
||||
}
|
||||
else {
|
||||
latestSignature = prevSignature!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
}
|
||||
cacheToUpdateSignature.set(sourceFile.path, latestSignature);
|
||||
|
||||
return !prevSignature || latestSignature !== prevSignature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Coverts the declaration emit result into exported modules map
|
||||
*/
|
||||
function updateExportedModules(sourceFile: SourceFile, exportedModulesFromDeclarationEmit: ExportedModulesFromDeclarationEmit | undefined, exportedModulesMapCache: ComputingExportedModulesMap) {
|
||||
if (!exportedModulesFromDeclarationEmit) {
|
||||
exportedModulesMapCache.set(sourceFile.path, false);
|
||||
return;
|
||||
}
|
||||
|
||||
let exportedModules: Map<true> | undefined;
|
||||
exportedModulesFromDeclarationEmit.forEach(symbol => addExportedModule(getReferencedFileFromImportedModuleSymbol(symbol)));
|
||||
exportedModulesMapCache.set(sourceFile.path, exportedModules || false);
|
||||
|
||||
function addExportedModule(exportedModulePath: Path | undefined) {
|
||||
if (exportedModulePath) {
|
||||
if (!exportedModules) {
|
||||
exportedModules = createMap<true>();
|
||||
}
|
||||
exportedModules.set(exportedModulePath, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the exported modules from cache into state's exported modules map
|
||||
* This should be called whenever it is safe to commit the state of the builder
|
||||
*/
|
||||
export function updateExportedFilesMapFromCache(state: BuilderState, exportedModulesMapCache: ComputingExportedModulesMap | undefined) {
|
||||
if (exportedModulesMapCache) {
|
||||
Debug.assert(!!state.exportedModulesMap);
|
||||
exportedModulesMapCache.forEach((exportedModules, path) => {
|
||||
if (exportedModules) {
|
||||
state.exportedModulesMap!.set(path, exportedModules);
|
||||
}
|
||||
else {
|
||||
state.exportedModulesMap!.delete(path);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the dependencies of the sourceFile
|
||||
*/
|
||||
@@ -347,7 +429,7 @@ namespace ts.BuilderState {
|
||||
/**
|
||||
* When program emits modular code, gets the files affected by the sourceFile whose shape has changed
|
||||
*/
|
||||
function getFilesAffectedByUpdatedShapeWhenModuleEmit(state: BuilderState, programOfThisState: Program, sourceFileWithUpdatedShape: SourceFile, cacheToUpdateSignature: Map<string>, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash | undefined) {
|
||||
function getFilesAffectedByUpdatedShapeWhenModuleEmit(state: BuilderState, programOfThisState: Program, sourceFileWithUpdatedShape: SourceFile, cacheToUpdateSignature: Map<string>, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash | undefined, exportedModulesMapCache: ComputingExportedModulesMap | undefined) {
|
||||
if (!isExternalModule(sourceFileWithUpdatedShape) && !containsOnlyAmbientModules(sourceFileWithUpdatedShape)) {
|
||||
return getAllFilesExcludingDefaultLibraryFile(state, programOfThisState, sourceFileWithUpdatedShape);
|
||||
}
|
||||
@@ -370,7 +452,7 @@ namespace ts.BuilderState {
|
||||
if (!seenFileNamesMap.has(currentPath)) {
|
||||
const currentSourceFile = programOfThisState.getSourceFileByPath(currentPath)!;
|
||||
seenFileNamesMap.set(currentPath, currentSourceFile);
|
||||
if (currentSourceFile && updateShapeSignature(state, programOfThisState, currentSourceFile, cacheToUpdateSignature, cancellationToken, computeHash!)) { // TODO: GH#18217
|
||||
if (currentSourceFile && updateShapeSignature(state, programOfThisState, currentSourceFile, cacheToUpdateSignature, cancellationToken, computeHash!, exportedModulesMapCache)) { // TODO: GH#18217
|
||||
queue.push(...getReferencedByPaths(state, currentPath));
|
||||
}
|
||||
}
|
||||
|
||||
+1133
-1149
File diff suppressed because it is too large
Load Diff
@@ -319,13 +319,15 @@ namespace ts {
|
||||
{
|
||||
name: "noImplicitAny",
|
||||
type: "boolean",
|
||||
strictFlag: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
description: Diagnostics.Raise_error_on_expressions_and_declarations_with_an_implied_any_type,
|
||||
description: Diagnostics.Raise_error_on_expressions_and_declarations_with_an_implied_any_type
|
||||
},
|
||||
{
|
||||
name: "strictNullChecks",
|
||||
type: "boolean",
|
||||
strictFlag: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
description: Diagnostics.Enable_strict_null_checks
|
||||
@@ -333,6 +335,7 @@ namespace ts {
|
||||
{
|
||||
name: "strictFunctionTypes",
|
||||
type: "boolean",
|
||||
strictFlag: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
description: Diagnostics.Enable_strict_checking_of_function_types
|
||||
@@ -340,6 +343,7 @@ namespace ts {
|
||||
{
|
||||
name: "strictPropertyInitialization",
|
||||
type: "boolean",
|
||||
strictFlag: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
description: Diagnostics.Enable_strict_checking_of_property_initialization_in_classes
|
||||
@@ -347,6 +351,7 @@ namespace ts {
|
||||
{
|
||||
name: "noImplicitThis",
|
||||
type: "boolean",
|
||||
strictFlag: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
description: Diagnostics.Raise_error_on_this_expressions_with_an_implied_any_type,
|
||||
@@ -354,6 +359,7 @@ namespace ts {
|
||||
{
|
||||
name: "alwaysStrict",
|
||||
type: "boolean",
|
||||
strictFlag: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
description: Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file
|
||||
@@ -363,6 +369,7 @@ namespace ts {
|
||||
{
|
||||
name: "noUnusedLocals",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Additional_Checks,
|
||||
description: Diagnostics.Report_errors_on_unused_locals,
|
||||
@@ -370,6 +377,7 @@ namespace ts {
|
||||
{
|
||||
name: "noUnusedParameters",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Additional_Checks,
|
||||
description: Diagnostics.Report_errors_on_unused_parameters,
|
||||
@@ -377,6 +385,7 @@ namespace ts {
|
||||
{
|
||||
name: "noImplicitReturns",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Additional_Checks,
|
||||
description: Diagnostics.Report_error_when_not_all_code_paths_in_function_return_a_value
|
||||
@@ -384,6 +393,7 @@ namespace ts {
|
||||
{
|
||||
name: "noFallthroughCasesInSwitch",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Additional_Checks,
|
||||
description: Diagnostics.Report_errors_for_fallthrough_cases_in_switch_statement
|
||||
@@ -455,12 +465,14 @@ namespace ts {
|
||||
{
|
||||
name: "allowSyntheticDefaultImports",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
category: Diagnostics.Module_Resolution_Options,
|
||||
description: Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking
|
||||
},
|
||||
{
|
||||
name: "esModuleInterop",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Module_Resolution_Options,
|
||||
description: Diagnostics.Enables_emit_interoperability_between_CommonJS_and_ES_Modules_via_creation_of_namespace_objects_for_all_imports_Implies_allowSyntheticDefaultImports
|
||||
@@ -640,6 +652,7 @@ namespace ts {
|
||||
{
|
||||
name: "noImplicitUseStrict",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Do_not_emit_use_strict_directives_in_module_output
|
||||
},
|
||||
@@ -678,24 +691,28 @@ namespace ts {
|
||||
{
|
||||
name: "allowUnusedLabels",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Do_not_report_errors_on_unused_labels
|
||||
},
|
||||
{
|
||||
name: "allowUnreachableCode",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Do_not_report_errors_on_unreachable_code
|
||||
},
|
||||
{
|
||||
name: "suppressExcessPropertyErrors",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Suppress_excess_property_checks_for_object_literals,
|
||||
},
|
||||
{
|
||||
name: "suppressImplicitAnyIndexErrors",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures,
|
||||
},
|
||||
@@ -714,6 +731,7 @@ namespace ts {
|
||||
{
|
||||
name: "noStrictGenericChecks",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Disable_strict_checking_of_generic_signatures_in_function_types,
|
||||
},
|
||||
@@ -1327,9 +1345,10 @@ namespace ts {
|
||||
errors.push(createDiagnosticForNodeInSourceFile(sourceFile, element.name, Diagnostics.String_literal_with_double_quotes_expected));
|
||||
}
|
||||
|
||||
const keyText = unescapeLeadingUnderscores(getTextOfPropertyName(element.name));
|
||||
const option = knownOptions ? knownOptions.get(keyText) : undefined;
|
||||
if (extraKeyDiagnosticMessage && !option) {
|
||||
const textOfKey = getTextOfPropertyName(element.name);
|
||||
const keyText = textOfKey && unescapeLeadingUnderscores(textOfKey);
|
||||
const option = keyText && knownOptions ? knownOptions.get(keyText) : undefined;
|
||||
if (keyText && extraKeyDiagnosticMessage && !option) {
|
||||
errors.push(createDiagnosticForNodeInSourceFile(sourceFile, element.name, extraKeyDiagnosticMessage, keyText));
|
||||
}
|
||||
const value = convertPropertyValueToJson(element.initializer, option);
|
||||
|
||||
@@ -987,22 +987,26 @@
|
||||
"category": "Error",
|
||||
"code": 1344
|
||||
},
|
||||
"This parameter is not allowed with 'use strict' directive.": {
|
||||
"An expression of type 'void' cannot be tested for truthiness": {
|
||||
"category": "Error",
|
||||
"code": 1345
|
||||
},
|
||||
"'use strict' directive cannot be used with non-simple parameter list.": {
|
||||
"This parameter is not allowed with 'use strict' directive.": {
|
||||
"category": "Error",
|
||||
"code": 1346
|
||||
},
|
||||
"Non-simple parameter declared here.": {
|
||||
"'use strict' directive cannot be used with non-simple parameter list.": {
|
||||
"category": "Error",
|
||||
"code": 1347
|
||||
},
|
||||
"'use strict' directive used here.": {
|
||||
"Non-simple parameter declared here.": {
|
||||
"category": "Error",
|
||||
"code": 1348
|
||||
},
|
||||
"'use strict' directive used here.": {
|
||||
"category": "Error",
|
||||
"code": 1349
|
||||
},
|
||||
|
||||
"Duplicate identifier '{0}'.": {
|
||||
"category": "Error",
|
||||
@@ -1976,10 +1980,6 @@
|
||||
"category": "Error",
|
||||
"code": 2549
|
||||
},
|
||||
"Generic type instantiation is excessively deep and possibly infinite.": {
|
||||
"category": "Error",
|
||||
"code": 2550
|
||||
},
|
||||
"Property '{0}' does not exist on type '{1}'. Did you mean '{2}'?": {
|
||||
"category": "Error",
|
||||
"code": 2551
|
||||
@@ -2080,6 +2080,14 @@
|
||||
"category": "Error",
|
||||
"code": 2575
|
||||
},
|
||||
"Property '{0}' is a static member of type '{1}'": {
|
||||
"category": "Error",
|
||||
"code": 2576
|
||||
},
|
||||
"Return type annotation circularly references itself.": {
|
||||
"category": "Error",
|
||||
"code": 2577
|
||||
},
|
||||
"JSX element attributes type '{0}' may not be a union type.": {
|
||||
"category": "Error",
|
||||
"code": 2600
|
||||
@@ -3917,7 +3925,7 @@
|
||||
"category": "Error",
|
||||
"code": 7034
|
||||
},
|
||||
"Try `npm install @types/{0}` if it exists or add a new declaration (.d.ts) file containing `declare module '{0}';`": {
|
||||
"Try `npm install @types/{1}` if it exists or add a new declaration (.d.ts) file containing `declare module '{0}';`": {
|
||||
"category": "Error",
|
||||
"code": 7035
|
||||
},
|
||||
@@ -3937,7 +3945,7 @@
|
||||
"category": "Error",
|
||||
"code": 7039
|
||||
},
|
||||
"If the '{0}' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/{0}`": {
|
||||
"If the '{0}' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/{1}`": {
|
||||
"category": "Error",
|
||||
"code": 7040
|
||||
},
|
||||
@@ -3945,6 +3953,10 @@
|
||||
"category": "Error",
|
||||
"code": 7041
|
||||
},
|
||||
"Module '{0}' was resolved to '{1}', but '--resolveJsonModule' is not used.": {
|
||||
"category": "Error",
|
||||
"code": 7042
|
||||
},
|
||||
"You cannot rename this element.": {
|
||||
"category": "Error",
|
||||
"code": 8000
|
||||
@@ -4187,7 +4199,10 @@
|
||||
"category": "Suggestion",
|
||||
"code": 80005
|
||||
},
|
||||
|
||||
"This may be converted to an async function.": {
|
||||
"category": "Suggestion",
|
||||
"code": 80006
|
||||
},
|
||||
"Add missing 'super()' call": {
|
||||
"category": "Message",
|
||||
"code": 90001
|
||||
@@ -4560,6 +4575,7 @@
|
||||
"category": "Message",
|
||||
"code": 95062
|
||||
},
|
||||
|
||||
"Add missing enum member '{0}'": {
|
||||
"category": "Message",
|
||||
"code": 95063
|
||||
@@ -4567,5 +4583,13 @@
|
||||
"Add all missing imports": {
|
||||
"category": "Message",
|
||||
"code": 95064
|
||||
},
|
||||
"Convert to async function":{
|
||||
"category": "Message",
|
||||
"code": 95065
|
||||
},
|
||||
"Convert all to async functions": {
|
||||
"category": "Message",
|
||||
"code": 95066
|
||||
}
|
||||
}
|
||||
|
||||
+13
-3
@@ -113,6 +113,7 @@ namespace ts {
|
||||
|
||||
let bundleInfo: BundleInfo = createDefaultBundleInfo();
|
||||
let emitSkipped = false;
|
||||
let exportedModulesFromDeclarationEmit: ExportedModulesFromDeclarationEmit | undefined;
|
||||
|
||||
// Emit each output file
|
||||
performance.mark("beforePrint");
|
||||
@@ -125,6 +126,7 @@ namespace ts {
|
||||
diagnostics: emitterDiagnostics.getDiagnostics(),
|
||||
emittedFiles: emittedFilesList,
|
||||
sourceMaps: sourceMapDataList,
|
||||
exportedModulesFromDeclarationEmit
|
||||
};
|
||||
|
||||
function emitSourceFileOrBundle({ jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, bundleInfoPath }: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle) {
|
||||
@@ -222,6 +224,10 @@ namespace ts {
|
||||
if (!declBlocked || emitOnlyDtsFiles) {
|
||||
Debug.assert(declarationTransform.transformed.length === 1, "Should only see one output from the decl transform");
|
||||
printSourceFileOrBundle(declarationFilePath, declarationMapPath, declarationTransform.transformed[0], /* bundleInfopath*/ undefined, declarationPrinter, declarationSourceMap);
|
||||
if (emitOnlyDtsFiles && declarationTransform.transformed[0].kind === SyntaxKind.SourceFile) {
|
||||
const sourceFile = declarationTransform.transformed[0] as SourceFile;
|
||||
exportedModulesFromDeclarationEmit = sourceFile.exportedModulesFromDeclarationEmit;
|
||||
}
|
||||
}
|
||||
declarationTransform.dispose();
|
||||
}
|
||||
@@ -2587,14 +2593,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
function emitSyntheticTripleSlashReferencesIfNeeded(node: Bundle) {
|
||||
emitTripleSlashDirectives(!!node.hasNoDefaultLib, node.syntheticFileReferences || [], node.syntheticTypeReferences || []);
|
||||
emitTripleSlashDirectives(!!node.hasNoDefaultLib, node.syntheticFileReferences || [], node.syntheticTypeReferences || [], node.syntheticLibReferences || []);
|
||||
}
|
||||
|
||||
function emitTripleSlashDirectivesIfNeeded(node: SourceFile) {
|
||||
if (node.isDeclarationFile) emitTripleSlashDirectives(node.hasNoDefaultLib, node.referencedFiles, node.typeReferenceDirectives);
|
||||
if (node.isDeclarationFile) emitTripleSlashDirectives(node.hasNoDefaultLib, node.referencedFiles, node.typeReferenceDirectives, node.libReferenceDirectives);
|
||||
}
|
||||
|
||||
function emitTripleSlashDirectives(hasNoDefaultLib: boolean, files: ReadonlyArray<FileReference>, types: ReadonlyArray<FileReference>) {
|
||||
function emitTripleSlashDirectives(hasNoDefaultLib: boolean, files: ReadonlyArray<FileReference>, types: ReadonlyArray<FileReference>, libs: ReadonlyArray<FileReference>) {
|
||||
if (hasNoDefaultLib) {
|
||||
write(`/// <reference no-default-lib="true"/>`);
|
||||
writeLine();
|
||||
@@ -2622,6 +2628,10 @@ namespace ts {
|
||||
write(`/// <reference types="${directive.fileName}" />`);
|
||||
writeLine();
|
||||
}
|
||||
for (const directive of libs) {
|
||||
write(`/// <reference lib="${directive.fileName}" />`);
|
||||
writeLine();
|
||||
}
|
||||
}
|
||||
|
||||
function emitSourceFileWorker(node: SourceFile) {
|
||||
|
||||
@@ -4712,7 +4712,7 @@ namespace ts {
|
||||
/**
|
||||
* Gets the property name of a BindingOrAssignmentElement
|
||||
*/
|
||||
export function getPropertyNameOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement) {
|
||||
export function getPropertyNameOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): PropertyName | undefined {
|
||||
switch (bindingElement.kind) {
|
||||
case SyntaxKind.BindingElement:
|
||||
// `a` in `let { a: b } = ...`
|
||||
@@ -4757,6 +4757,12 @@ namespace ts {
|
||||
Debug.fail("Invalid property name for binding element.");
|
||||
}
|
||||
|
||||
function isStringOrNumericLiteral(node: Node): node is StringLiteral | NumericLiteral {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.StringLiteral
|
||||
|| kind === SyntaxKind.NumericLiteral;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the elements of a BindingOrAssignmentPattern
|
||||
*/
|
||||
|
||||
@@ -29,6 +29,15 @@ namespace ts {
|
||||
path: string;
|
||||
extension: Extension;
|
||||
packageId: PackageId | undefined;
|
||||
/**
|
||||
* When the resolved is not created from cache, the value is
|
||||
* - string if original Path if it is symbolic link to the resolved path
|
||||
* - undefined if path is not a symbolic link
|
||||
* When the resolved is created using value from cache of ResolvedModuleWithFailedLookupLocations, the value is:
|
||||
* - string if original Path if it is symbolic link to the resolved path
|
||||
* - true if path is not a symbolic link - this indicates that the originalPath calculation is already done and needs to be skipped
|
||||
*/
|
||||
originalPath?: string | true;
|
||||
}
|
||||
|
||||
/** Result of trying to resolve a module at a file. Needs to have 'packageId' added later. */
|
||||
@@ -62,9 +71,9 @@ namespace ts {
|
||||
return { fileName: resolved.path, packageId: resolved.packageId };
|
||||
}
|
||||
|
||||
function createResolvedModuleWithFailedLookupLocations(resolved: Resolved | undefined, originalPath: string | undefined, isExternalLibraryImport: boolean, failedLookupLocations: string[]): ResolvedModuleWithFailedLookupLocations {
|
||||
function createResolvedModuleWithFailedLookupLocations(resolved: Resolved | undefined, isExternalLibraryImport: boolean, failedLookupLocations: string[]): ResolvedModuleWithFailedLookupLocations {
|
||||
return {
|
||||
resolvedModule: resolved && { resolvedFileName: resolved.path, originalPath, extension: resolved.extension, isExternalLibraryImport, packageId: resolved.packageId },
|
||||
resolvedModule: resolved && { resolvedFileName: resolved.path, originalPath: resolved.originalPath === true ? undefined : resolved.originalPath, extension: resolved.extension, isExternalLibraryImport, packageId: resolved.packageId },
|
||||
failedLookupLocations
|
||||
};
|
||||
}
|
||||
@@ -362,9 +371,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getOrCreateCacheForModuleName(nonRelativeModuleName: string): PerModuleNameCache {
|
||||
if (isExternalModuleNameRelative(nonRelativeModuleName)) {
|
||||
return undefined!; // TODO: GH#18217
|
||||
}
|
||||
Debug.assert(!isExternalModuleNameRelative(nonRelativeModuleName));
|
||||
let perModuleNameCache = moduleNameToDirectoryMap.get(nonRelativeModuleName);
|
||||
if (!perModuleNameCache) {
|
||||
perModuleNameCache = createPerModuleNameCache();
|
||||
@@ -401,46 +408,47 @@ namespace ts {
|
||||
}
|
||||
directoryPathMap.set(path, result);
|
||||
|
||||
const resolvedFileName = result.resolvedModule && result.resolvedModule.resolvedFileName;
|
||||
const resolvedFileName = result.resolvedModule &&
|
||||
(result.resolvedModule.originalPath || result.resolvedModule.resolvedFileName);
|
||||
// find common prefix between directory and resolved file name
|
||||
// this common prefix should be the shorted path that has the same resolution
|
||||
// this common prefix should be the shortest path that has the same resolution
|
||||
// directory: /a/b/c/d/e
|
||||
// resolvedFileName: /a/b/foo.d.ts
|
||||
const commonPrefix = getCommonPrefix(path, resolvedFileName);
|
||||
// commonPrefix: /a/b
|
||||
// for failed lookups cache the result for every directory up to root
|
||||
const commonPrefix = resolvedFileName && getCommonPrefix(path, resolvedFileName);
|
||||
let current = path;
|
||||
while (true) {
|
||||
while (current !== commonPrefix) {
|
||||
const parent = getDirectoryPath(current);
|
||||
if (parent === current || directoryPathMap.has(parent)) {
|
||||
break;
|
||||
}
|
||||
directoryPathMap.set(parent, result);
|
||||
current = parent;
|
||||
|
||||
if (current === commonPrefix) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getCommonPrefix(directory: Path, resolution: string | undefined) {
|
||||
if (resolution === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
function getCommonPrefix(directory: Path, resolution: string) {
|
||||
const resolutionDirectory = toPath(getDirectoryPath(resolution), currentDirectory, getCanonicalFileName);
|
||||
|
||||
// find first position where directory and resolution differs
|
||||
let i = 0;
|
||||
while (i < Math.min(directory.length, resolutionDirectory.length) && directory.charCodeAt(i) === resolutionDirectory.charCodeAt(i)) {
|
||||
const limit = Math.min(directory.length, resolutionDirectory.length);
|
||||
while (i < limit && directory.charCodeAt(i) === resolutionDirectory.charCodeAt(i)) {
|
||||
i++;
|
||||
}
|
||||
|
||||
// find last directory separator before position i
|
||||
const sep = directory.lastIndexOf(directorySeparator, i);
|
||||
if (sep < 0) {
|
||||
if (i === directory.length && (resolutionDirectory.length === i || resolutionDirectory[i] === directorySeparator)) {
|
||||
return directory;
|
||||
}
|
||||
const rootLength = getRootLength(directory);
|
||||
if (i < rootLength) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return directory.substr(0, sep);
|
||||
const sep = directory.lastIndexOf(directorySeparator, i - 1);
|
||||
if (sep === -1) {
|
||||
return undefined;
|
||||
}
|
||||
return directory.substr(0, Math.max(sep, rootLength));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -492,10 +500,9 @@ namespace ts {
|
||||
|
||||
if (perFolderCache) {
|
||||
perFolderCache.set(moduleName, result);
|
||||
// put result in per-module name cache
|
||||
const perModuleNameCache = cache!.getOrCreateCacheForModuleName(moduleName);
|
||||
if (perModuleNameCache) {
|
||||
perModuleNameCache.set(containingDirectory, result);
|
||||
if (!isExternalModuleNameRelative(moduleName)) {
|
||||
// put result in per-module name cache
|
||||
cache!.getOrCreateCacheForModuleName(moduleName).set(containingDirectory, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -753,16 +760,16 @@ namespace ts {
|
||||
tryResolve(Extensions.JavaScript) ||
|
||||
(compilerOptions.resolveJsonModule ? tryResolve(Extensions.Json) : undefined));
|
||||
if (result && result.value) {
|
||||
const { resolved, originalPath, isExternalLibraryImport } = result.value;
|
||||
return createResolvedModuleWithFailedLookupLocations(resolved, originalPath, isExternalLibraryImport, failedLookupLocations);
|
||||
const { resolved, isExternalLibraryImport } = result.value;
|
||||
return createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations);
|
||||
}
|
||||
return { resolvedModule: undefined, failedLookupLocations };
|
||||
|
||||
function tryResolve(extensions: Extensions): SearchResult<{ resolved: Resolved, originalPath?: string, isExternalLibraryImport: boolean }> {
|
||||
function tryResolve(extensions: Extensions): SearchResult<{ resolved: Resolved, isExternalLibraryImport: boolean }> {
|
||||
const loader: ResolutionKindSpecificLoader = (extensions, candidate, failedLookupLocations, onlyRecordFailures, state) => nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/ true);
|
||||
const resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state);
|
||||
if (resolved) {
|
||||
return toSearchResult({ resolved, isExternalLibraryImport: false });
|
||||
return toSearchResult({ resolved, isExternalLibraryImport: stringContains(resolved.path, nodeModulesPathPart) });
|
||||
}
|
||||
|
||||
if (!isExternalModuleNameRelative(moduleName)) {
|
||||
@@ -773,17 +780,13 @@ namespace ts {
|
||||
if (!resolved) return undefined;
|
||||
|
||||
let resolvedValue = resolved.value;
|
||||
let originalPath: string | undefined;
|
||||
if (!compilerOptions.preserveSymlinks && resolvedValue) {
|
||||
originalPath = resolvedValue.path;
|
||||
if (!compilerOptions.preserveSymlinks && resolvedValue && !resolvedValue.originalPath) {
|
||||
const path = realPath(resolvedValue.path, host, traceEnabled);
|
||||
if (path === originalPath) {
|
||||
originalPath = undefined;
|
||||
}
|
||||
resolvedValue = { ...resolvedValue, path };
|
||||
const originalPath = path === resolvedValue.path ? undefined : resolvedValue.path;
|
||||
resolvedValue = { ...resolvedValue, path, originalPath };
|
||||
}
|
||||
// For node_modules lookups, get the real path so that multiple accesses to an `npm link`-ed module do not create duplicate files.
|
||||
return { value: resolvedValue && { resolved: resolvedValue, originalPath, isExternalLibraryImport: true } };
|
||||
return { value: resolvedValue && { resolved: resolvedValue, isExternalLibraryImport: true } };
|
||||
}
|
||||
else {
|
||||
const { path: candidate, parts } = normalizePathAndParts(combinePaths(containingDirectory, moduleName));
|
||||
@@ -840,7 +843,8 @@ namespace ts {
|
||||
return loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson);
|
||||
}
|
||||
|
||||
const nodeModulesPathPart = "/node_modules/";
|
||||
/*@internal*/
|
||||
export const nodeModulesPathPart = "/node_modules/";
|
||||
|
||||
/**
|
||||
* This will be called on the successfully resolved path from `loadModuleFromFile`.
|
||||
@@ -1233,7 +1237,7 @@ namespace ts {
|
||||
trace(host, Diagnostics.Resolution_for_module_0_was_found_in_cache_from_location_1, moduleName, containingDirectory);
|
||||
}
|
||||
failedLookupLocations.push(...result.failedLookupLocations);
|
||||
return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId } };
|
||||
return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, originalPath: result.resolvedModule.originalPath || true, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId } };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1245,16 +1249,16 @@ namespace ts {
|
||||
|
||||
const resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript);
|
||||
// No originalPath because classic resolution doesn't resolve realPath
|
||||
return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, /*originalPath*/ undefined, /*isExternalLibraryImport*/ false, failedLookupLocations);
|
||||
return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, /*isExternalLibraryImport*/ false, failedLookupLocations);
|
||||
|
||||
function tryResolve(extensions: Extensions): SearchResult<Resolved> {
|
||||
const resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFileNoPackageId, failedLookupLocations, state);
|
||||
if (resolvedUsingSettings) {
|
||||
return { value: resolvedUsingSettings };
|
||||
}
|
||||
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName);
|
||||
|
||||
if (!isExternalModuleNameRelative(moduleName)) {
|
||||
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName);
|
||||
// Climb up parent directories looking for a module.
|
||||
const resolved = forEachAncestorDirectory(containingDirectory, directory => {
|
||||
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, directory, traceEnabled, host, failedLookupLocations);
|
||||
@@ -1292,7 +1296,7 @@ namespace ts {
|
||||
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled };
|
||||
const failedLookupLocations: string[] = [];
|
||||
const resolved = loadModuleFromNodeModulesOneLevel(Extensions.DtsOnly, moduleName, globalCache, failedLookupLocations, state);
|
||||
return createResolvedModuleWithFailedLookupLocations(resolved, /*originalPath*/ undefined, /*isExternalLibraryImport*/ true, failedLookupLocations);
|
||||
return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ true, failedLookupLocations);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,11 +27,21 @@ namespace ts.moduleSpecifiers {
|
||||
compilerOptions: CompilerOptions,
|
||||
importingSourceFile: SourceFile,
|
||||
host: ModuleSpecifierResolutionHost,
|
||||
files: ReadonlyArray<SourceFile>,
|
||||
preferences: ModuleSpecifierPreferences,
|
||||
redirectTargetsMap: RedirectTargetsMap,
|
||||
): string {
|
||||
return first(first(getModuleSpecifiers(moduleSymbol, compilerOptions, importingSourceFile, host, files, preferences, redirectTargetsMap)));
|
||||
const isBundle = (compilerOptions.out || compilerOptions.outFile);
|
||||
if (isBundle && host.getCommonSourceDirectory) {
|
||||
// For declaration bundles, we need to generate absolute paths relative to the common source dir for imports,
|
||||
// just like how the declaration emitter does for the ambient module declarations - we can easily accomplish this
|
||||
// using the `baseUrl` compiler option (which we would otherwise never use in declaration emit) and a non-relative
|
||||
// specifier preference
|
||||
compilerOptions = {
|
||||
...compilerOptions,
|
||||
baseUrl: host.getCommonSourceDirectory(),
|
||||
};
|
||||
}
|
||||
const preferences: ModuleSpecifierPreferences = { importModuleSpecifierPreference: isBundle ? "non-relative" : "relative" };
|
||||
return first(first(getModuleSpecifiers(moduleSymbol, compilerOptions, importingSourceFile, host, host.getSourceFiles ? host.getSourceFiles() : [importingSourceFile], preferences, redirectTargetsMap)));
|
||||
}
|
||||
|
||||
// For each symlink/original for a module, returns a list of ways to import that file.
|
||||
@@ -51,7 +61,7 @@ namespace ts.moduleSpecifiers {
|
||||
if (!files) {
|
||||
return Debug.fail("Files list must be present to resolve symlinks in specifier resolution");
|
||||
}
|
||||
const moduleSourceFile = getSourceFileOfNode(moduleSymbol.valueDeclaration);
|
||||
const moduleSourceFile = getSourceFileOfNode(moduleSymbol.valueDeclaration || getNonAugmentationDeclaration(moduleSymbol));
|
||||
const modulePaths = getAllModulePaths(files, importingSourceFile.path, moduleSourceFile.fileName, info.getCanonicalFileName, host, redirectTargetsMap);
|
||||
|
||||
const global = mapDefined(modulePaths, moduleFileName => getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions));
|
||||
@@ -232,8 +242,10 @@ namespace ts.moduleSpecifiers {
|
||||
}
|
||||
|
||||
function tryGetModuleNameFromAmbientModule(moduleSymbol: Symbol): string | undefined {
|
||||
const decl = moduleSymbol.valueDeclaration;
|
||||
if (isModuleDeclaration(decl) && isStringLiteral(decl.name)) {
|
||||
const decl = find(moduleSymbol.declarations,
|
||||
d => isNonGlobalAmbientModule(d) && (!isExternalModuleAugmentation(d) || !isExternalModuleNameRelative(getTextOfIdentifierOrLiteral(d.name)))
|
||||
) as (ModuleDeclaration & { name: StringLiteral }) | undefined;
|
||||
if (decl) {
|
||||
return decl.name.text;
|
||||
}
|
||||
}
|
||||
@@ -389,7 +401,7 @@ namespace ts.moduleSpecifiers {
|
||||
partEnd = fullPath.indexOf("/", partStart + 1);
|
||||
switch (state) {
|
||||
case States.BeforeNodeModules:
|
||||
if (fullPath.indexOf("/node_modules/", partStart) === partStart) {
|
||||
if (fullPath.indexOf(nodeModulesPathPart, partStart) === partStart) {
|
||||
topLevelNodeModulesIndex = partStart;
|
||||
topLevelPackageNameIndex = partEnd;
|
||||
state = States.NodeModules;
|
||||
@@ -406,7 +418,7 @@ namespace ts.moduleSpecifiers {
|
||||
}
|
||||
break;
|
||||
case States.PackageContent:
|
||||
if (fullPath.indexOf("/node_modules/", partStart) === partStart) {
|
||||
if (fullPath.indexOf(nodeModulesPathPart, partStart) === partStart) {
|
||||
state = States.NodeModules;
|
||||
}
|
||||
else {
|
||||
|
||||
+26
-10
@@ -475,7 +475,7 @@ namespace ts {
|
||||
case SyntaxKind.JSDocAugmentsTag:
|
||||
return visitNode(cbNode, (<JSDocAugmentsTag>node).class);
|
||||
case SyntaxKind.JSDocTemplateTag:
|
||||
return visitNodes(cbNode, cbNodes, (<JSDocTemplateTag>node).typeParameters);
|
||||
return 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) {
|
||||
@@ -2374,7 +2374,7 @@ namespace ts {
|
||||
|
||||
function parseJSDocType(): TypeNode {
|
||||
const dotdotdot = parseOptionalToken(SyntaxKind.DotDotDotToken);
|
||||
let type = parseType();
|
||||
let type = parseTypeOrTypePredicate();
|
||||
if (dotdotdot) {
|
||||
const variadic = createNode(SyntaxKind.JSDocVariadicType, dotdotdot.pos) as JSDocVariadicType;
|
||||
variadic.type = type;
|
||||
@@ -4465,7 +4465,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
const argument = allowInAnd(parseExpression);
|
||||
if (isStringOrNumericLiteral(argument)) {
|
||||
if (isStringOrNumericLiteralLike(argument)) {
|
||||
argument.text = internIdentifier(argument.text);
|
||||
}
|
||||
indexedAccess.argumentExpression = argument;
|
||||
@@ -6507,6 +6507,25 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function skipWhitespaceOrAsterisk(): void {
|
||||
if (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) {
|
||||
if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) {
|
||||
return; // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range
|
||||
}
|
||||
}
|
||||
|
||||
let precedingLineBreak = scanner.hasPrecedingLineBreak();
|
||||
while ((precedingLineBreak && token() === SyntaxKind.AsteriskToken) || token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) {
|
||||
if (token() === SyntaxKind.NewLineTrivia) {
|
||||
precedingLineBreak = true;
|
||||
}
|
||||
else if (token() === SyntaxKind.AsteriskToken) {
|
||||
precedingLineBreak = false;
|
||||
}
|
||||
nextJSDocToken();
|
||||
}
|
||||
}
|
||||
|
||||
function parseTag(indent: number) {
|
||||
Debug.assert(token() === SyntaxKind.AtToken);
|
||||
const atToken = <AtToken>createNode(SyntaxKind.AtToken, scanner.getTokenPos());
|
||||
@@ -6514,7 +6533,7 @@ namespace ts {
|
||||
nextJSDocToken();
|
||||
|
||||
const tagName = parseJSDocIdentifierName();
|
||||
skipWhitespace();
|
||||
skipWhitespaceOrAsterisk();
|
||||
|
||||
let tag: JSDocTag | undefined;
|
||||
switch (tagName.escapedText) {
|
||||
@@ -6658,7 +6677,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function tryParseTypeExpression(): JSDocTypeExpression | undefined {
|
||||
skipWhitespace();
|
||||
skipWhitespaceOrAsterisk();
|
||||
return token() === SyntaxKind.OpenBraceToken ? parseJSDocTypeExpression() : undefined;
|
||||
}
|
||||
|
||||
@@ -6698,7 +6717,7 @@ namespace ts {
|
||||
function parseParameterOrPropertyTag(atToken: AtToken, tagName: Identifier, target: PropertyLikeParse, indent: number | undefined): JSDocParameterTag | JSDocPropertyTag {
|
||||
let typeExpression = tryParseTypeExpression();
|
||||
let isNameFirst = !typeExpression;
|
||||
skipWhitespace();
|
||||
skipWhitespaceOrAsterisk();
|
||||
|
||||
const { name, isBracketed } = parseBracketNameInPropertyAndParamTag();
|
||||
skipWhitespace();
|
||||
@@ -7049,13 +7068,10 @@ namespace ts {
|
||||
typeParameters.push(typeParameter);
|
||||
} while (parseOptionalJsdoc(SyntaxKind.CommaToken));
|
||||
|
||||
if (constraint) {
|
||||
first(typeParameters).constraint = constraint.type;
|
||||
}
|
||||
|
||||
const result = <JSDocTemplateTag>createNode(SyntaxKind.JSDocTemplateTag, atToken.pos);
|
||||
result.atToken = atToken;
|
||||
result.tagName = tagName;
|
||||
result.constraint = constraint;
|
||||
result.typeParameters = createNodeArray(typeParameters, typeParametersPos);
|
||||
finishNode(result);
|
||||
return result;
|
||||
|
||||
+17
-22
@@ -1237,6 +1237,7 @@ namespace ts {
|
||||
getSourceFile: program.getSourceFile,
|
||||
getSourceFileByPath: program.getSourceFileByPath,
|
||||
getSourceFiles: program.getSourceFiles,
|
||||
getLibFileFromReference: program.getLibFileFromReference,
|
||||
isSourceFileFromExternalLibrary,
|
||||
writeFile: writeFileCallback || (
|
||||
(fileName, data, writeByteOrderMark, onError, sourceFiles) => host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles)),
|
||||
@@ -1476,10 +1477,7 @@ namespace ts {
|
||||
|
||||
function getSemanticDiagnosticsForFileNoCache(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] | undefined {
|
||||
return runWithCancellationToken(() => {
|
||||
// If skipLibCheck is enabled, skip reporting errors if file is a declaration file.
|
||||
// If skipDefaultLibCheck is enabled, skip reporting errors if file contains a
|
||||
// '/// <reference no-default-lib="true"/>' directive.
|
||||
if (options.skipLibCheck && sourceFile.isDeclarationFile || options.skipDefaultLibCheck && sourceFile.hasNoDefaultLib) {
|
||||
if (skipTypeChecking(sourceFile, options)) {
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
@@ -2321,27 +2319,20 @@ namespace ts {
|
||||
}
|
||||
|
||||
function computeCommonSourceDirectory(sourceFiles: SourceFile[]): string {
|
||||
const fileNames: string[] = [];
|
||||
for (const file of sourceFiles) {
|
||||
if (!file.isDeclarationFile) {
|
||||
fileNames.push(file.fileName);
|
||||
}
|
||||
}
|
||||
const fileNames = mapDefined(sourceFiles, file => file.isDeclarationFile ? undefined : file.fileName);
|
||||
return computeCommonSourceDirectoryOfFilenames(fileNames, currentDirectory, getCanonicalFileName);
|
||||
}
|
||||
|
||||
function checkSourceFilesBelongToPath(sourceFiles: SourceFile[], rootDirectory: string): boolean {
|
||||
function checkSourceFilesBelongToPath(sourceFiles: ReadonlyArray<SourceFile>, rootDirectory: string): boolean {
|
||||
let allFilesBelongToPath = true;
|
||||
if (sourceFiles) {
|
||||
const absoluteRootDirectoryPath = host.getCanonicalFileName(getNormalizedAbsolutePath(rootDirectory, currentDirectory));
|
||||
const absoluteRootDirectoryPath = host.getCanonicalFileName(getNormalizedAbsolutePath(rootDirectory, currentDirectory));
|
||||
|
||||
for (const sourceFile of sourceFiles) {
|
||||
if (!sourceFile.isDeclarationFile) {
|
||||
const absoluteSourceFilePath = host.getCanonicalFileName(getNormalizedAbsolutePath(sourceFile.fileName, currentDirectory));
|
||||
if (absoluteSourceFilePath.indexOf(absoluteRootDirectoryPath) !== 0) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files, sourceFile.fileName, rootDirectory));
|
||||
allFilesBelongToPath = false;
|
||||
}
|
||||
for (const sourceFile of sourceFiles) {
|
||||
if (!sourceFile.isDeclarationFile) {
|
||||
const absoluteSourceFilePath = host.getCanonicalFileName(getNormalizedAbsolutePath(sourceFile.fileName, currentDirectory));
|
||||
if (absoluteSourceFilePath.indexOf(absoluteRootDirectoryPath) !== 0) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files, sourceFile.fileName, rootDirectory));
|
||||
allFilesBelongToPath = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2358,7 +2349,7 @@ namespace ts {
|
||||
if (sourceFile === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
sourceFile.path = toPath(refPath);
|
||||
const commandLine = parseJsonSourceFileConfigFileContent(sourceFile, configParsingHost, basePath, /*existingOptions*/ undefined, refPath);
|
||||
return { commandLine, sourceFile };
|
||||
}
|
||||
@@ -2852,7 +2843,6 @@ namespace ts {
|
||||
switch (extension) {
|
||||
case Extension.Ts:
|
||||
case Extension.Dts:
|
||||
case Extension.Json: // Since module is resolved to json file only when --resolveJsonModule, we dont need further check
|
||||
// These are always allowed.
|
||||
return undefined;
|
||||
case Extension.Tsx:
|
||||
@@ -2861,6 +2851,8 @@ namespace ts {
|
||||
return needJsx() || needAllowJs();
|
||||
case Extension.Js:
|
||||
return needAllowJs();
|
||||
case Extension.Json:
|
||||
return needResolveJsonModule();
|
||||
}
|
||||
|
||||
function needJsx() {
|
||||
@@ -2869,6 +2861,9 @@ namespace ts {
|
||||
function needAllowJs() {
|
||||
return options.allowJs || !getStrictOptionValue(options, "noImplicitAny") ? undefined : Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type;
|
||||
}
|
||||
function needResolveJsonModule() {
|
||||
return options.resolveJsonModule ? undefined : Diagnostics.Module_0_was_resolved_to_1_but_resolveJsonModule_is_not_used;
|
||||
}
|
||||
}
|
||||
|
||||
function getModuleNames({ imports, moduleAugmentations }: SourceFile): string[] {
|
||||
|
||||
@@ -419,7 +419,7 @@ namespace ts {
|
||||
|
||||
function getDirectoryToWatchFromFailedLookupLocationDirectory(dir: string, dirPath: Path) {
|
||||
// If directory path contains node module, get the most parent node_modules directory for watching
|
||||
while (stringContains(dirPath, "/node_modules/")) {
|
||||
while (stringContains(dirPath, nodeModulesPathPart)) {
|
||||
dir = getDirectoryPath(dir);
|
||||
dirPath = getDirectoryPath(dirPath);
|
||||
}
|
||||
|
||||
@@ -1933,6 +1933,7 @@ namespace ts {
|
||||
|
||||
function scanJSDocToken(): JsDocSyntaxKind {
|
||||
startPos = tokenPos = pos;
|
||||
tokenFlags = 0;
|
||||
if (pos >= end) {
|
||||
return token = SyntaxKind.EndOfFileToken;
|
||||
}
|
||||
@@ -1952,6 +1953,7 @@ namespace ts {
|
||||
return token = SyntaxKind.AtToken;
|
||||
case CharacterCodes.lineFeed:
|
||||
case CharacterCodes.carriageReturn:
|
||||
tokenFlags |= TokenFlags.PrecedingLineBreak;
|
||||
return token = SyntaxKind.NewLineTrivia;
|
||||
case CharacterCodes.asterisk:
|
||||
return token = SyntaxKind.AsteriskToken;
|
||||
|
||||
@@ -100,7 +100,8 @@ namespace ts.sourcemaps {
|
||||
// Lookup file in program, if provided
|
||||
const path = toPath(fileName, location, host.getCanonicalFileName);
|
||||
const file = program && program.getSourceFile(path);
|
||||
if (!file) {
|
||||
// file returned here could be .d.ts when asked for .ts file if projectReferences and module resolution created this source file
|
||||
if (!file || file.resolvedPath !== path) {
|
||||
// Otherwise check the cache (which may hit disk)
|
||||
return fallbackCache.get(path);
|
||||
}
|
||||
@@ -373,4 +374,4 @@ namespace ts.sourcemaps {
|
||||
encodedText.charCodeAt(pos) === CharacterCodes.comma ||
|
||||
encodedText.charCodeAt(pos) === CharacterCodes.semicolon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -756,8 +756,7 @@ namespace ts {
|
||||
if (recursive) {
|
||||
return watchDirectoryRecursively(directoryName, callback);
|
||||
}
|
||||
watchDirectory(directoryName, callback);
|
||||
return undefined!; // TODO: GH#18217
|
||||
return watchDirectory(directoryName, callback);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -33,10 +33,11 @@ namespace ts {
|
||||
let needsScopeFixMarker = false;
|
||||
let resultHasScopeMarker = false;
|
||||
let enclosingDeclaration: Node;
|
||||
let necessaryTypeRefernces: Map<true> | undefined;
|
||||
let necessaryTypeReferences: Map<true> | undefined;
|
||||
let lateMarkedStatements: LateVisibilityPaintedStatement[] | undefined;
|
||||
let lateStatementReplacementMap: Map<VisitResult<LateVisibilityPaintedStatement>>;
|
||||
let suppressNewDiagnosticContexts: boolean;
|
||||
let exportedModulesFromDeclarationEmit: Symbol[] | undefined;
|
||||
|
||||
const host = context.getEmitHost();
|
||||
const symbolTracker: SymbolTracker = {
|
||||
@@ -46,11 +47,13 @@ namespace ts {
|
||||
reportPrivateInBaseOfClassExpression,
|
||||
moduleResolverHost: host,
|
||||
trackReferencedAmbientModule,
|
||||
trackExternalModuleSymbolOfImportTypeNode
|
||||
};
|
||||
let errorNameNode: DeclarationName | undefined;
|
||||
|
||||
let currentSourceFile: SourceFile;
|
||||
let refs: Map<SourceFile>;
|
||||
let libs: Map<boolean>;
|
||||
const resolver = context.getEmitResolver();
|
||||
const options = context.getCompilerOptions();
|
||||
const newLine = getNewLineCharacter(options);
|
||||
@@ -61,9 +64,9 @@ namespace ts {
|
||||
if (!typeReferenceDirectives) {
|
||||
return;
|
||||
}
|
||||
necessaryTypeRefernces = necessaryTypeRefernces || createMap<true>();
|
||||
necessaryTypeReferences = necessaryTypeReferences || createMap<true>();
|
||||
for (const ref of typeReferenceDirectives) {
|
||||
necessaryTypeRefernces.set(ref, true);
|
||||
necessaryTypeReferences.set(ref, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +118,12 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function trackExternalModuleSymbolOfImportTypeNode(symbol: Symbol) {
|
||||
if (!isBundledEmit) {
|
||||
(exportedModulesFromDeclarationEmit || (exportedModulesFromDeclarationEmit = [])).push(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
function trackSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags) {
|
||||
if (symbol.flags & SymbolFlags.TypeParameter) return;
|
||||
handleSymbolAccessibilityError(resolver.isSymbolAccessible(symbol, enclosingDeclaration, meaning, /*shouldComputeAliasesToMakeVisible*/ true));
|
||||
@@ -155,6 +164,7 @@ namespace ts {
|
||||
if (node.kind === SyntaxKind.Bundle) {
|
||||
isBundledEmit = true;
|
||||
refs = createMap<SourceFile>();
|
||||
libs = createMap<boolean>();
|
||||
let hasNoDefaultLib = false;
|
||||
const bundle = createBundle(map(node.sourceFiles,
|
||||
sourceFile => {
|
||||
@@ -169,6 +179,7 @@ namespace ts {
|
||||
needsScopeFixMarker = false;
|
||||
resultHasScopeMarker = false;
|
||||
collectReferences(sourceFile, refs);
|
||||
collectLibs(sourceFile, libs);
|
||||
if (isExternalModule(sourceFile)) {
|
||||
resultHasExternalModuleIndicator = false; // unused in external module bundle emit (all external modules are within module blocks, therefore are known to be modules)
|
||||
needsDeclare = false;
|
||||
@@ -192,6 +203,7 @@ namespace ts {
|
||||
}));
|
||||
bundle.syntheticFileReferences = [];
|
||||
bundle.syntheticTypeReferences = getFileReferencesForUsedTypeReferences();
|
||||
bundle.syntheticLibReferences = getLibReferences();
|
||||
bundle.hasNoDefaultLib = hasNoDefaultLib;
|
||||
const outputFilePath = getDirectoryPath(normalizeSlashes(getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath!));
|
||||
const referenceVisitor = mapReferencesIntoArray(bundle.syntheticFileReferences as FileReference[], outputFilePath);
|
||||
@@ -211,8 +223,9 @@ namespace ts {
|
||||
suppressNewDiagnosticContexts = false;
|
||||
lateMarkedStatements = undefined;
|
||||
lateStatementReplacementMap = createMap();
|
||||
necessaryTypeRefernces = undefined;
|
||||
necessaryTypeReferences = undefined;
|
||||
refs = collectReferences(currentSourceFile, createMap());
|
||||
libs = collectLibs(currentSourceFile, createMap());
|
||||
const references: FileReference[] = [];
|
||||
const outputFilePath = getDirectoryPath(normalizeSlashes(getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath!));
|
||||
const referenceVisitor = mapReferencesIntoArray(references, outputFilePath);
|
||||
@@ -223,11 +236,16 @@ namespace ts {
|
||||
if (isExternalModule(node) && (!resultHasExternalModuleIndicator || (needsScopeFixMarker && !resultHasScopeMarker))) {
|
||||
combinedStatements = setTextRange(createNodeArray([...combinedStatements, createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([]), /*moduleSpecifier*/ undefined)]), combinedStatements);
|
||||
}
|
||||
const updated = updateSourceFileNode(node, combinedStatements, /*isDeclarationFile*/ true, references, getFileReferencesForUsedTypeReferences(), node.hasNoDefaultLib);
|
||||
const updated = updateSourceFileNode(node, combinedStatements, /*isDeclarationFile*/ true, references, getFileReferencesForUsedTypeReferences(), node.hasNoDefaultLib, getLibReferences());
|
||||
updated.exportedModulesFromDeclarationEmit = exportedModulesFromDeclarationEmit;
|
||||
return updated;
|
||||
|
||||
function getLibReferences() {
|
||||
return map(arrayFrom(libs.keys()), lib => ({ fileName: lib, pos: -1, end: -1 }));
|
||||
}
|
||||
|
||||
function getFileReferencesForUsedTypeReferences() {
|
||||
return necessaryTypeRefernces ? mapDefined(arrayFrom(necessaryTypeRefernces.keys()), getFileReferenceForTypeName) : [];
|
||||
return necessaryTypeReferences ? mapDefined(arrayFrom(necessaryTypeReferences.keys()), getFileReferenceForTypeName) : [];
|
||||
}
|
||||
|
||||
function getFileReferenceForTypeName(typeName: string): FileReference | undefined {
|
||||
@@ -288,6 +306,16 @@ namespace ts {
|
||||
return ret;
|
||||
}
|
||||
|
||||
function collectLibs(sourceFile: SourceFile, ret: Map<boolean>) {
|
||||
forEach(sourceFile.libReferenceDirectives, ref => {
|
||||
const lib = host.getLibFileFromReference(ref);
|
||||
if (lib) {
|
||||
ret.set(ref.fileName.toLocaleLowerCase(), true);
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
function filterBindingPatternInitializers(name: BindingName) {
|
||||
if (name.kind === SyntaxKind.Identifier) {
|
||||
return name;
|
||||
@@ -483,10 +511,18 @@ namespace ts {
|
||||
function rewriteModuleSpecifier<T extends Node>(parent: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration | ImportTypeNode, input: T | undefined): T | StringLiteral {
|
||||
if (!input) return undefined!; // TODO: GH#18217
|
||||
resultHasExternalModuleIndicator = resultHasExternalModuleIndicator || (parent.kind !== SyntaxKind.ModuleDeclaration && parent.kind !== SyntaxKind.ImportType);
|
||||
if (input.kind === SyntaxKind.StringLiteral && isBundledEmit) {
|
||||
const newName = getExternalModuleNameFromDeclaration(context.getEmitHost(), resolver, parent);
|
||||
if (newName) {
|
||||
return createLiteral(newName);
|
||||
if (isStringLiteralLike(input)) {
|
||||
if (isBundledEmit) {
|
||||
const newName = getExternalModuleNameFromDeclaration(context.getEmitHost(), resolver, parent);
|
||||
if (newName) {
|
||||
return createLiteral(newName);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const symbol = resolver.getSymbolOfExternalModuleSpecifier(input);
|
||||
if (symbol) {
|
||||
(exportedModulesFromDeclarationEmit || (exportedModulesFromDeclarationEmit = [])).push(symbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
return input;
|
||||
@@ -935,7 +971,7 @@ namespace ts {
|
||||
}
|
||||
case SyntaxKind.FunctionDeclaration: {
|
||||
// Generators lose their generator-ness, excepting their return type
|
||||
return cleanup(updateFunctionDeclaration(
|
||||
const clean = cleanup(updateFunctionDeclaration(
|
||||
input,
|
||||
/*decorators*/ undefined,
|
||||
ensureModifiers(input, isPrivate),
|
||||
@@ -946,6 +982,21 @@ namespace ts {
|
||||
ensureType(input, input.type),
|
||||
/*body*/ undefined
|
||||
));
|
||||
if (clean && resolver.isJSContainerFunctionDeclaration(input)) {
|
||||
const declarations = mapDefined(resolver.getPropertiesOfContainerFunction(input), p => {
|
||||
if (!isPropertyAccessExpression(p.valueDeclaration)) {
|
||||
return undefined;
|
||||
}
|
||||
const type = resolver.createTypeOfDeclaration(p.valueDeclaration, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker);
|
||||
const varDecl = createVariableDeclaration(unescapeLeadingUnderscores(p.escapedName), type, /*initializer*/ undefined);
|
||||
return createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([varDecl]));
|
||||
});
|
||||
const namespaceDecl = createModuleDeclaration(/*decorators*/ undefined, ensureModifiers(input, isPrivate), input.name!, createModuleBlock(declarations), NodeFlags.Namespace);
|
||||
return [clean, namespaceDecl];
|
||||
}
|
||||
else {
|
||||
return clean;
|
||||
}
|
||||
}
|
||||
case SyntaxKind.ModuleDeclaration: {
|
||||
needsDeclare = false;
|
||||
|
||||
@@ -447,7 +447,7 @@ namespace ts {
|
||||
const argumentExpression = ensureIdentifier(flattenContext, visitNode(propertyName.expression, flattenContext.visitor), /*reuseIdentifierExpressions*/ false, /*location*/ propertyName);
|
||||
return createElementAccess(value, argumentExpression);
|
||||
}
|
||||
else if (isStringOrNumericLiteral(propertyName)) {
|
||||
else if (isStringOrNumericLiteralLike(propertyName)) {
|
||||
const argumentExpression = getSynthesizedClone(propertyName);
|
||||
argumentExpression.text = argumentExpression.text;
|
||||
return createElementAccess(value, argumentExpression);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// Currently we do not want to expose API for build, we should work out the API, and then expose it just like we did for builder/watch
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
const minimumDate = new Date(-8640000000000000);
|
||||
const maximumDate = new Date(8640000000000000);
|
||||
|
||||
+26
-2
@@ -759,6 +759,7 @@ namespace ts {
|
||||
kind: SyntaxKind.TypeParameter;
|
||||
parent: DeclarationWithTypeParameterChildren | InferTypeNode;
|
||||
name: Identifier;
|
||||
/** Note: Consider calling `getEffectiveConstraintOfTypeParameter` */
|
||||
constraint?: TypeNode;
|
||||
default?: TypeNode;
|
||||
|
||||
@@ -1081,7 +1082,7 @@ namespace ts {
|
||||
|
||||
export interface TypePredicateNode extends TypeNode {
|
||||
kind: SyntaxKind.TypePredicate;
|
||||
parent: SignatureDeclaration;
|
||||
parent: SignatureDeclaration | JSDocTypeExpression;
|
||||
parameterName: Identifier | ThisTypeNode;
|
||||
type: TypeNode;
|
||||
}
|
||||
@@ -2363,6 +2364,7 @@ namespace ts {
|
||||
|
||||
export interface JSDocTemplateTag extends JSDocTag {
|
||||
kind: SyntaxKind.JSDocTemplateTag;
|
||||
constraint: TypeNode | undefined;
|
||||
typeParameters: NodeArray<TypeParameterDeclaration>;
|
||||
}
|
||||
|
||||
@@ -2633,14 +2635,20 @@ namespace ts {
|
||||
/* @internal */ pragmas: PragmaMap;
|
||||
/* @internal */ localJsxNamespace?: __String;
|
||||
/* @internal */ localJsxFactory?: EntityName;
|
||||
|
||||
/*@internal*/ exportedModulesFromDeclarationEmit?: ExportedModulesFromDeclarationEmit;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export type ExportedModulesFromDeclarationEmit = ReadonlyArray<Symbol>;
|
||||
|
||||
export interface Bundle extends Node {
|
||||
kind: SyntaxKind.Bundle;
|
||||
prepends: ReadonlyArray<InputFiles | UnparsedSource>;
|
||||
sourceFiles: ReadonlyArray<SourceFile>;
|
||||
/* @internal */ syntheticFileReferences?: ReadonlyArray<FileReference>;
|
||||
/* @internal */ syntheticTypeReferences?: ReadonlyArray<FileReference>;
|
||||
/* @internal */ syntheticLibReferences?: ReadonlyArray<FileReference>;
|
||||
/* @internal */ hasNoDefaultLib?: boolean;
|
||||
}
|
||||
|
||||
@@ -2878,6 +2886,7 @@ namespace ts {
|
||||
diagnostics: ReadonlyArray<Diagnostic>;
|
||||
emittedFiles?: string[]; // Array of files the compiler wrote to disk
|
||||
/* @internal */ sourceMaps?: SourceMapData[]; // Array of sourceMapData if compiler emitted sourcemaps
|
||||
/* @internal */ exportedModulesFromDeclarationEmit?: ExportedModulesFromDeclarationEmit;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -2903,6 +2912,8 @@ namespace ts {
|
||||
getBaseTypes(type: InterfaceType): BaseType[];
|
||||
getBaseTypeOfLiteralType(type: Type): Type;
|
||||
getWidenedType(type: Type): Type;
|
||||
/* @internal */
|
||||
getPromisedTypeOfPromise(promise: Type, errorNode?: Node): Type | undefined;
|
||||
getReturnTypeOfSignature(signature: Signature): Type;
|
||||
/**
|
||||
* Gets the type of a parameter at a given position in a signature.
|
||||
@@ -2967,6 +2978,7 @@ namespace ts {
|
||||
getAugmentedPropertiesOfType(type: Type): Symbol[];
|
||||
getRootSymbols(symbol: Symbol): Symbol[];
|
||||
getContextualType(node: Expression): Type | undefined;
|
||||
/* @internal */ getContextualTypeForObjectLiteralElement(element: ObjectLiteralElementLike): Type | undefined;
|
||||
/* @internal */ getContextualTypeForArgumentAtIndex(call: CallLikeExpression, argIndex: number): Type | undefined;
|
||||
/* @internal */ getContextualTypeForJsxAttribute(attribute: JsxAttribute | JsxSpreadAttribute): Type | undefined;
|
||||
/* @internal */ isContextSensitive(node: Expression | MethodDeclaration | ObjectLiteralElementLike | JsxAttributeLike): boolean;
|
||||
@@ -3362,7 +3374,9 @@ namespace ts {
|
||||
isImplementationOfOverload(node: FunctionLike): boolean | undefined;
|
||||
isRequiredInitializedParameter(node: ParameterDeclaration): boolean;
|
||||
isOptionalUninitializedParameterProperty(node: ParameterDeclaration): boolean;
|
||||
createTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker, addUndefined?: boolean): TypeNode | undefined;
|
||||
isJSContainerFunctionDeclaration(node: FunctionDeclaration): boolean;
|
||||
getPropertiesOfContainerFunction(node: Declaration): Symbol[];
|
||||
createTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration | PropertyAccessExpression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker, addUndefined?: boolean): TypeNode | undefined;
|
||||
createReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined;
|
||||
createTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined;
|
||||
createLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): Expression;
|
||||
@@ -3381,6 +3395,7 @@ namespace ts {
|
||||
isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean;
|
||||
getJsxFactoryEntity(location?: Node): EntityName | undefined;
|
||||
getAllAccessorDeclarations(declaration: AccessorDeclaration): AllAccessorDeclarations;
|
||||
getSymbolOfExternalModuleSpecifier(node: StringLiteralLike): Symbol | undefined;
|
||||
}
|
||||
|
||||
export const enum SymbolFlags {
|
||||
@@ -3659,6 +3674,7 @@ namespace ts {
|
||||
superCall?: SuperCall; // Cached first super-call found in the constructor. Used in checking whether super is called before this-accessing
|
||||
switchTypes?: Type[]; // Cached array of switch case expression types
|
||||
jsxNamespace?: Symbol | false; // Resolved jsx namespace symbol for this node
|
||||
contextFreeType?: Type; // Cached context-free type used by the first pass of inference; used when a function's return is partially contextually sensitive
|
||||
}
|
||||
|
||||
export const enum TypeFlags {
|
||||
@@ -3817,6 +3833,7 @@ namespace ts {
|
||||
ReverseMapped = 1 << 11, // Object contains a property from a reverse-mapped type
|
||||
JsxAttributes = 1 << 12, // Jsx attributes type
|
||||
MarkerType = 1 << 13, // Marker type used for variance probing
|
||||
JSLiteral = 1 << 14, // Object type declared in JS - disables errors on read/write of nonexisting members
|
||||
ClassOrInterface = Class | Interface
|
||||
}
|
||||
|
||||
@@ -3935,6 +3952,7 @@ namespace ts {
|
||||
constraintType?: Type;
|
||||
templateType?: Type;
|
||||
modifiersType?: Type;
|
||||
resolvedApparentType?: Type;
|
||||
}
|
||||
|
||||
export interface EvolvingArrayType extends ObjectType {
|
||||
@@ -4532,6 +4550,8 @@ namespace ts {
|
||||
isCommandLineOnly?: boolean;
|
||||
showInSimplifiedHelpView?: boolean;
|
||||
category?: DiagnosticMessage;
|
||||
strictFlag?: true; // true if the option is one of the flag under strict
|
||||
affectsSemanticDiagnostics?: true; // true if option affects semantic diagnostics
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -4697,6 +4717,7 @@ namespace ts {
|
||||
verticalTab = 0x0B, // \v
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export interface UpToDateHost {
|
||||
fileExists(fileName: string): boolean;
|
||||
getModifiedTime(fileName: string): Date | undefined;
|
||||
@@ -5056,6 +5077,7 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
isSourceFileFromExternalLibrary(file: SourceFile): boolean;
|
||||
getLibFileFromReference(ref: FileReference): SourceFile | undefined;
|
||||
|
||||
getCommonSourceDirectory(): string;
|
||||
getCanonicalFileName(fileName: string): string;
|
||||
@@ -5324,6 +5346,7 @@ namespace ts {
|
||||
fileExists?(path: string): boolean;
|
||||
readFile?(path: string): string | undefined;
|
||||
getSourceFiles?(): ReadonlyArray<SourceFile>; // Used for cached resolutions to find symlinks without traversing the fs (again)
|
||||
getCommonSourceDirectory?(): string;
|
||||
}
|
||||
|
||||
// Note: this used to be deprecated in our public API, but is still used internally
|
||||
@@ -5338,6 +5361,7 @@ namespace ts {
|
||||
reportInaccessibleUniqueSymbolError?(): void;
|
||||
moduleResolverHost?: ModuleSpecifierResolutionHost;
|
||||
trackReferencedAmbientModule?(decl: ModuleDeclaration, symbol: Symbol): void;
|
||||
trackExternalModuleSymbolOfImportTypeNode?(symbol: Symbol): void;
|
||||
}
|
||||
|
||||
export interface TextSpan {
|
||||
|
||||
+107
-60
@@ -638,6 +638,10 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getNonAugmentationDeclaration(symbol: Symbol) {
|
||||
return find(symbol.declarations, d => !isExternalModuleAugmentation(d) && !(isModuleDeclaration(d) && isGlobalScopeAugmentation(d)));
|
||||
}
|
||||
|
||||
export function isEffectiveExternalModule(node: SourceFile, compilerOptions: CompilerOptions) {
|
||||
return isExternalModule(node) || compilerOptions.isolatedModules || ((getEmitModuleKind(compilerOptions) === ModuleKind.CommonJS) && !!node.commonJsModuleIndicator);
|
||||
}
|
||||
@@ -767,9 +771,9 @@ namespace ts {
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return escapeLeadingUnderscores(name.text);
|
||||
case SyntaxKind.ComputedPropertyName:
|
||||
return isStringOrNumericLiteral(name.expression) ? escapeLeadingUnderscores(name.expression.text) : undefined!; // TODO: GH#18217 Almost all uses of this assume the result to be defined!
|
||||
return isStringOrNumericLiteralLike(name.expression) ? escapeLeadingUnderscores(name.expression.text) : undefined!; // TODO: GH#18217 Almost all uses of this assume the result to be defined!
|
||||
default:
|
||||
Debug.assertNever(name);
|
||||
return Debug.assertNever(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1016,6 +1020,8 @@ namespace ts {
|
||||
return !isExpressionWithTypeArgumentsInClassExtendsClause(parent);
|
||||
case SyntaxKind.TypeParameter:
|
||||
return node === (<TypeParameterDeclaration>parent).constraint;
|
||||
case SyntaxKind.JSDocTemplateTag:
|
||||
return node === (<JSDocTemplateTag>parent).constraint;
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.PropertySignature:
|
||||
case SyntaxKind.Parameter:
|
||||
@@ -1719,12 +1725,15 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getDeclarationOfJSInitializer(node: Node): Node | undefined {
|
||||
if (!isInJavaScriptFile(node) || !node.parent) {
|
||||
if (!node.parent) {
|
||||
return undefined;
|
||||
}
|
||||
let name: Expression | BindingName | undefined;
|
||||
let decl: Node | undefined;
|
||||
if (isVariableDeclaration(node.parent) && node.parent.initializer === node) {
|
||||
if (!isInJavaScriptFile(node) && !isVarConst(node.parent)) {
|
||||
return undefined;
|
||||
}
|
||||
name = node.parent.name;
|
||||
decl = node.parent;
|
||||
}
|
||||
@@ -1886,8 +1895,12 @@ namespace ts {
|
||||
/// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property
|
||||
/// assignments we treat as special in the binder
|
||||
export function getSpecialPropertyAssignmentKind(expr: BinaryExpression): SpecialPropertyAssignmentKind {
|
||||
if (!isInJavaScriptFile(expr) ||
|
||||
expr.operatorToken.kind !== SyntaxKind.EqualsToken ||
|
||||
const special = getSpecialPropertyAssignmentKindWorker(expr);
|
||||
return special === SpecialPropertyAssignmentKind.Property || isInJavaScriptFile(expr) ? special : SpecialPropertyAssignmentKind.None;
|
||||
}
|
||||
|
||||
function getSpecialPropertyAssignmentKindWorker(expr: BinaryExpression): SpecialPropertyAssignmentKind {
|
||||
if (expr.operatorToken.kind !== SyntaxKind.EqualsToken ||
|
||||
!isPropertyAccessExpression(expr.left)) {
|
||||
return SpecialPropertyAssignmentKind.None;
|
||||
}
|
||||
@@ -1948,6 +1961,14 @@ namespace ts {
|
||||
!!getJSDocTypeTag(expr.parent);
|
||||
}
|
||||
|
||||
export function isFunctionSymbol(symbol: Symbol | undefined) {
|
||||
if (!symbol || !symbol.valueDeclaration) {
|
||||
return false;
|
||||
}
|
||||
const decl = symbol.valueDeclaration;
|
||||
return decl.kind === SyntaxKind.FunctionDeclaration || isVariableDeclaration(decl) && decl.initializer && isFunctionLike(decl.initializer);
|
||||
}
|
||||
|
||||
export function importFromModuleSpecifier(node: StringLiteralLike): AnyValidImportOrReExport {
|
||||
return tryGetImportFromModuleSpecifier(node) || Debug.fail(Debug.showSyntaxKind(node.parent));
|
||||
}
|
||||
@@ -2348,7 +2369,10 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
const binExp = name.parent.parent;
|
||||
return isBinaryExpression(binExp) && getSpecialPropertyAssignmentKind(binExp) !== SpecialPropertyAssignmentKind.None && getNameOfDeclaration(binExp) === name;
|
||||
return isBinaryExpression(binExp) &&
|
||||
getSpecialPropertyAssignmentKind(binExp) !== SpecialPropertyAssignmentKind.None &&
|
||||
(binExp.left.symbol || binExp.symbol) &&
|
||||
getNameOfDeclaration(binExp) === name;
|
||||
}
|
||||
}
|
||||
default:
|
||||
@@ -2560,10 +2584,8 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isStringOrNumericLiteral(node: Node): node is StringLiteral | NumericLiteral {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.StringLiteral
|
||||
|| kind === SyntaxKind.NumericLiteral;
|
||||
export function isStringOrNumericLiteralLike(node: Node): node is StringLiteralLike | NumericLiteral {
|
||||
return isStringLiteralLike(node) || isNumericLiteral(node);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2580,7 +2602,7 @@ namespace ts {
|
||||
|
||||
export function isDynamicName(name: DeclarationName): boolean {
|
||||
return name.kind === SyntaxKind.ComputedPropertyName &&
|
||||
!isStringOrNumericLiteral(name.expression) &&
|
||||
!isStringOrNumericLiteralLike(name.expression) &&
|
||||
!isWellKnownSymbolSyntactically(name.expression);
|
||||
}
|
||||
|
||||
@@ -2593,24 +2615,25 @@ namespace ts {
|
||||
return isPropertyAccessExpression(node) && isESSymbolIdentifier(node.expression);
|
||||
}
|
||||
|
||||
export function getPropertyNameForPropertyNameNode(name: DeclarationName): __String | undefined {
|
||||
if (name.kind === SyntaxKind.Identifier) {
|
||||
return name.escapedText;
|
||||
export function getPropertyNameForPropertyNameNode(name: PropertyName): __String | undefined {
|
||||
switch (name.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return name.escapedText;
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return escapeLeadingUnderscores(name.text);
|
||||
case SyntaxKind.ComputedPropertyName:
|
||||
const nameExpression = name.expression;
|
||||
if (isWellKnownSymbolSyntactically(nameExpression)) {
|
||||
return getPropertyNameForKnownSymbolName(idText((<PropertyAccessExpression>nameExpression).name));
|
||||
}
|
||||
else if (isStringOrNumericLiteralLike(nameExpression)) {
|
||||
return escapeLeadingUnderscores(nameExpression.text);
|
||||
}
|
||||
return undefined;
|
||||
default:
|
||||
return Debug.assertNever(name);
|
||||
}
|
||||
if (name.kind === SyntaxKind.StringLiteral || name.kind === SyntaxKind.NumericLiteral) {
|
||||
return escapeLeadingUnderscores(name.text);
|
||||
}
|
||||
if (name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
const nameExpression = name.expression;
|
||||
if (isWellKnownSymbolSyntactically(nameExpression)) {
|
||||
return getPropertyNameForKnownSymbolName(idText((<PropertyAccessExpression>nameExpression).name));
|
||||
}
|
||||
else if (nameExpression.kind === SyntaxKind.StringLiteral || nameExpression.kind === SyntaxKind.NumericLiteral) {
|
||||
return escapeLeadingUnderscores((<LiteralExpression>nameExpression).text);
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export type PropertyNameLiteral = Identifier | StringLiteralLike | NumericLiteral;
|
||||
@@ -3183,16 +3206,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getDeclarationEmitOutputFilePath(fileName: string, host: EmitHost) {
|
||||
// TODO: GH#25810 following should work but makes the build break:
|
||||
// return getDeclarationEmitOutputFilePathWorker(fileName, host.getCompilerOptions(), host.getCurrentDirectory(), host.getCommonSourceDirectory(), f => host.getCanonicalFileName(f));
|
||||
|
||||
const options = host.getCompilerOptions();
|
||||
const outputDir = options.declarationDir || options.outDir; // Prefer declaration folder if specified
|
||||
|
||||
const path = outputDir
|
||||
? getSourceFilePathInNewDir(fileName, host, outputDir)
|
||||
: fileName;
|
||||
return removeFileExtension(path) + Extension.Dts;
|
||||
return getDeclarationEmitOutputFilePathWorker(fileName, host.getCompilerOptions(), host.getCurrentDirectory(), host.getCommonSourceDirectory(), f => host.getCanonicalFileName(f));
|
||||
}
|
||||
|
||||
export function getDeclarationEmitOutputFilePathWorker(fileName: string, options: CompilerOptions, currentDirectory: string, commonSourceDirectory: string, getCanonicalFileName: GetCanonicalFileName): string {
|
||||
@@ -3325,17 +3339,17 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
forEach(declarations, (member: Declaration) => {
|
||||
if ((member.kind === SyntaxKind.GetAccessor || member.kind === SyntaxKind.SetAccessor)
|
||||
forEach(declarations, member => {
|
||||
if (isAccessor(member)
|
||||
&& hasModifier(member, ModifierFlags.Static) === hasModifier(accessor, ModifierFlags.Static)) {
|
||||
const memberName = getPropertyNameForPropertyNameNode((member as NamedDeclaration).name!);
|
||||
const memberName = getPropertyNameForPropertyNameNode(member.name);
|
||||
const accessorName = getPropertyNameForPropertyNameNode(accessor.name);
|
||||
if (memberName === accessorName) {
|
||||
if (!firstAccessor) {
|
||||
firstAccessor = <AccessorDeclaration>member;
|
||||
firstAccessor = member;
|
||||
}
|
||||
else if (!secondAccessor) {
|
||||
secondAccessor = <AccessorDeclaration>member;
|
||||
secondAccessor = member;
|
||||
}
|
||||
|
||||
if (member.kind === SyntaxKind.GetAccessor && !getAccessor) {
|
||||
@@ -3362,7 +3376,9 @@ namespace ts {
|
||||
* parsed in a JavaScript file, gets the type annotation from JSDoc.
|
||||
*/
|
||||
export function getEffectiveTypeAnnotationNode(node: Node): TypeNode | undefined {
|
||||
return (node as HasType).type || (isInJavaScriptFile(node) ? getJSDocType(node) : undefined);
|
||||
const type = (node as HasType).type;
|
||||
if (type || !isInJavaScriptFile(node)) return type;
|
||||
return isJSDocPropertyLikeTag(node) ? node.typeExpression && node.typeExpression.type : getJSDocType(node);
|
||||
}
|
||||
|
||||
export function getTypeAnnotationNode(node: Node): TypeNode | undefined {
|
||||
@@ -3374,10 +3390,9 @@ namespace ts {
|
||||
* JavaScript file, gets the return type annotation from JSDoc.
|
||||
*/
|
||||
export function getEffectiveReturnTypeNode(node: SignatureDeclaration | JSDocSignature): TypeNode | undefined {
|
||||
if (isJSDocSignature(node)) {
|
||||
return node.type && node.type.typeExpression && node.type.typeExpression.type;
|
||||
}
|
||||
return node.type || (isInJavaScriptFile(node) ? getJSDocReturnType(node) : undefined);
|
||||
return isJSDocSignature(node) ?
|
||||
node.type && node.type.typeExpression && node.type.typeExpression.type :
|
||||
node.type || (isInJavaScriptFile(node) ? getJSDocReturnType(node) : undefined);
|
||||
}
|
||||
|
||||
export function getJSDocTypeParameterDeclarations(node: DeclarationWithTypeParameters): ReadonlyArray<TypeParameterDeclaration> {
|
||||
@@ -4197,7 +4212,9 @@ namespace ts {
|
||||
return operator === SyntaxKind.PlusPlusToken || operator === SyntaxKind.MinusMinusToken ? writeOrReadWrite() : AccessKind.Read;
|
||||
case SyntaxKind.BinaryExpression:
|
||||
const { left, operatorToken } = parent as BinaryExpression;
|
||||
return left === node && isAssignmentOperator(operatorToken.kind) ? writeOrReadWrite() : AccessKind.Read;
|
||||
return left === node && isAssignmentOperator(operatorToken.kind) ?
|
||||
operatorToken.kind === SyntaxKind.EqualsToken ? AccessKind.Write : writeOrReadWrite()
|
||||
: AccessKind.Read;
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
return (parent as PropertyAccessExpression).name !== node ? AccessKind.Read : accessKind(parent);
|
||||
default:
|
||||
@@ -4836,13 +4853,13 @@ namespace ts {
|
||||
if (isDeclaration(hostNode)) {
|
||||
return getDeclarationIdentifier(hostNode);
|
||||
}
|
||||
// Covers remaining cases
|
||||
// Covers remaining cases (returning undefined if none match).
|
||||
switch (hostNode.kind) {
|
||||
case SyntaxKind.VariableStatement:
|
||||
if (hostNode.declarationList && hostNode.declarationList.declarations[0]) {
|
||||
return getDeclarationIdentifier(hostNode.declarationList.declarations[0]);
|
||||
}
|
||||
return undefined;
|
||||
break;
|
||||
case SyntaxKind.ExpressionStatement:
|
||||
const expr = hostNode.expression;
|
||||
switch (expr.kind) {
|
||||
@@ -4854,9 +4871,7 @@ namespace ts {
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
case SyntaxKind.EndOfFileToken:
|
||||
return undefined;
|
||||
break;
|
||||
case SyntaxKind.ParenthesizedExpression: {
|
||||
return getDeclarationIdentifier(hostNode.expression);
|
||||
}
|
||||
@@ -4864,10 +4879,8 @@ namespace ts {
|
||||
if (isDeclaration(hostNode.statement) || isExpression(hostNode.statement)) {
|
||||
return getDeclarationIdentifier(hostNode.statement);
|
||||
}
|
||||
return undefined;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Debug.assertNever(hostNode, "Found typedef tag attached to node which it should not be!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5103,7 +5116,27 @@ namespace ts {
|
||||
Debug.assert(node.parent.kind === SyntaxKind.JSDocComment);
|
||||
return flatMap(node.parent.tags, tag => isJSDocTemplateTag(tag) ? tag.typeParameters : undefined) as ReadonlyArray<TypeParameterDeclaration>;
|
||||
}
|
||||
return node.typeParameters || (isInJavaScriptFile(node) ? getJSDocTypeParameterDeclarations(node) : emptyArray);
|
||||
if (node.typeParameters) {
|
||||
return node.typeParameters;
|
||||
}
|
||||
if (isInJavaScriptFile(node)) {
|
||||
const decls = getJSDocTypeParameterDeclarations(node);
|
||||
if (decls.length) {
|
||||
return decls;
|
||||
}
|
||||
const typeTag = getJSDocType(node);
|
||||
if (typeTag && isFunctionTypeNode(typeTag) && typeTag.typeParameters) {
|
||||
return typeTag.typeParameters;
|
||||
}
|
||||
}
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
export function getEffectiveConstraintOfTypeParameter(node: TypeParameterDeclaration): TypeNode | undefined {
|
||||
return node.constraint ? node.constraint
|
||||
: isJSDocTemplateTag(node.parent) && node === node.parent.typeParameters[0]
|
||||
? node.parent.constraint
|
||||
: undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6967,6 +7000,15 @@ namespace ts {
|
||||
return compilerOptions[flag] === undefined ? !!compilerOptions.strict : !!compilerOptions[flag];
|
||||
}
|
||||
|
||||
export function compilerOptionsAffectSemanticDiagnostics(newOptions: CompilerOptions, oldOptions: CompilerOptions) {
|
||||
if (oldOptions === newOptions) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return optionDeclarations.some(option => (!!option.strictFlag && getStrictOptionValue(newOptions, option.name as StrictOptionName) !== getStrictOptionValue(oldOptions, option.name as StrictOptionName)) ||
|
||||
(!!option.affectsSemanticDiagnostics && !newOptions[option.name] !== !oldOptions[option.name]));
|
||||
}
|
||||
|
||||
export function hasZeroOrOneAsteriskCharacter(str: string): boolean {
|
||||
let seenAsterisk = false;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
@@ -7260,8 +7302,6 @@ namespace ts {
|
||||
if (pathComponents.length === 0) return "";
|
||||
|
||||
const root = pathComponents[0] && ensureTrailingDirectorySeparator(pathComponents[0]);
|
||||
if (pathComponents.length === 1) return root;
|
||||
|
||||
return root + pathComponents.slice(1).join(directorySeparator);
|
||||
}
|
||||
|
||||
@@ -8213,4 +8253,11 @@ namespace ts {
|
||||
// Include the `<>`
|
||||
return { pos: typeParameters.pos - 1, end: typeParameters.end + 1 };
|
||||
}
|
||||
|
||||
export function skipTypeChecking(sourceFile: SourceFile, options: CompilerOptions) {
|
||||
// If skipLibCheck is enabled, skip reporting errors if file is a declaration file.
|
||||
// If skipDefaultLibCheck is enabled, skip reporting errors if file contains a
|
||||
// '/// <reference no-default-lib="true"/>' directive.
|
||||
return options.skipLibCheck && sourceFile.isDeclarationFile || options.skipDefaultLibCheck && sourceFile.hasNoDefaultLib;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,6 +183,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
let host: DirectoryStructureHost = system;
|
||||
host; // tslint:disable-line no-unused-expression (TODO: `host` is unused!)
|
||||
const useCaseSensitiveFileNames = () => system.useCaseSensitiveFileNames;
|
||||
const writeFileName = (s: string) => system.write(s + system.newLine);
|
||||
const onWatchStatusChange = reportWatchStatus || createWatchStatusReporter(system);
|
||||
|
||||
+157
-130
@@ -50,10 +50,8 @@ namespace FourSlash {
|
||||
data?: {};
|
||||
}
|
||||
|
||||
export interface Range {
|
||||
export interface Range extends ts.TextRange {
|
||||
fileName: string;
|
||||
pos: number;
|
||||
end: number;
|
||||
marker?: Marker;
|
||||
}
|
||||
|
||||
@@ -870,8 +868,7 @@ namespace FourSlash {
|
||||
const actualByName = ts.createMap<ts.CompletionEntry>();
|
||||
for (const entry of actualCompletions.entries) {
|
||||
if (actualByName.has(entry.name)) {
|
||||
// TODO: GH#23587
|
||||
if (entry.name !== "undefined" && entry.name !== "require") this.raiseError(`Duplicate (${actualCompletions.entries.filter(a => a.name === entry.name).length}) completions for ${entry.name}`);
|
||||
this.raiseError(`Duplicate (${actualCompletions.entries.filter(a => a.name === entry.name).length}) completions for ${entry.name}`);
|
||||
}
|
||||
else {
|
||||
actualByName.set(entry.name, entry);
|
||||
@@ -1103,7 +1100,7 @@ namespace FourSlash {
|
||||
return node;
|
||||
}
|
||||
|
||||
private verifyRange(desc: string, expected: Range, actual: ts.Node) {
|
||||
private verifyRange(desc: string, expected: ts.TextRange, actual: ts.Node) {
|
||||
const actualStart = actual.getStart();
|
||||
const actualEnd = actual.getEnd();
|
||||
if (actualStart !== expected.pos || actualEnd !== expected.end) {
|
||||
@@ -1639,11 +1636,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
baselineFile = baselineFile.replace(ts.Extension.Ts, ".baseline");
|
||||
|
||||
}
|
||||
Harness.Baseline.runBaseline(
|
||||
baselineFile,
|
||||
() => {
|
||||
return this.baselineCurrentFileLocations(pos => this.getBreakpointStatementLocation(pos)!);
|
||||
});
|
||||
Harness.Baseline.runBaseline(baselineFile, this.baselineCurrentFileLocations(pos => this.getBreakpointStatementLocation(pos)!));
|
||||
}
|
||||
|
||||
private getEmitFiles(): ReadonlyArray<FourSlashFile> {
|
||||
@@ -1674,66 +1667,58 @@ Actual: ${stringify(fullActual)}`);
|
||||
for (const { name, text } of outputFiles) {
|
||||
const fromTestFile = this.getFileContent(name);
|
||||
if (fromTestFile !== text) {
|
||||
this.raiseError("Emit output is not as expected: " + showTextDiff(fromTestFile, text));
|
||||
this.raiseError(`Emit output for ${name} is not as expected: ${showTextDiff(fromTestFile, text)}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public baselineGetEmitOutput(): void {
|
||||
Harness.Baseline.runBaseline(
|
||||
ts.Debug.assertDefined(this.testData.globalOptions[MetadataOptionNames.baselineFile]),
|
||||
() => {
|
||||
let resultString = "";
|
||||
// Loop through all the emittedFiles and emit them one by one
|
||||
for (const emitFile of this.getEmitFiles()) {
|
||||
const emitOutput = this.languageService.getEmitOutput(emitFile.fileName);
|
||||
// Print emitOutputStatus in readable format
|
||||
resultString += "EmitSkipped: " + emitOutput.emitSkipped + Harness.IO.newLine();
|
||||
let resultString = "";
|
||||
// Loop through all the emittedFiles and emit them one by one
|
||||
for (const emitFile of this.getEmitFiles()) {
|
||||
const emitOutput = this.languageService.getEmitOutput(emitFile.fileName);
|
||||
// Print emitOutputStatus in readable format
|
||||
resultString += "EmitSkipped: " + emitOutput.emitSkipped + Harness.IO.newLine();
|
||||
|
||||
if (emitOutput.emitSkipped) {
|
||||
resultString += "Diagnostics:" + Harness.IO.newLine();
|
||||
const diagnostics = ts.getPreEmitDiagnostics(this.languageService.getProgram()!); // TODO: GH#18217
|
||||
for (const diagnostic of diagnostics) {
|
||||
if (!ts.isString(diagnostic.messageText)) {
|
||||
let chainedMessage: ts.DiagnosticMessageChain | undefined = diagnostic.messageText;
|
||||
let indentation = " ";
|
||||
while (chainedMessage) {
|
||||
resultString += indentation + chainedMessage.messageText + Harness.IO.newLine();
|
||||
chainedMessage = chainedMessage.next;
|
||||
indentation = indentation + " ";
|
||||
}
|
||||
}
|
||||
else {
|
||||
resultString += " " + diagnostic.messageText + Harness.IO.newLine();
|
||||
}
|
||||
if (emitOutput.emitSkipped) {
|
||||
resultString += "Diagnostics:" + Harness.IO.newLine();
|
||||
const diagnostics = ts.getPreEmitDiagnostics(this.languageService.getProgram()!); // TODO: GH#18217
|
||||
for (const diagnostic of diagnostics) {
|
||||
if (!ts.isString(diagnostic.messageText)) {
|
||||
let chainedMessage: ts.DiagnosticMessageChain | undefined = diagnostic.messageText;
|
||||
let indentation = " ";
|
||||
while (chainedMessage) {
|
||||
resultString += indentation + chainedMessage.messageText + Harness.IO.newLine();
|
||||
chainedMessage = chainedMessage.next;
|
||||
indentation = indentation + " ";
|
||||
}
|
||||
}
|
||||
|
||||
for (const outputFile of emitOutput.outputFiles) {
|
||||
const fileName = "FileName : " + outputFile.name + Harness.IO.newLine();
|
||||
resultString = resultString + Harness.IO.newLine() + fileName + outputFile.text;
|
||||
else {
|
||||
resultString += " " + diagnostic.messageText + Harness.IO.newLine();
|
||||
}
|
||||
resultString += Harness.IO.newLine();
|
||||
}
|
||||
}
|
||||
|
||||
return resultString;
|
||||
});
|
||||
for (const outputFile of emitOutput.outputFiles) {
|
||||
const fileName = "FileName : " + outputFile.name + Harness.IO.newLine();
|
||||
resultString = resultString + Harness.IO.newLine() + fileName + outputFile.text;
|
||||
}
|
||||
resultString += Harness.IO.newLine();
|
||||
}
|
||||
|
||||
Harness.Baseline.runBaseline(ts.Debug.assertDefined(this.testData.globalOptions[MetadataOptionNames.baselineFile]), resultString);
|
||||
}
|
||||
|
||||
public baselineQuickInfo() {
|
||||
let baselineFile = this.testData.globalOptions[MetadataOptionNames.baselineFile];
|
||||
if (!baselineFile) {
|
||||
baselineFile = ts.getBaseFileName(this.activeFile.fileName).replace(ts.Extension.Ts, ".baseline");
|
||||
}
|
||||
|
||||
const baselineFile = this.testData.globalOptions[MetadataOptionNames.baselineFile] ||
|
||||
ts.getBaseFileName(this.activeFile.fileName).replace(ts.Extension.Ts, ".baseline");
|
||||
Harness.Baseline.runBaseline(
|
||||
baselineFile,
|
||||
() => stringify(
|
||||
stringify(
|
||||
this.testData.markers.map(marker => ({
|
||||
marker,
|
||||
quickInfo: this.languageService.getQuickInfoAtPosition(marker.fileName, marker.position)
|
||||
}))
|
||||
));
|
||||
}))));
|
||||
}
|
||||
|
||||
public printBreakpointLocation(pos: number) {
|
||||
@@ -1967,18 +1952,11 @@ Actual: ${stringify(fullActual)}`);
|
||||
* May be negative.
|
||||
*/
|
||||
private applyEdits(fileName: string, edits: ReadonlyArray<ts.TextChange>, isFormattingEdit: boolean): number {
|
||||
// We get back a set of edits, but langSvc.editScript only accepts one at a time. Use this to keep track
|
||||
// of the incremental offset from each edit to the next. We assume these edit ranges don't overlap
|
||||
|
||||
// Copy this so we don't ruin someone else's copy
|
||||
edits = JSON.parse(JSON.stringify(edits));
|
||||
|
||||
// Get a snapshot of the content of the file so we can make sure any formatting edits didn't destroy non-whitespace characters
|
||||
const oldContent = this.getFileContent(fileName);
|
||||
let runningOffset = 0;
|
||||
|
||||
for (let i = 0; i < edits.length; i++) {
|
||||
const edit = edits[i];
|
||||
forEachTextChange(edits, edit => {
|
||||
const offsetStart = edit.span.start;
|
||||
const offsetEnd = offsetStart + edit.span.length;
|
||||
this.editScriptAndUpdateMarkers(fileName, offsetStart, offsetEnd, edit.newText);
|
||||
@@ -1994,14 +1972,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
}
|
||||
runningOffset += editDelta;
|
||||
|
||||
// Update positions of any future edits affected by this change
|
||||
for (let j = i + 1; j < edits.length; j++) {
|
||||
if (edits[j].span.start >= edits[i].span.start) {
|
||||
edits[j].span.start += editDelta;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (isFormattingEdit) {
|
||||
const newContent = this.getFileContent(fileName);
|
||||
@@ -2043,30 +2014,14 @@ Actual: ${stringify(fullActual)}`);
|
||||
this.languageServiceAdapterHost.editScript(fileName, editStart, editEnd, newText);
|
||||
for (const marker of this.testData.markers) {
|
||||
if (marker.fileName === fileName) {
|
||||
marker.position = updatePosition(marker.position);
|
||||
marker.position = updatePosition(marker.position, editStart, editEnd, newText);
|
||||
}
|
||||
}
|
||||
|
||||
for (const range of this.testData.ranges) {
|
||||
if (range.fileName === fileName) {
|
||||
range.pos = updatePosition(range.pos);
|
||||
range.end = updatePosition(range.end);
|
||||
}
|
||||
}
|
||||
|
||||
function updatePosition(position: number) {
|
||||
if (position > editStart) {
|
||||
if (position < editEnd) {
|
||||
// Inside the edit - mark it as invalidated (?)
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
// Move marker back/forward by the appropriate amount
|
||||
return position + (editStart - editEnd) + newText.length;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return position;
|
||||
range.pos = updatePosition(range.pos, editStart, editEnd, newText);
|
||||
range.end = updatePosition(range.end, editStart, editEnd, newText);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2347,10 +2302,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
public baselineCurrentFileNameOrDottedNameSpans() {
|
||||
Harness.Baseline.runBaseline(
|
||||
this.testData.globalOptions[MetadataOptionNames.baselineFile],
|
||||
() => {
|
||||
return this.baselineCurrentFileLocations(pos =>
|
||||
this.getNameOrDottedNameSpan(pos)!);
|
||||
});
|
||||
this.baselineCurrentFileLocations(pos => this.getNameOrDottedNameSpan(pos)!));
|
||||
}
|
||||
|
||||
public printNameOrDottedNameSpans(pos: number) {
|
||||
@@ -2500,22 +2452,24 @@ Actual: ${stringify(fullActual)}`);
|
||||
|
||||
this.applyCodeActions(codeActions);
|
||||
|
||||
this.verifyNewContent(options, ts.flatMap(codeActions, a => a.changes.map(c => c.fileName)));
|
||||
this.verifyNewContentAfterChange(options, ts.flatMap(codeActions, a => a.changes.map(c => c.fileName)));
|
||||
}
|
||||
|
||||
public verifyRangeIs(expectedText: string, includeWhiteSpace?: boolean) {
|
||||
this.verifyTextMatches(this.rangeText(this.getOnlyRange()), !!includeWhiteSpace, expectedText);
|
||||
}
|
||||
|
||||
private getOnlyRange() {
|
||||
const ranges = this.getRanges();
|
||||
if (ranges.length !== 1) {
|
||||
this.raiseError("Exactly one range should be specified in the testfile.");
|
||||
}
|
||||
return ts.first(ranges);
|
||||
}
|
||||
|
||||
const actualText = this.rangeText(ranges[0]);
|
||||
|
||||
const result = includeWhiteSpace
|
||||
? actualText === expectedText
|
||||
: this.removeWhitespace(actualText) === this.removeWhitespace(expectedText);
|
||||
|
||||
if (!result) {
|
||||
private verifyTextMatches(actualText: string, includeWhitespace: boolean, expectedText: string) {
|
||||
const removeWhitespace = (s: string): string => includeWhitespace ? s : this.removeWhitespace(s);
|
||||
if (removeWhitespace(actualText) !== removeWhitespace(expectedText)) {
|
||||
this.raiseError(`Actual range text doesn't match expected text.\n${showTextDiff(expectedText, actualText)}`);
|
||||
}
|
||||
}
|
||||
@@ -2582,33 +2536,68 @@ Actual: ${stringify(fullActual)}`);
|
||||
const action = actions[index];
|
||||
|
||||
assert.equal(action.description, options.description);
|
||||
assert.deepEqual(action.commands, options.commands);
|
||||
|
||||
for (const change of action.changes) {
|
||||
this.applyEdits(change.fileName, change.textChanges, /*isFormattingEdit*/ false);
|
||||
if (options.applyChanges) {
|
||||
for (const change of action.changes) {
|
||||
this.applyEdits(change.fileName, change.textChanges, /*isFormattingEdit*/ false);
|
||||
}
|
||||
this.verifyNewContentAfterChange(options, action.changes.map(c => c.fileName));
|
||||
}
|
||||
else {
|
||||
this.verifyNewContent(options, action.changes);
|
||||
}
|
||||
|
||||
this.verifyNewContent(options, action.changes.map(c => c.fileName));
|
||||
}
|
||||
|
||||
private verifyNewContent(options: FourSlashInterface.NewContentOptions, changedFiles: ReadonlyArray<string>) {
|
||||
const assertedChangedFiles = !options.newFileContent || typeof options.newFileContent === "string"
|
||||
private verifyNewContent({ newFileContent, newRangeContent }: FourSlashInterface.NewContentOptions, changes: ReadonlyArray<ts.FileTextChanges>): void {
|
||||
if (newRangeContent !== undefined) {
|
||||
assert(newFileContent === undefined);
|
||||
assert(changes.length === 1, "Affected 0 or more than 1 file, must use 'newFileContent' instead of 'newRangeContent'");
|
||||
const change = ts.first(changes);
|
||||
assert(change.fileName = this.activeFile.fileName);
|
||||
const newText = ts.textChanges.applyChanges(this.getFileContent(this.activeFile.fileName), change.textChanges);
|
||||
const newRange = updateTextRangeForTextChanges(this.getOnlyRange(), change.textChanges);
|
||||
const actualText = newText.slice(newRange.pos, newRange.end);
|
||||
this.verifyTextMatches(actualText, /*includeWhitespace*/ true, newRangeContent);
|
||||
}
|
||||
else {
|
||||
if (newFileContent === undefined) throw ts.Debug.fail();
|
||||
if (typeof newFileContent !== "object") newFileContent = { [this.activeFile.fileName]: newFileContent };
|
||||
for (const change of changes) {
|
||||
const expectedNewContent = newFileContent[change.fileName];
|
||||
if (expectedNewContent === undefined) {
|
||||
ts.Debug.fail(`Did not expect a change in ${change.fileName}`);
|
||||
}
|
||||
const oldText = this.tryGetFileContent(change.fileName);
|
||||
ts.Debug.assert(!!change.isNewFile === (oldText === undefined));
|
||||
const newContent = change.isNewFile ? ts.first(change.textChanges).newText : ts.textChanges.applyChanges(oldText!, change.textChanges);
|
||||
assert.equal(newContent, expectedNewContent);
|
||||
}
|
||||
for (const newFileName in newFileContent) {
|
||||
ts.Debug.assert(changes.some(c => c.fileName === newFileName), "No change in file", () => newFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private verifyNewContentAfterChange({ newFileContent, newRangeContent }: FourSlashInterface.NewContentOptions, changedFiles: ReadonlyArray<string>) {
|
||||
const assertedChangedFiles = !newFileContent || typeof newFileContent === "string"
|
||||
? [this.activeFile.fileName]
|
||||
: ts.getOwnKeys(options.newFileContent);
|
||||
: ts.getOwnKeys(newFileContent);
|
||||
assert.deepEqual(assertedChangedFiles, changedFiles);
|
||||
|
||||
if (options.newFileContent !== undefined) {
|
||||
assert(!options.newRangeContent);
|
||||
if (typeof options.newFileContent === "string") {
|
||||
this.verifyCurrentFileContent(options.newFileContent);
|
||||
if (newFileContent !== undefined) {
|
||||
assert(!newRangeContent);
|
||||
if (typeof newFileContent === "string") {
|
||||
this.verifyCurrentFileContent(newFileContent);
|
||||
}
|
||||
else {
|
||||
for (const fileName in options.newFileContent) {
|
||||
this.verifyFileContent(fileName, options.newFileContent[fileName]);
|
||||
for (const fileName in newFileContent) {
|
||||
this.verifyFileContent(fileName, newFileContent[fileName]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.verifyRangeIs(options.newRangeContent!, /*includeWhitespace*/ true);
|
||||
this.verifyRangeIs(newRangeContent!, /*includeWhitespace*/ true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2985,7 +2974,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
|
||||
public verifyApplicableRefactorAvailableAtMarker(negative: boolean, markerName: string) {
|
||||
const isAvailable = this.getApplicableRefactors(this.getMarkerByName(markerName).position).length > 0;
|
||||
const isAvailable = this.getApplicableRefactors(this.getMarkerByName(markerName)).length > 0;
|
||||
if (negative && isAvailable) {
|
||||
this.raiseError(`verifyApplicableRefactorAvailableAtMarker failed - expected no refactor at marker ${markerName} but found some.`);
|
||||
}
|
||||
@@ -3002,7 +2991,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
|
||||
public verifyRefactorAvailable(negative: boolean, name: string, actionName?: string) {
|
||||
let refactors = this.getApplicableRefactors(this.getSelection());
|
||||
let refactors = this.getApplicableRefactorsAtSelection();
|
||||
refactors = refactors.filter(r => r.name === name && (actionName === undefined || r.actions.some(a => a.name === actionName)));
|
||||
const isAvailable = refactors.length > 0;
|
||||
|
||||
@@ -3022,11 +3011,11 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
|
||||
public verifyRefactorsAvailable(names: ReadonlyArray<string>): void {
|
||||
assert.deepEqual(unique(this.getApplicableRefactors(this.getSelection()), r => r.name), names);
|
||||
assert.deepEqual(unique(this.getApplicableRefactorsAtSelection(), r => r.name), names);
|
||||
}
|
||||
|
||||
public verifyRefactor({ name, actionName, refactors }: FourSlashInterface.VerifyRefactorOptions) {
|
||||
const actualRefactors = this.getApplicableRefactors(this.getSelection()).filter(r => r.name === name && r.actions.some(a => a.name === actionName));
|
||||
const actualRefactors = this.getApplicableRefactorsAtSelection().filter(r => r.name === name && r.actions.some(a => a.name === actionName));
|
||||
this.assertObjectsEqual(actualRefactors, refactors);
|
||||
}
|
||||
|
||||
@@ -3047,7 +3036,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
|
||||
public applyRefactor({ refactorName, actionName, actionDescription, newContent: newContentWithRenameMarker }: FourSlashInterface.ApplyRefactorOptions) {
|
||||
const range = this.getSelection();
|
||||
const refactors = this.getApplicableRefactors(range);
|
||||
const refactors = this.getApplicableRefactorsAtSelection();
|
||||
const refactorsWithName = refactors.filter(r => r.name === refactorName);
|
||||
if (refactorsWithName.length === 0) {
|
||||
this.raiseError(`The expected refactor: ${refactorName} is not available at the marker location.\nAvailable refactors: ${refactors.map(r => r.name)}`);
|
||||
@@ -3125,8 +3114,8 @@ Actual: ${stringify(fullActual)}`);
|
||||
const action = ts.first(refactor.actions);
|
||||
assert(action.name === "Move to a new file" && action.description === "Move to a new file");
|
||||
|
||||
const editInfo = this.languageService.getEditsForRefactor(this.activeFile.fileName, this.formatCodeSettings, range, refactor.name, action.name, options.preferences || ts.emptyOptions)!;
|
||||
this.testNewFileContents(editInfo.edits, options.newFileContents, "move to new file");
|
||||
const editInfo = this.languageService.getEditsForRefactor(range.fileName, this.formatCodeSettings, range, refactor.name, action.name, options.preferences || ts.emptyOptions)!;
|
||||
this.verifyNewContent({ newFileContent: options.newFileContents }, editInfo.edits);
|
||||
}
|
||||
|
||||
private testNewFileContents(edits: ReadonlyArray<ts.FileTextChanges>, newFileContents: { [fileName: string]: string }, description: string): void {
|
||||
@@ -3165,21 +3154,21 @@ Actual: ${stringify(fullActual)}`);
|
||||
formattingOptions?: ts.FormatCodeSettings) {
|
||||
|
||||
formattingOptions = formattingOptions || this.formatCodeSettings;
|
||||
const markerPos = this.getMarkerByName(markerName).position;
|
||||
const marker = this.getMarkerByName(markerName);
|
||||
|
||||
const applicableRefactors = this.languageService.getApplicableRefactors(this.activeFile.fileName, markerPos, ts.emptyOptions);
|
||||
const applicableRefactors = this.languageService.getApplicableRefactors(this.activeFile.fileName, marker.position, ts.emptyOptions);
|
||||
const applicableRefactorToApply = ts.find(applicableRefactors, refactor => refactor.name === refactorNameToApply);
|
||||
|
||||
if (!applicableRefactorToApply) {
|
||||
this.raiseError(`The expected refactor: ${refactorNameToApply} is not available at the marker location.`);
|
||||
}
|
||||
|
||||
const editInfo = this.languageService.getEditsForRefactor(this.activeFile.fileName, formattingOptions, markerPos, refactorNameToApply, actionName, ts.emptyOptions)!;
|
||||
const editInfo = this.languageService.getEditsForRefactor(marker.fileName, formattingOptions, marker.position, refactorNameToApply, actionName, ts.emptyOptions)!;
|
||||
|
||||
for (const edit of editInfo.edits) {
|
||||
this.applyEdits(edit.fileName, edit.textChanges, /*isFormattingEdit*/ false);
|
||||
}
|
||||
const actualContent = this.getFileContent(this.activeFile.fileName);
|
||||
const actualContent = this.getFileContent(marker.fileName);
|
||||
|
||||
if (actualContent !== expectedContent) {
|
||||
this.raiseError(`verifyFileAfterApplyingRefactors failed:\n${showTextDiff(expectedContent, actualContent)}`);
|
||||
@@ -3381,9 +3370,45 @@ Actual: ${stringify(fullActual)}`);
|
||||
test(renameKeys(newFileContents, key => pathUpdater(key) || key), "with file moved");
|
||||
}
|
||||
|
||||
private getApplicableRefactors(positionOrRange: number | ts.TextRange, preferences = ts.emptyOptions): ReadonlyArray<ts.ApplicableRefactorInfo> {
|
||||
return this.languageService.getApplicableRefactors(this.activeFile.fileName, positionOrRange, preferences) || ts.emptyArray;
|
||||
private getApplicableRefactorsAtSelection() {
|
||||
return this.getApplicableRefactorsWorker(this.getSelection(), this.activeFile.fileName);
|
||||
}
|
||||
private getApplicableRefactors(rangeOrMarker: Range | Marker, preferences = ts.emptyOptions): ReadonlyArray<ts.ApplicableRefactorInfo> {
|
||||
return this.getApplicableRefactorsWorker("position" in rangeOrMarker ? rangeOrMarker.position : rangeOrMarker, rangeOrMarker.fileName, preferences);
|
||||
}
|
||||
private getApplicableRefactorsWorker(positionOrRange: number | ts.TextRange, fileName: string, preferences = ts.emptyOptions): ReadonlyArray<ts.ApplicableRefactorInfo> {
|
||||
return this.languageService.getApplicableRefactors(fileName, positionOrRange, preferences) || ts.emptyArray;
|
||||
}
|
||||
}
|
||||
|
||||
function updateTextRangeForTextChanges({ pos, end }: ts.TextRange, textChanges: ReadonlyArray<ts.TextChange>): ts.TextRange {
|
||||
forEachTextChange(textChanges, change => {
|
||||
const update = (p: number): number => updatePosition(p, change.span.start, ts.textSpanEnd(change.span), change.newText);
|
||||
pos = update(pos);
|
||||
end = update(end);
|
||||
});
|
||||
return { pos, end };
|
||||
}
|
||||
|
||||
/** Apply each textChange in order, updating future changes to account for the text offset of previous changes. */
|
||||
function forEachTextChange(changes: ReadonlyArray<ts.TextChange>, cb: (change: ts.TextChange) => void): void {
|
||||
// Copy this so we don't ruin someone else's copy
|
||||
changes = JSON.parse(JSON.stringify(changes));
|
||||
for (let i = 0; i < changes.length; i++) {
|
||||
const change = changes[i];
|
||||
cb(change);
|
||||
const changeDelta = change.newText.length - change.span.length;
|
||||
for (let j = i + 1; j < changes.length; j++) {
|
||||
if (changes[j].span.start >= change.span.start) {
|
||||
changes[j].span.start += changeDelta;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updatePosition(position: number, editStart: number, editEnd: number, { length }: string): number {
|
||||
// If inside the edit, return -1 to mark as invalid
|
||||
return position <= editStart ? position : position < editEnd ? -1 : position + length - + (editEnd - editStart);
|
||||
}
|
||||
|
||||
function renameKeys<T>(obj: { readonly [key: string]: T }, renameKey: (key: string) => string): { readonly [key: string]: T } {
|
||||
@@ -4848,10 +4873,12 @@ namespace FourSlashInterface {
|
||||
}
|
||||
|
||||
export interface VerifyCodeFixOptions extends NewContentOptions {
|
||||
description: string;
|
||||
errorCode?: number;
|
||||
index?: number;
|
||||
preferences?: ts.UserPreferences;
|
||||
readonly description: string;
|
||||
readonly errorCode?: number;
|
||||
readonly index?: number;
|
||||
readonly preferences?: ts.UserPreferences;
|
||||
readonly applyChanges?: boolean;
|
||||
readonly commands?: ReadonlyArray<ts.CodeActionCommand>;
|
||||
}
|
||||
|
||||
export interface VerifyCodeFixAvailableOptions {
|
||||
|
||||
+54
-77
@@ -1483,17 +1483,12 @@ namespace Harness {
|
||||
}
|
||||
|
||||
export function doErrorBaseline(baselinePath: string, inputFiles: ReadonlyArray<TestFile>, errors: ReadonlyArray<ts.Diagnostic>, pretty?: boolean) {
|
||||
Baseline.runBaseline(baselinePath.replace(/\.tsx?$/, ".errors.txt"), (): string | null => {
|
||||
if (!errors || (errors.length === 0)) {
|
||||
/* tslint:disable:no-null-keyword */
|
||||
return null;
|
||||
/* tslint:enable:no-null-keyword */
|
||||
}
|
||||
return getErrorBaseline(inputFiles, errors, pretty);
|
||||
});
|
||||
Baseline.runBaseline(baselinePath.replace(/\.tsx?$/, ".errors.txt"),
|
||||
// tslint:disable-next-line no-null-keyword
|
||||
!errors || (errors.length === 0) ? null : getErrorBaseline(inputFiles, errors, pretty));
|
||||
}
|
||||
|
||||
export function doTypeAndSymbolBaseline(baselinePath: string, program: ts.Program, allFiles: {unitName: string, content: string}[], opts?: Baseline.BaselineOptions, multifile?: boolean, skipTypeBaselines?: boolean, skipSymbolBaselines?: boolean) {
|
||||
export function doTypeAndSymbolBaseline(baselinePath: string, program: ts.Program, allFiles: {unitName: string, content: string}[], opts?: Baseline.BaselineOptions, multifile?: boolean, skipTypeBaselines?: boolean, skipSymbolBaselines?: boolean, hasErrorBaseline?: boolean) {
|
||||
// The full walker simulates the types that you would get from doing a full
|
||||
// compile. The pull walker simulates the types you get when you just do
|
||||
// a type query for a random node (like how the LS would do it). Most of the
|
||||
@@ -1509,7 +1504,7 @@ namespace Harness {
|
||||
// These types are equivalent, but depend on what order the compiler observed
|
||||
// certain parts of the program.
|
||||
|
||||
const fullWalker = new TypeWriterWalker(program, /*fullTypeCheck*/ true);
|
||||
const fullWalker = new TypeWriterWalker(program, /*fullTypeCheck*/ true, !!hasErrorBaseline);
|
||||
|
||||
// Produce baselines. The first gives the types for all expressions.
|
||||
// The second gives symbols for all identifiers.
|
||||
@@ -1552,7 +1547,7 @@ namespace Harness {
|
||||
|
||||
if (!multifile) {
|
||||
const fullBaseLine = generateBaseLine(isSymbolBaseLine, isSymbolBaseLine ? skipSymbolBaselines : skipTypeBaselines);
|
||||
Baseline.runBaseline(outputFileName + fullExtension, () => fullBaseLine, opts);
|
||||
Baseline.runBaseline(outputFileName + fullExtension, fullBaseLine, opts);
|
||||
}
|
||||
else {
|
||||
Baseline.runMultifileBaseline(outputFileName, fullExtension, () => {
|
||||
@@ -1637,22 +1632,21 @@ namespace Harness {
|
||||
throw new Error("Number of sourcemap files should be same as js files.");
|
||||
}
|
||||
|
||||
Baseline.runBaseline(baselinePath.replace(/\.tsx?/, ".js.map"), () => {
|
||||
if ((options.noEmitOnError && result.diagnostics.length !== 0) || result.maps.size === 0) {
|
||||
// We need to return null here or the runBaseLine will actually create a empty file.
|
||||
// Baselining isn't required here because there is no output.
|
||||
/* tslint:disable:no-null-keyword */
|
||||
return null;
|
||||
/* tslint:enable:no-null-keyword */
|
||||
}
|
||||
|
||||
let sourceMapCode = "";
|
||||
let sourceMapCode: string | null;
|
||||
if ((options.noEmitOnError && result.diagnostics.length !== 0) || result.maps.size === 0) {
|
||||
// We need to return null here or the runBaseLine will actually create a empty file.
|
||||
// Baselining isn't required here because there is no output.
|
||||
/* tslint:disable:no-null-keyword */
|
||||
sourceMapCode = null;
|
||||
/* tslint:enable:no-null-keyword */
|
||||
}
|
||||
else {
|
||||
sourceMapCode = "";
|
||||
result.maps.forEach(sourceMap => {
|
||||
sourceMapCode += fileOutput(sourceMap, harnessSettings);
|
||||
});
|
||||
|
||||
return sourceMapCode;
|
||||
});
|
||||
}
|
||||
Baseline.runBaseline(baselinePath.replace(/\.tsx?/, ".js.map"), sourceMapCode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1662,49 +1656,40 @@ namespace Harness {
|
||||
}
|
||||
|
||||
// check js output
|
||||
Baseline.runBaseline(baselinePath.replace(/\.tsx?/, ts.Extension.Js), () => {
|
||||
let tsCode = "";
|
||||
const tsSources = otherFiles.concat(toBeCompiled);
|
||||
if (tsSources.length > 1) {
|
||||
tsCode += "//// [" + header + "] ////\r\n\r\n";
|
||||
}
|
||||
for (let i = 0; i < tsSources.length; i++) {
|
||||
tsCode += "//// [" + ts.getBaseFileName(tsSources[i].unitName) + "]\r\n";
|
||||
tsCode += tsSources[i].content + (i < (tsSources.length - 1) ? "\r\n" : "");
|
||||
}
|
||||
let tsCode = "";
|
||||
const tsSources = otherFiles.concat(toBeCompiled);
|
||||
if (tsSources.length > 1) {
|
||||
tsCode += "//// [" + header + "] ////\r\n\r\n";
|
||||
}
|
||||
for (let i = 0; i < tsSources.length; i++) {
|
||||
tsCode += "//// [" + ts.getBaseFileName(tsSources[i].unitName) + "]\r\n";
|
||||
tsCode += tsSources[i].content + (i < (tsSources.length - 1) ? "\r\n" : "");
|
||||
}
|
||||
|
||||
let jsCode = "";
|
||||
result.js.forEach(file => {
|
||||
jsCode += fileOutput(file, harnessSettings);
|
||||
});
|
||||
|
||||
if (result.dts.size > 0) {
|
||||
jsCode += "\r\n\r\n";
|
||||
result.dts.forEach(declFile => {
|
||||
jsCode += fileOutput(declFile, harnessSettings);
|
||||
});
|
||||
}
|
||||
|
||||
const declFileContext = prepareDeclarationCompilationContext(
|
||||
toBeCompiled, otherFiles, result, harnessSettings, options, /*currentDirectory*/ undefined
|
||||
);
|
||||
const declFileCompilationResult = compileDeclarationFiles(declFileContext, result.symlinks);
|
||||
|
||||
if (declFileCompilationResult && declFileCompilationResult.declResult.diagnostics.length) {
|
||||
jsCode += "\r\n\r\n//// [DtsFileErrors]\r\n";
|
||||
jsCode += "\r\n\r\n";
|
||||
jsCode += getErrorBaseline(tsConfigFiles.concat(declFileCompilationResult.declInputFiles, declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.diagnostics);
|
||||
}
|
||||
|
||||
if (jsCode.length > 0) {
|
||||
return tsCode + "\r\n\r\n" + jsCode;
|
||||
}
|
||||
else {
|
||||
/* tslint:disable:no-null-keyword */
|
||||
return null;
|
||||
/* tslint:enable:no-null-keyword */
|
||||
}
|
||||
let jsCode = "";
|
||||
result.js.forEach(file => {
|
||||
jsCode += fileOutput(file, harnessSettings);
|
||||
});
|
||||
|
||||
if (result.dts.size > 0) {
|
||||
jsCode += "\r\n\r\n";
|
||||
result.dts.forEach(declFile => {
|
||||
jsCode += fileOutput(declFile, harnessSettings);
|
||||
});
|
||||
}
|
||||
|
||||
const declFileContext = prepareDeclarationCompilationContext(
|
||||
toBeCompiled, otherFiles, result, harnessSettings, options, /*currentDirectory*/ undefined
|
||||
);
|
||||
const declFileCompilationResult = compileDeclarationFiles(declFileContext, result.symlinks);
|
||||
|
||||
if (declFileCompilationResult && declFileCompilationResult.declResult.diagnostics.length) {
|
||||
jsCode += "\r\n\r\n//// [DtsFileErrors]\r\n";
|
||||
jsCode += "\r\n\r\n";
|
||||
jsCode += getErrorBaseline(tsConfigFiles.concat(declFileCompilationResult.declInputFiles, declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.diagnostics);
|
||||
}
|
||||
|
||||
Baseline.runBaseline(baselinePath.replace(/\.tsx?/, ts.Extension.Js), jsCode.length > 0 ? tsCode + "\r\n\r\n" + jsCode : null); // tslint:disable-line no-null-keyword
|
||||
}
|
||||
|
||||
function fileOutput(file: documents.TextDocument, harnessSettings: TestCaseParser.CompilerSettings): string {
|
||||
@@ -2027,16 +2012,6 @@ namespace Harness {
|
||||
}
|
||||
|
||||
const fileCache: { [idx: string]: boolean } = {};
|
||||
function generateActual(generateContent: () => string | null): string | null {
|
||||
|
||||
const actual = generateContent();
|
||||
|
||||
if (actual === undefined) {
|
||||
throw new Error("The generated content was \"undefined\". Return \"null\" if no baselining is required.\"");
|
||||
}
|
||||
|
||||
return actual;
|
||||
}
|
||||
|
||||
function compareToBaseline(actual: string | null, relativeFileName: string, opts: BaselineOptions | undefined) {
|
||||
// actual is now either undefined (the generator had an error), null (no file requested),
|
||||
@@ -2100,9 +2075,11 @@ namespace Harness {
|
||||
}
|
||||
}
|
||||
|
||||
export function runBaseline(relativeFileName: string, generateContent: () => string | null, opts?: BaselineOptions): void {
|
||||
export function runBaseline(relativeFileName: string, actual: string | null, opts?: BaselineOptions): void {
|
||||
const actualFileName = localPath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder);
|
||||
const actual = generateActual(generateContent);
|
||||
if (actual === undefined) {
|
||||
throw new Error("The generated content was \"undefined\". Return \"null\" if no baselining is required.\"");
|
||||
}
|
||||
const comparison = compareToBaseline(actual, relativeFileName, opts);
|
||||
writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ class TypeWriterWalker {
|
||||
|
||||
private checker: ts.TypeChecker;
|
||||
|
||||
constructor(private program: ts.Program, fullTypeCheck: boolean) {
|
||||
constructor(private program: ts.Program, fullTypeCheck: boolean, private hadErrorBaseline: boolean) {
|
||||
// Consider getting both the diagnostics checker and the non-diagnostics checker to verify
|
||||
// they are consistent.
|
||||
this.checker = fullTypeCheck
|
||||
@@ -69,6 +69,26 @@ class TypeWriterWalker {
|
||||
}
|
||||
}
|
||||
|
||||
private isImportStatementName(node: ts.Node) {
|
||||
if (ts.isImportSpecifier(node.parent) && (node.parent.name === node || node.parent.propertyName === node)) return true;
|
||||
if (ts.isImportClause(node.parent) && node.parent.name === node) return true;
|
||||
if (ts.isImportEqualsDeclaration(node.parent) && node.parent.name === node) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private isExportStatementName(node: ts.Node) {
|
||||
if (ts.isExportAssignment(node.parent) && node.parent.expression === node) return true;
|
||||
if (ts.isExportSpecifier(node.parent) && (node.parent.name === node || node.parent.propertyName === node)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private isIntrinsicJsxTag(node: ts.Node) {
|
||||
const p = node.parent;
|
||||
if (!(ts.isJsxOpeningElement(p) || ts.isJsxClosingElement(p) || ts.isJsxSelfClosingElement(p))) return false;
|
||||
if (p.tagName !== node) return false;
|
||||
return ts.isIntrinsicJsxName(node.getText());
|
||||
}
|
||||
|
||||
private writeTypeOrSymbol(node: ts.Node, isSymbolWalk: boolean): TypeWriterResult | undefined {
|
||||
const actualPos = ts.skipTrivia(this.currentSourceFile.text, node.pos);
|
||||
const lineAndCharacter = this.currentSourceFile.getLineAndCharacterOfPosition(actualPos);
|
||||
@@ -85,7 +105,31 @@ class TypeWriterWalker {
|
||||
// let type = this.checker.getTypeAtLocation(node);
|
||||
let type = ts.isExpressionWithTypeArgumentsInClassExtendsClause(node.parent) ? this.checker.getTypeAtLocation(node.parent) : undefined;
|
||||
if (!type || type.flags & ts.TypeFlags.Any) type = this.checker.getTypeAtLocation(node);
|
||||
const typeString = this.checker.typeToString(type, node.parent, ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.AllowUniqueESSymbolType);
|
||||
const typeString =
|
||||
// Distinguish `errorType`s from `any`s; but only if the file has no errors.
|
||||
// Additionally,
|
||||
// * the LHS of a qualified name
|
||||
// * a binding pattern name
|
||||
// * labels
|
||||
// * the "global" in "declare global"
|
||||
// * the "target" in "new.target"
|
||||
// * names in import statements
|
||||
// * type-only names in export statements
|
||||
// * and intrinsic jsx tag names
|
||||
// return `error`s via `getTypeAtLocation`
|
||||
// But this is generally expected, so we don't call those out, either
|
||||
(!this.hadErrorBaseline &&
|
||||
type.flags & ts.TypeFlags.Any &&
|
||||
!ts.isBindingElement(node.parent) &&
|
||||
!ts.isPropertyAccessOrQualifiedName(node.parent) &&
|
||||
!ts.isLabelName(node) &&
|
||||
!(ts.isModuleDeclaration(node.parent) && ts.isGlobalScopeAugmentation(node.parent)) &&
|
||||
!ts.isMetaProperty(node.parent) &&
|
||||
!this.isImportStatementName(node) &&
|
||||
!this.isExportStatementName(node) &&
|
||||
!this.isIntrinsicJsxTag(node)) ?
|
||||
(type as ts.IntrinsicType).intrinsicName :
|
||||
this.checker.typeToString(type, node.parent, ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.AllowUniqueESSymbolType);
|
||||
return {
|
||||
line: lineAndCharacter.line,
|
||||
syntaxKind: node.kind,
|
||||
|
||||
Vendored
+859
-805
File diff suppressed because it is too large
Load Diff
Vendored
+3
@@ -1019,6 +1019,7 @@ interface Event {
|
||||
*/
|
||||
readonly isTrusted: boolean;
|
||||
returnValue: boolean;
|
||||
readonly srcElement: object | null;
|
||||
/**
|
||||
* Returns the object to which event is dispatched (its target).
|
||||
*/
|
||||
@@ -2654,6 +2655,7 @@ interface WindowOrWorkerGlobalScope {
|
||||
createImageBitmap(image: ImageBitmapSource): Promise<ImageBitmap>;
|
||||
createImageBitmap(image: ImageBitmapSource, sx: number, sy: number, sw: number, sh: number): Promise<ImageBitmap>;
|
||||
fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
|
||||
queueMicrotask(callback: Function): void;
|
||||
setInterval(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
|
||||
setTimeout(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
|
||||
}
|
||||
@@ -2935,6 +2937,7 @@ declare function clearTimeout(handle?: number): void;
|
||||
declare function createImageBitmap(image: ImageBitmapSource): Promise<ImageBitmap>;
|
||||
declare function createImageBitmap(image: ImageBitmapSource, sx: number, sy: number, sw: number, sh: number): Promise<ImageBitmap>;
|
||||
declare function fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
|
||||
declare function queueMicrotask(callback: Function): void;
|
||||
declare function setInterval(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
|
||||
declare function setTimeout(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
|
||||
declare function addEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+153
-107
@@ -1,8 +1,11 @@
|
||||
namespace ts.server {
|
||||
export const maxProgramSizeForNonTsFiles = 20 * 1024 * 1024;
|
||||
/*@internal*/
|
||||
export const maxFileSize = 4 * 1024 * 1024;
|
||||
|
||||
// tslint:disable variable-name
|
||||
export const ProjectsUpdatedInBackgroundEvent = "projectsUpdatedInBackground";
|
||||
export const LargeFileReferencedEvent = "largeFileReferenced";
|
||||
export const ConfigFileDiagEvent = "configFileDiag";
|
||||
export const ProjectLanguageServiceStateEvent = "projectLanguageServiceState";
|
||||
export const ProjectInfoTelemetryEvent = "projectInfo";
|
||||
@@ -14,6 +17,11 @@ namespace ts.server {
|
||||
data: { openFiles: string[]; };
|
||||
}
|
||||
|
||||
export interface LargeFileReferencedEvent {
|
||||
eventName: typeof LargeFileReferencedEvent;
|
||||
data: { file: string; fileSize: number; maxFileSize: number; };
|
||||
}
|
||||
|
||||
export interface ConfigFileDiagEvent {
|
||||
eventName: typeof ConfigFileDiagEvent;
|
||||
data: { triggerFile: string, configFileName: string, diagnostics: ReadonlyArray<Diagnostic> };
|
||||
@@ -90,7 +98,7 @@ namespace ts.server {
|
||||
readonly checkJs: boolean;
|
||||
}
|
||||
|
||||
export type ProjectServiceEvent = ProjectsUpdatedInBackgroundEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent | OpenFileInfoTelemetryEvent;
|
||||
export type ProjectServiceEvent = LargeFileReferencedEvent | ProjectsUpdatedInBackgroundEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent | OpenFileInfoTelemetryEvent;
|
||||
|
||||
export type ProjectServiceEventHandler = (event: ProjectServiceEvent) => void;
|
||||
|
||||
@@ -337,10 +345,17 @@ namespace ts.server {
|
||||
return `Project: ${project ? project.getProjectName() : ""} WatchType: ${watchType}`;
|
||||
}
|
||||
|
||||
function updateProjectIfDirty(project: Project) {
|
||||
/*@internal*/
|
||||
export function updateProjectIfDirty(project: Project) {
|
||||
return project.dirty && project.updateGraph();
|
||||
}
|
||||
|
||||
function setProjectOptionsUsed(project: ConfiguredProject | ExternalProject) {
|
||||
if (project.projectKind === ProjectKind.Configured) {
|
||||
(project as ConfiguredProject).projectOptions = true;
|
||||
}
|
||||
}
|
||||
|
||||
export class ProjectService {
|
||||
|
||||
/*@internal*/
|
||||
@@ -617,7 +632,7 @@ namespace ts.server {
|
||||
this.pendingProjectUpdates.set(projectName, project);
|
||||
this.throttledOperations.schedule(projectName, /*delay*/ 250, () => {
|
||||
if (this.pendingProjectUpdates.delete(projectName)) {
|
||||
project.updateGraph();
|
||||
updateProjectIfDirty(project);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -642,6 +657,19 @@ namespace ts.server {
|
||||
this.eventHandler(event);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
sendLargeFileReferencedEvent(file: string, fileSize: number) {
|
||||
if (!this.eventHandler) {
|
||||
return;
|
||||
}
|
||||
|
||||
const event: LargeFileReferencedEvent = {
|
||||
eventName: LargeFileReferencedEvent,
|
||||
data: { file, fileSize, maxFileSize }
|
||||
};
|
||||
this.eventHandler(event);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(project: Project) {
|
||||
this.delayUpdateProjectGraph(project);
|
||||
@@ -1382,47 +1410,6 @@ namespace ts.server {
|
||||
return findProjectByName(projectFileName, this.externalProjects);
|
||||
}
|
||||
|
||||
private convertConfigFileContentToProjectOptions(configFilename: string, cachedDirectoryStructureHost: CachedDirectoryStructureHost) {
|
||||
configFilename = normalizePath(configFilename);
|
||||
|
||||
const configFileContent = this.host.readFile(configFilename)!; // TODO: GH#18217
|
||||
|
||||
const result = parseJsonText(configFilename, configFileContent);
|
||||
if (!result.endOfFileToken) {
|
||||
result.endOfFileToken = <EndOfFileToken>{ kind: SyntaxKind.EndOfFileToken };
|
||||
}
|
||||
const errors = result.parseDiagnostics as Diagnostic[];
|
||||
const parsedCommandLine = parseJsonSourceFileConfigFileContent(
|
||||
result,
|
||||
cachedDirectoryStructureHost,
|
||||
getDirectoryPath(configFilename),
|
||||
/*existingOptions*/ {},
|
||||
configFilename,
|
||||
/*resolutionStack*/[],
|
||||
this.hostConfiguration.extraFileExtensions);
|
||||
|
||||
if (parsedCommandLine.errors.length) {
|
||||
errors.push(...parsedCommandLine.errors);
|
||||
}
|
||||
|
||||
Debug.assert(!!parsedCommandLine.fileNames);
|
||||
|
||||
const projectOptions: ProjectOptions = {
|
||||
files: parsedCommandLine.fileNames,
|
||||
compilerOptions: parsedCommandLine.options,
|
||||
configHasExtendsProperty: parsedCommandLine.raw.extends !== undefined,
|
||||
configHasFilesProperty: parsedCommandLine.raw.files !== undefined,
|
||||
configHasIncludeProperty: parsedCommandLine.raw.include !== undefined,
|
||||
configHasExcludeProperty: parsedCommandLine.raw.exclude !== undefined,
|
||||
wildcardDirectories: createMapFromTemplate(parsedCommandLine.wildcardDirectories!), // TODO: GH#18217
|
||||
typeAcquisition: parsedCommandLine.typeAcquisition,
|
||||
compileOnSave: parsedCommandLine.compileOnSave,
|
||||
projectReferences: parsedCommandLine.projectReferences
|
||||
};
|
||||
|
||||
return { projectOptions, configFileErrors: errors, configFileSpecs: parsedCommandLine.configFileSpecs };
|
||||
}
|
||||
|
||||
/** Get a filename if the language service exceeds the maximum allowed program size; otherwise returns undefined. */
|
||||
private getFilenameForExceededTotalSizeLimitForNonTsFiles<T>(name: string, options: CompilerOptions | undefined, fileNames: T[], propertyReader: FilePropertyReader<T>): string | undefined {
|
||||
if (options && options.disableSizeLimit || !this.host.getFileSize) {
|
||||
@@ -1479,24 +1466,28 @@ namespace ts.server {
|
||||
options.compileOnSave === undefined ? true : options.compileOnSave);
|
||||
project.excludedFiles = excludedFiles;
|
||||
|
||||
this.addFilesToNonInferredProjectAndUpdateGraph(project, files, externalFilePropertyReader, typeAcquisition);
|
||||
this.addFilesToNonInferredProject(project, files, externalFilePropertyReader, typeAcquisition);
|
||||
this.externalProjects.push(project);
|
||||
this.sendProjectTelemetry(projectFileName, project);
|
||||
return project;
|
||||
}
|
||||
|
||||
private sendProjectTelemetry(projectKey: string, project: ExternalProject | ConfiguredProject, projectOptions?: ProjectOptions): void {
|
||||
if (this.seenProjects.has(projectKey)) {
|
||||
/*@internal*/
|
||||
sendProjectTelemetry(project: ExternalProject | ConfiguredProject): void {
|
||||
if (this.seenProjects.has(project.projectName)) {
|
||||
setProjectOptionsUsed(project);
|
||||
return;
|
||||
}
|
||||
this.seenProjects.set(projectKey, true);
|
||||
this.seenProjects.set(project.projectName, true);
|
||||
|
||||
if (!this.eventHandler || !this.host.createSHA256Hash) {
|
||||
setProjectOptionsUsed(project);
|
||||
return;
|
||||
}
|
||||
|
||||
const projectOptions = project.projectKind === ProjectKind.Configured ? (project as ConfiguredProject).projectOptions as ProjectOptions : undefined;
|
||||
setProjectOptionsUsed(project);
|
||||
const data: ProjectInfoTelemetryEventData = {
|
||||
projectId: this.host.createSHA256Hash(projectKey),
|
||||
projectId: this.host.createSHA256Hash(project.projectName),
|
||||
fileStats: countEachFileTypes(project.getScriptInfos()),
|
||||
compilerOptions: convertCompilerOptionsForTelemetry(project.getCompilationSettings()),
|
||||
typeAcquisition: convertTypeAcquisition(project.getTypeAcquisition()),
|
||||
@@ -1517,8 +1508,7 @@ namespace ts.server {
|
||||
return "other";
|
||||
}
|
||||
|
||||
const configFilePath = project instanceof ConfiguredProject ? project.getConfigFilePath() : undefined!; // TODO: GH#18217
|
||||
return getBaseConfigFileName(configFilePath) || "other";
|
||||
return getBaseConfigFileName(project.getConfigFilePath()) || "other";
|
||||
}
|
||||
|
||||
function convertTypeAcquisition({ enable, include, exclude }: TypeAcquisition): ProjectInfoTypeAcquisitionData {
|
||||
@@ -1530,30 +1520,19 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
private addFilesToNonInferredProjectAndUpdateGraph<T>(project: ConfiguredProject | ExternalProject, files: T[], propertyReader: FilePropertyReader<T>, typeAcquisition: TypeAcquisition): void {
|
||||
private addFilesToNonInferredProject<T>(project: ConfiguredProject | ExternalProject, files: T[], propertyReader: FilePropertyReader<T>, typeAcquisition: TypeAcquisition): void {
|
||||
this.updateNonInferredProjectFiles(project, files, propertyReader);
|
||||
project.setTypeAcquisition(typeAcquisition);
|
||||
// This doesnt need scheduling since its either creation or reload of the project
|
||||
project.updateGraph();
|
||||
}
|
||||
|
||||
private createConfiguredProject(configFileName: NormalizedPath) {
|
||||
const cachedDirectoryStructureHost = createCachedDirectoryStructureHost(this.host, this.host.getCurrentDirectory(), this.host.useCaseSensitiveFileNames)!; // TODO: GH#18217
|
||||
const { projectOptions, configFileErrors, configFileSpecs } = this.convertConfigFileContentToProjectOptions(configFileName, cachedDirectoryStructureHost);
|
||||
this.logger.info(`Opened configuration file ${configFileName}`);
|
||||
const lastFileExceededProgramSize = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(configFileName, projectOptions.compilerOptions, projectOptions.files!, fileNamePropertyReader); // TODO: GH#18217
|
||||
const project = new ConfiguredProject(
|
||||
configFileName,
|
||||
this,
|
||||
this.documentRegistry,
|
||||
projectOptions.configHasFilesProperty,
|
||||
projectOptions.compilerOptions!, // TODO: GH#18217
|
||||
lastFileExceededProgramSize,
|
||||
projectOptions.compileOnSave === undefined ? false : projectOptions.compileOnSave,
|
||||
cachedDirectoryStructureHost,
|
||||
projectOptions.projectReferences);
|
||||
|
||||
project.configFileSpecs = configFileSpecs;
|
||||
cachedDirectoryStructureHost);
|
||||
// TODO: We probably should also watch the configFiles that are extended
|
||||
project.configFileWatcher = this.watchFactory.watchFile(
|
||||
this.host,
|
||||
@@ -1563,19 +1542,82 @@ namespace ts.server {
|
||||
WatchType.ConfigFilePath,
|
||||
project
|
||||
);
|
||||
if (!lastFileExceededProgramSize) {
|
||||
project.watchWildcards(projectOptions.wildcardDirectories!); // TODO: GH#18217
|
||||
}
|
||||
|
||||
project.setProjectErrors(configFileErrors);
|
||||
const filesToAdd = projectOptions.files!.concat(project.getExternalFiles());
|
||||
this.addFilesToNonInferredProjectAndUpdateGraph(project, filesToAdd, fileNamePropertyReader, projectOptions.typeAcquisition!); // TODO: GH#18217
|
||||
this.configuredProjects.set(project.canonicalConfigFilePath, project);
|
||||
this.setConfigFileExistenceByNewConfiguredProject(project);
|
||||
this.sendProjectTelemetry(configFileName, project, projectOptions);
|
||||
return project;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
private createConfiguredProjectWithDelayLoad(configFileName: NormalizedPath) {
|
||||
const project = this.createConfiguredProject(configFileName);
|
||||
project.pendingReload = ConfigFileProgramReloadLevel.Full;
|
||||
return project;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
private createAndLoadConfiguredProject(configFileName: NormalizedPath) {
|
||||
const project = this.createConfiguredProject(configFileName);
|
||||
this.loadConfiguredProject(project);
|
||||
return project;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the config file of the project, and update the project root file names.
|
||||
*/
|
||||
/* @internal */
|
||||
private loadConfiguredProject(project: ConfiguredProject) {
|
||||
// Read updated contents from disk
|
||||
const configFilename = normalizePath(project.getConfigFilePath());
|
||||
|
||||
const configFileContent = this.host.readFile(configFilename)!; // TODO: GH#18217
|
||||
|
||||
const result = parseJsonText(configFilename, configFileContent);
|
||||
if (!result.endOfFileToken) {
|
||||
result.endOfFileToken = <EndOfFileToken>{ kind: SyntaxKind.EndOfFileToken };
|
||||
}
|
||||
const configFileErrors = result.parseDiagnostics as Diagnostic[];
|
||||
const parsedCommandLine = parseJsonSourceFileConfigFileContent(
|
||||
result,
|
||||
project.getCachedDirectoryStructureHost(),
|
||||
getDirectoryPath(configFilename),
|
||||
/*existingOptions*/ {},
|
||||
configFilename,
|
||||
/*resolutionStack*/[],
|
||||
this.hostConfiguration.extraFileExtensions);
|
||||
|
||||
if (parsedCommandLine.errors.length) {
|
||||
configFileErrors.push(...parsedCommandLine.errors);
|
||||
}
|
||||
|
||||
Debug.assert(!!parsedCommandLine.fileNames);
|
||||
const compilerOptions = parsedCommandLine.options;
|
||||
|
||||
// Update the project
|
||||
if (!project.projectOptions) {
|
||||
project.projectOptions = {
|
||||
configHasExtendsProperty: parsedCommandLine.raw.extends !== undefined,
|
||||
configHasFilesProperty: parsedCommandLine.raw.files !== undefined,
|
||||
configHasIncludeProperty: parsedCommandLine.raw.include !== undefined,
|
||||
configHasExcludeProperty: parsedCommandLine.raw.exclude !== undefined
|
||||
};
|
||||
}
|
||||
project.configFileSpecs = parsedCommandLine.configFileSpecs;
|
||||
project.setProjectErrors(configFileErrors);
|
||||
project.updateReferences(parsedCommandLine.projectReferences);
|
||||
const lastFileExceededProgramSize = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(project.canonicalConfigFilePath, compilerOptions, parsedCommandLine.fileNames, fileNamePropertyReader);
|
||||
if (lastFileExceededProgramSize) {
|
||||
project.disableLanguageService(lastFileExceededProgramSize);
|
||||
project.stopWatchingWildCards();
|
||||
}
|
||||
else {
|
||||
project.enableLanguageService();
|
||||
project.watchWildcards(createMapFromTemplate(parsedCommandLine.wildcardDirectories!)); // TODO: GH#18217
|
||||
}
|
||||
project.enablePluginsWithOptions(compilerOptions);
|
||||
const filesToAdd = parsedCommandLine.fileNames.concat(project.getExternalFiles());
|
||||
this.updateRootAndOptionsOfNonInferredProject(project, filesToAdd, fileNamePropertyReader, compilerOptions, parsedCommandLine.typeAcquisition!, parsedCommandLine.compileOnSave!); // TODO: GH#18217
|
||||
}
|
||||
|
||||
private updateNonInferredProjectFiles<T>(project: ExternalProject | ConfiguredProject, files: T[], propertyReader: FilePropertyReader<T>) {
|
||||
const projectRootFilesMap = project.getRootFilesMap();
|
||||
const newRootScriptInfoMap = createMap<ProjectRoot>();
|
||||
@@ -1634,31 +1676,31 @@ namespace ts.server {
|
||||
project.markAsDirty();
|
||||
}
|
||||
|
||||
private updateNonInferredProject<T>(project: ExternalProject | ConfiguredProject, newUncheckedFiles: T[], propertyReader: FilePropertyReader<T>, newOptions: CompilerOptions, newTypeAcquisition: TypeAcquisition, compileOnSave: boolean | undefined) {
|
||||
private updateRootAndOptionsOfNonInferredProject<T>(project: ExternalProject | ConfiguredProject, newUncheckedFiles: T[], propertyReader: FilePropertyReader<T>, newOptions: CompilerOptions, newTypeAcquisition: TypeAcquisition, compileOnSave: boolean | undefined) {
|
||||
project.setCompilerOptions(newOptions);
|
||||
// VS only set the CompileOnSaveEnabled option in the request if the option was changed recently
|
||||
// therefore if it is undefined, it should not be updated.
|
||||
if (compileOnSave !== undefined) {
|
||||
project.compileOnSaveEnabled = compileOnSave;
|
||||
}
|
||||
this.addFilesToNonInferredProjectAndUpdateGraph(project, newUncheckedFiles, propertyReader, newTypeAcquisition);
|
||||
this.addFilesToNonInferredProject(project, newUncheckedFiles, propertyReader, newTypeAcquisition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload the file names from config file specs and update the project graph
|
||||
*/
|
||||
/*@internal*/
|
||||
reloadFileNamesOfConfiguredProject(project: ConfiguredProject): boolean {
|
||||
reloadFileNamesOfConfiguredProject(project: ConfiguredProject) {
|
||||
const configFileSpecs = project.configFileSpecs!; // TODO: GH#18217
|
||||
const configFileName = project.getConfigFilePath();
|
||||
const fileNamesResult = getFileNamesFromConfigSpecs(configFileSpecs, getDirectoryPath(configFileName), project.getCompilationSettings(), project.getCachedDirectoryStructureHost(), this.hostConfiguration.extraFileExtensions);
|
||||
project.updateErrorOnNoInputFiles(fileNamesResult.fileNames.length !== 0);
|
||||
this.updateNonInferredProjectFiles(project, fileNamesResult.fileNames, fileNamePropertyReader);
|
||||
this.updateNonInferredProjectFiles(project, fileNamesResult.fileNames.concat(project.getExternalFiles()), fileNamePropertyReader);
|
||||
return project.updateGraph();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the config file of the project again and update the project
|
||||
* Read the config file of the project again by clearing the cache and update the project graph
|
||||
*/
|
||||
/* @internal */
|
||||
reloadConfiguredProject(project: ConfiguredProject) {
|
||||
@@ -1670,23 +1712,10 @@ namespace ts.server {
|
||||
const configFileName = project.getConfigFilePath();
|
||||
this.logger.info(`Reloading configured project ${configFileName}`);
|
||||
|
||||
// Read updated contents from disk
|
||||
const { projectOptions, configFileErrors, configFileSpecs } = this.convertConfigFileContentToProjectOptions(configFileName, host);
|
||||
// Load project from the disk
|
||||
this.loadConfiguredProject(project);
|
||||
project.updateGraph();
|
||||
|
||||
// Update the project
|
||||
project.configFileSpecs = configFileSpecs;
|
||||
project.setProjectErrors(configFileErrors);
|
||||
project.updateReferences(projectOptions.projectReferences);
|
||||
const lastFileExceededProgramSize = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(project.canonicalConfigFilePath, projectOptions.compilerOptions, projectOptions.files!, fileNamePropertyReader); // TODO: GH#18217
|
||||
if (lastFileExceededProgramSize) {
|
||||
project.disableLanguageService(lastFileExceededProgramSize);
|
||||
project.stopWatchingWildCards();
|
||||
}
|
||||
else {
|
||||
project.enableLanguageService();
|
||||
project.watchWildcards(projectOptions.wildcardDirectories!); // TODO: GH#18217
|
||||
}
|
||||
this.updateNonInferredProject(project, projectOptions.files!, fileNamePropertyReader, projectOptions.compilerOptions!, projectOptions.typeAcquisition!, projectOptions.compileOnSave!); // TODO: GH#18217
|
||||
this.sendConfigFileDiagEvent(project, configFileName);
|
||||
}
|
||||
|
||||
@@ -2018,17 +2047,14 @@ namespace ts.server {
|
||||
// otherwise we create a new one.
|
||||
const configFileName = this.getConfigFileNameForFile(info);
|
||||
if (configFileName) {
|
||||
const project = this.findConfiguredProjectByProjectName(configFileName);
|
||||
if (!project) {
|
||||
this.createConfiguredProject(configFileName);
|
||||
updatedProjects.set(configFileName, true);
|
||||
}
|
||||
else if (!updatedProjects.has(configFileName)) {
|
||||
const project = this.findConfiguredProjectByProjectName(configFileName) || this.createConfiguredProject(configFileName);
|
||||
if (!updatedProjects.has(configFileName)) {
|
||||
if (delayReload) {
|
||||
project.pendingReload = ConfigFileProgramReloadLevel.Full;
|
||||
this.delayUpdateProjectGraph(project);
|
||||
}
|
||||
else {
|
||||
// reload from the disk
|
||||
this.reloadConfiguredProject(project);
|
||||
}
|
||||
updatedProjects.set(configFileName, true);
|
||||
@@ -2116,7 +2142,7 @@ namespace ts.server {
|
||||
const configFileName = this.getConfigFileNameForFile(originalFileInfo);
|
||||
if (!configFileName) return undefined;
|
||||
|
||||
const configuredProject = this.findConfiguredProjectByProjectName(configFileName) || this.createConfiguredProject(configFileName);
|
||||
const configuredProject = this.findConfiguredProjectByProjectName(configFileName) || this.createAndLoadConfiguredProject(configFileName);
|
||||
updateProjectIfDirty(configuredProject);
|
||||
// Keep this configured project as referenced from project
|
||||
addOriginalConfiguredProject(configuredProject);
|
||||
@@ -2148,7 +2174,7 @@ namespace ts.server {
|
||||
private findExternalProjectContainingOpenScriptInfo(info: ScriptInfo): ExternalProject | undefined {
|
||||
return find(this.externalProjects, proj => {
|
||||
// Ensure project structure is up-to-date to check if info is present in external project
|
||||
proj.updateGraph();
|
||||
updateProjectIfDirty(proj);
|
||||
return proj.containsScriptInfo(info);
|
||||
});
|
||||
}
|
||||
@@ -2166,7 +2192,8 @@ namespace ts.server {
|
||||
if (configFileName) {
|
||||
project = this.findConfiguredProjectByProjectName(configFileName);
|
||||
if (!project) {
|
||||
project = this.createConfiguredProject(configFileName);
|
||||
project = this.createAndLoadConfiguredProject(configFileName);
|
||||
project.updateGraph();
|
||||
// Send the event only if the project got created as part of this open request and info is part of the project
|
||||
if (info.isOrphan()) {
|
||||
// Since the file isnt part of configured project, do not send config file info
|
||||
@@ -2242,6 +2269,20 @@ namespace ts.server {
|
||||
toRemoveConfiguredProjects.delete(project.canonicalConfigFilePath);
|
||||
markOriginalProjectsAsUsed(project);
|
||||
}
|
||||
else {
|
||||
// If the configured project for project reference has more than zero references, keep it alive
|
||||
const resolvedProjectReferences = project.getResolvedProjectReferences();
|
||||
if (resolvedProjectReferences) {
|
||||
for (const ref of resolvedProjectReferences) {
|
||||
if (ref) {
|
||||
const refProject = this.configuredProjects.get(ref.sourceFile.path);
|
||||
if (refProject && refProject.hasOpenRef()) {
|
||||
toRemoveConfiguredProjects.delete(project.canonicalConfigFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Remove all the non marked projects
|
||||
@@ -2542,7 +2583,9 @@ namespace ts.server {
|
||||
externalProject.enableLanguageService();
|
||||
}
|
||||
// external project already exists and not config files were added - update the project and return;
|
||||
this.updateNonInferredProject(externalProject, proj.rootFiles, externalFilePropertyReader, compilerOptions, proj.typeAcquisition, proj.options.compileOnSave);
|
||||
// The graph update here isnt postponed since any file open operation needs all updated external projects
|
||||
this.updateRootAndOptionsOfNonInferredProject(externalProject, proj.rootFiles, externalFilePropertyReader, compilerOptions, proj.typeAcquisition, proj.options.compileOnSave);
|
||||
externalProject.updateGraph();
|
||||
return;
|
||||
}
|
||||
// some config files were added to external project (that previously were not there)
|
||||
@@ -2589,8 +2632,8 @@ namespace ts.server {
|
||||
for (const tsconfigFile of tsConfigFiles) {
|
||||
let project = this.findConfiguredProjectByProjectName(tsconfigFile);
|
||||
if (!project) {
|
||||
// errors are stored in the project
|
||||
project = this.createConfiguredProject(tsconfigFile);
|
||||
// errors are stored in the project, do not need to update the graph
|
||||
project = this.createConfiguredProjectWithDelayLoad(tsconfigFile);
|
||||
}
|
||||
if (project && !contains(exisingConfigFiles, tsconfigFile)) {
|
||||
// keep project alive even if no documents are opened - its lifetime is bound to the lifetime of containing external project
|
||||
@@ -2600,8 +2643,11 @@ namespace ts.server {
|
||||
}
|
||||
else {
|
||||
// no config files - remove the item from the collection
|
||||
// Create external project and update its graph, do not delay update since
|
||||
// any file open operation needs all updated external projects
|
||||
this.externalProjectToConfiguredProjectMap.delete(proj.projectFileName);
|
||||
this.createExternalProject(proj.projectFileName, rootFiles, proj.options, proj.typeAcquisition, excludedFiles);
|
||||
const project = this.createExternalProject(proj.projectFileName, rootFiles, proj.options, proj.typeAcquisition, excludedFiles);
|
||||
project.updateGraph();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+59
-24
@@ -149,6 +149,8 @@ namespace ts.server {
|
||||
*/
|
||||
private projectStateVersion = 0;
|
||||
|
||||
protected isInitialLoadPending: () => boolean = returnFalse;
|
||||
|
||||
/*@internal*/
|
||||
dirty = false;
|
||||
|
||||
@@ -164,12 +166,12 @@ namespace ts.server {
|
||||
private readonly cancellationToken: ThrottledCancellationToken;
|
||||
|
||||
public isNonTsProject() {
|
||||
this.updateGraph();
|
||||
updateProjectIfDirty(this);
|
||||
return allFilesAreJsOrDts(this);
|
||||
}
|
||||
|
||||
public isJsOnlyProject() {
|
||||
this.updateGraph();
|
||||
updateProjectIfDirty(this);
|
||||
return hasOneOrMoreJsAndNoTsFiles(this);
|
||||
}
|
||||
|
||||
@@ -459,7 +461,7 @@ namespace ts.server {
|
||||
|
||||
getLanguageService(ensureSynchronized = true): LanguageService {
|
||||
if (ensureSynchronized) {
|
||||
this.updateGraph();
|
||||
updateProjectIfDirty(this);
|
||||
}
|
||||
return this.languageService;
|
||||
}
|
||||
@@ -477,7 +479,7 @@ namespace ts.server {
|
||||
if (!this.languageServiceEnabled) {
|
||||
return [];
|
||||
}
|
||||
this.updateGraph();
|
||||
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
|
||||
sourceFile => this.shouldEmitFile(this.projectService.getScriptInfoForPath(sourceFile.path)!) ? sourceFile.fileName : undefined);
|
||||
@@ -572,6 +574,14 @@ namespace ts.server {
|
||||
for (const f of this.program.getSourceFiles()) {
|
||||
this.detachScriptInfoIfNotRoot(f.fileName);
|
||||
}
|
||||
const projectReferences = this.program.getProjectReferences();
|
||||
if (projectReferences) {
|
||||
for (const ref of projectReferences) {
|
||||
if (ref) {
|
||||
this.detachScriptInfoFromProject(ref.sourceFile.fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Release external files
|
||||
forEach(this.externalFiles, externalFile => this.detachScriptInfoIfNotRoot(externalFile));
|
||||
@@ -1025,7 +1035,10 @@ namespace ts.server {
|
||||
|
||||
/* @internal */
|
||||
getChangesSinceVersion(lastKnownVersion?: number): ProjectFilesWithTSDiagnostics {
|
||||
this.updateGraph();
|
||||
// Update the graph only if initial configured project load is not pending
|
||||
if (!this.isInitialLoadPending()) {
|
||||
updateProjectIfDirty(this);
|
||||
}
|
||||
|
||||
const info: protocol.ProjectVersionInfo = {
|
||||
projectName: this.getProjectName(),
|
||||
@@ -1083,9 +1096,8 @@ namespace ts.server {
|
||||
this.rootFilesMap.delete(info.path);
|
||||
}
|
||||
|
||||
protected enableGlobalPlugins() {
|
||||
protected enableGlobalPlugins(options: CompilerOptions) {
|
||||
const host = this.projectService.host;
|
||||
const options = this.getCompilationSettings();
|
||||
|
||||
if (!host.require) {
|
||||
this.projectService.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded");
|
||||
@@ -1236,7 +1248,7 @@ namespace ts.server {
|
||||
if (!projectRootPath && !projectService.useSingleInferredProject) {
|
||||
this.canonicalCurrentDirectory = projectService.toCanonicalFileName(this.currentDirectory);
|
||||
}
|
||||
this.enableGlobalPlugins();
|
||||
this.enableGlobalPlugins(this.getCompilerOptions());
|
||||
}
|
||||
|
||||
addRoot(info: ScriptInfo) {
|
||||
@@ -1308,28 +1320,29 @@ namespace ts.server {
|
||||
|
||||
private projectErrors: Diagnostic[] | undefined;
|
||||
|
||||
private projectReferences: ReadonlyArray<ProjectReference> | undefined;
|
||||
|
||||
/*@internal*/
|
||||
projectOptions?: ProjectOptions | true;
|
||||
|
||||
protected isInitialLoadPending: () => boolean = returnTrue;
|
||||
|
||||
/*@internal*/
|
||||
constructor(configFileName: NormalizedPath,
|
||||
projectService: ProjectService,
|
||||
documentRegistry: DocumentRegistry,
|
||||
hasExplicitListOfFiles: boolean,
|
||||
compilerOptions: CompilerOptions,
|
||||
lastFileExceededProgramSize: string | undefined,
|
||||
public compileOnSaveEnabled: boolean,
|
||||
cachedDirectoryStructureHost: CachedDirectoryStructureHost,
|
||||
private projectReferences: ReadonlyArray<ProjectReference> | undefined) {
|
||||
cachedDirectoryStructureHost: CachedDirectoryStructureHost) {
|
||||
super(configFileName,
|
||||
ProjectKind.Configured,
|
||||
projectService,
|
||||
documentRegistry,
|
||||
hasExplicitListOfFiles,
|
||||
lastFileExceededProgramSize,
|
||||
compilerOptions,
|
||||
compileOnSaveEnabled,
|
||||
/*hasExplicitListOfFiles*/ false,
|
||||
/*lastFileExceededProgramSize*/ undefined,
|
||||
/*compilerOptions*/ {},
|
||||
/*compileOnSaveEnabled*/ false,
|
||||
cachedDirectoryStructureHost,
|
||||
getDirectoryPath(configFileName));
|
||||
this.canonicalConfigFilePath = asNormalizedPath(projectService.toCanonicalFileName(configFileName));
|
||||
this.enablePlugins();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1337,17 +1350,23 @@ namespace ts.server {
|
||||
* @returns: true if set of files in the project stays the same and false - otherwise.
|
||||
*/
|
||||
updateGraph(): boolean {
|
||||
this.isInitialLoadPending = returnFalse;
|
||||
const reloadLevel = this.pendingReload;
|
||||
this.pendingReload = ConfigFileProgramReloadLevel.None;
|
||||
let result: boolean;
|
||||
switch (reloadLevel) {
|
||||
case ConfigFileProgramReloadLevel.Partial:
|
||||
return this.projectService.reloadFileNamesOfConfiguredProject(this);
|
||||
result = this.projectService.reloadFileNamesOfConfiguredProject(this);
|
||||
break;
|
||||
case ConfigFileProgramReloadLevel.Full:
|
||||
this.projectService.reloadConfiguredProject(this);
|
||||
return true;
|
||||
result = true;
|
||||
break;
|
||||
default:
|
||||
return super.updateGraph();
|
||||
result = super.updateGraph();
|
||||
}
|
||||
this.projectService.sendProjectTelemetry(this);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
@@ -1367,9 +1386,19 @@ namespace ts.server {
|
||||
this.projectReferences = refs;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getResolvedProjectReferences() {
|
||||
const program = this.getCurrentProgram();
|
||||
return program && program.getProjectReferences();
|
||||
}
|
||||
|
||||
enablePlugins() {
|
||||
this.enablePluginsWithOptions(this.getCompilerOptions());
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
enablePluginsWithOptions(options: CompilerOptions) {
|
||||
const host = this.projectService.host;
|
||||
const options = this.getCompilationSettings();
|
||||
|
||||
if (!host.require) {
|
||||
this.projectService.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded");
|
||||
@@ -1393,7 +1422,7 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
this.enableGlobalPlugins();
|
||||
this.enableGlobalPlugins(options);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1533,6 +1562,12 @@ namespace ts.server {
|
||||
getDirectoryPath(projectFilePath || normalizeSlashes(externalProjectName)));
|
||||
}
|
||||
|
||||
updateGraph() {
|
||||
const result = super.updateGraph();
|
||||
this.projectService.sendProjectTelemetry(this);
|
||||
return result;
|
||||
}
|
||||
|
||||
getExcludedFiles() {
|
||||
return this.excludedFiles;
|
||||
}
|
||||
|
||||
+22
-1
@@ -1839,7 +1839,7 @@ namespace ts.server.protocol {
|
||||
* begin with prefix.
|
||||
*/
|
||||
export interface CompletionsRequest extends FileLocationRequest {
|
||||
command: CommandTypes.Completions;
|
||||
command: CommandTypes.Completions | CommandTypes.CompletionInfo;
|
||||
arguments: CompletionsRequestArgs;
|
||||
}
|
||||
|
||||
@@ -2436,6 +2436,27 @@ namespace ts.server.protocol {
|
||||
openFiles: string[];
|
||||
}
|
||||
|
||||
export type LargeFileReferencedEventName = "largeFileReferenced";
|
||||
export interface LargeFileReferencedEvent extends Event {
|
||||
event: LargeFileReferencedEventName;
|
||||
body: LargeFileReferencedEventBody;
|
||||
}
|
||||
|
||||
export interface LargeFileReferencedEventBody {
|
||||
/**
|
||||
* name of the large file being loaded
|
||||
*/
|
||||
file: string;
|
||||
/**
|
||||
* size of the file
|
||||
*/
|
||||
fileSize: number;
|
||||
/**
|
||||
* max file size allowed on the server
|
||||
*/
|
||||
maxFileSize: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Arguments for reload request.
|
||||
*/
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace ts.server {
|
||||
*/
|
||||
private pendingReloadFromDisk: boolean;
|
||||
|
||||
constructor(private readonly host: ServerHost, private readonly fileName: NormalizedPath, initialVersion?: ScriptInfoVersion) {
|
||||
constructor(private readonly host: ServerHost, private readonly fileName: NormalizedPath, initialVersion: ScriptInfoVersion | undefined, private readonly info: ScriptInfo) {
|
||||
this.version = initialVersion || { svc: 0, text: 0 };
|
||||
}
|
||||
|
||||
@@ -163,7 +163,21 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private getFileText(tempFileName?: string) {
|
||||
return this.host.readFile(tempFileName || this.fileName) || "";
|
||||
let text: string;
|
||||
const fileName = tempFileName || this.fileName;
|
||||
const getText = () => text === undefined ? (text = this.host.readFile(fileName) || "") : text;
|
||||
// Only non typescript files have size limitation
|
||||
if (!hasTypeScriptFileExtension(this.fileName)) {
|
||||
const fileSize = this.host.getFileSize ? this.host.getFileSize(fileName) : getText().length;
|
||||
if (fileSize > maxFileSize) {
|
||||
Debug.assert(!!this.info.containingProjects.length);
|
||||
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 getText();
|
||||
}
|
||||
|
||||
private switchToScriptVersionCache(): ScriptVersionCache {
|
||||
@@ -245,7 +259,7 @@ namespace ts.server {
|
||||
initialVersion?: ScriptInfoVersion) {
|
||||
this.isDynamic = isDynamicFileName(fileName);
|
||||
|
||||
this.textStorage = new TextStorage(host, fileName, initialVersion);
|
||||
this.textStorage = new TextStorage(host, fileName, initialVersion, this);
|
||||
if (hasMixedContent || this.isDynamic) {
|
||||
this.textStorage.reload("");
|
||||
this.realpath = this.path;
|
||||
@@ -456,12 +470,15 @@ namespace ts.server {
|
||||
if (this.isDynamicOrHasMixedContent()) {
|
||||
this.textStorage.reload("");
|
||||
this.markContainingProjectsAsDirty();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if (this.textStorage.reloadWithFileText(tempFileName)) {
|
||||
this.markContainingProjectsAsDirty();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
|
||||
@@ -559,6 +559,10 @@ namespace ts.server {
|
||||
const { openFiles } = event.data;
|
||||
this.projectsUpdatedInBackgroundEvent(openFiles);
|
||||
break;
|
||||
case LargeFileReferencedEvent:
|
||||
const { file, fileSize, maxFileSize } = event.data;
|
||||
this.event<protocol.LargeFileReferencedEventBody>({ file, fileSize, maxFileSize }, "largeFileReferenced");
|
||||
break;
|
||||
case ConfigFileDiagEvent:
|
||||
const { triggerFile, configFileName: configFile, diagnostics } = event.data;
|
||||
const bakedDiags = map(diagnostics, diagnostic => formatConfigFileDiag(diagnostic, /*includeFileName*/ true));
|
||||
@@ -695,7 +699,7 @@ namespace ts.server {
|
||||
const { fileName, project } = checkList[index];
|
||||
index++;
|
||||
// Ensure the project is upto date before checking if this file is present in the project
|
||||
project.updateGraph();
|
||||
updateProjectIfDirty(project);
|
||||
if (!project.containsFile(fileName, requireOpen)) {
|
||||
return;
|
||||
}
|
||||
@@ -1084,7 +1088,7 @@ namespace ts.server {
|
||||
|
||||
private getProjectInfoWorker(uncheckedFileName: string, projectFileName: string | undefined, needFileNameList: boolean, excludeConfigFiles: boolean) {
|
||||
const { project } = this.getFileAndProjectWorker(uncheckedFileName, projectFileName);
|
||||
project.updateGraph();
|
||||
updateProjectIfDirty(project);
|
||||
const projectInfo = {
|
||||
configFileName: project.getProjectName(),
|
||||
languageServiceDisabled: !project.languageServiceEnabled,
|
||||
|
||||
+1
-10
@@ -120,6 +120,7 @@ namespace ts.server {
|
||||
};
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export interface ProjectOptions {
|
||||
configHasExtendsProperty: boolean;
|
||||
/**
|
||||
@@ -128,16 +129,6 @@ namespace ts.server {
|
||||
configHasFilesProperty: boolean;
|
||||
configHasIncludeProperty: boolean;
|
||||
configHasExcludeProperty: boolean;
|
||||
|
||||
projectReferences: ReadonlyArray<ProjectReference> | undefined;
|
||||
/**
|
||||
* these fields can be present in the project file
|
||||
*/
|
||||
files?: string[];
|
||||
wildcardDirectories?: Map<WatchDirectoryFlags>;
|
||||
compilerOptions?: CompilerOptions;
|
||||
typeAcquisition?: TypeAcquisition;
|
||||
compileOnSave?: boolean;
|
||||
}
|
||||
|
||||
export function isInferredProjectName(name: string) {
|
||||
|
||||
@@ -0,0 +1,538 @@
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
const fixId = "convertToAsyncFunction";
|
||||
const errorCodes = [Diagnostics.This_may_be_converted_to_an_async_function.code];
|
||||
registerCodeFix({
|
||||
errorCodes,
|
||||
getCodeActions(context: CodeFixContext) {
|
||||
const changes = textChanges.ChangeTracker.with(context, (t) => convertToAsyncFunction(t, context.sourceFile, context.span.start, context.program.getTypeChecker(), context));
|
||||
return [createCodeFixAction(fixId, changes, Diagnostics.Convert_to_async_function, fixId, Diagnostics.Convert_all_to_async_functions)];
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, err) => convertToAsyncFunction(changes, err.file, err.start, context.program.getTypeChecker(), context)),
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
custom type to encapsulate information for variable declarations synthesized in the refactor
|
||||
numberOfUsesOriginal - number of times the variable should be assigned in the refactor
|
||||
numberOfUsesSynthesized - count of how many times the variable has been assigned so far
|
||||
At the end of the refactor, numberOfUsesOriginal should === numberOfUsesSynthesized
|
||||
*/
|
||||
interface SynthIdentifier {
|
||||
identifier: Identifier;
|
||||
types: Type[];
|
||||
numberOfAssignmentsOriginal: number;
|
||||
}
|
||||
|
||||
interface SymbolAndIdentifier {
|
||||
identifier: Identifier;
|
||||
symbol: Symbol;
|
||||
}
|
||||
|
||||
interface Transformer {
|
||||
checker: TypeChecker;
|
||||
synthNamesMap: Map<SynthIdentifier>; // keys are the symbol id of the identifier
|
||||
allVarNames: SymbolAndIdentifier[];
|
||||
setOfExpressionsToReturn: Map<true>; // keys are the node ids of the expressions
|
||||
constIdentifiers: Identifier[];
|
||||
originalTypeMap: Map<Type>; // keys are the node id of the identifier
|
||||
isInJSFile: boolean;
|
||||
}
|
||||
|
||||
function convertToAsyncFunction(changes: textChanges.ChangeTracker, sourceFile: SourceFile, position: number, checker: TypeChecker, context: CodeFixContextBase): void {
|
||||
// get the function declaration - returns a promise
|
||||
const functionToConvert: FunctionLikeDeclaration = getContainingFunction(getTokenAtPosition(sourceFile, position)) as FunctionLikeDeclaration;
|
||||
if (!functionToConvert) {
|
||||
return;
|
||||
}
|
||||
|
||||
const synthNamesMap: Map<SynthIdentifier> = createMap();
|
||||
const originalTypeMap: Map<Type> = createMap();
|
||||
const allVarNames: SymbolAndIdentifier[] = [];
|
||||
const isInJSFile = isInJavaScriptFile(functionToConvert);
|
||||
const setOfExpressionsToReturn = getAllPromiseExpressionsToReturn(functionToConvert, checker);
|
||||
const functionToConvertRenamed: FunctionLikeDeclaration = renameCollidingVarNames(functionToConvert, checker, synthNamesMap, context, setOfExpressionsToReturn, originalTypeMap, allVarNames);
|
||||
const constIdentifiers = getConstIdentifiers(synthNamesMap);
|
||||
const returnStatements = getReturnStatementsWithPromiseHandlers(functionToConvertRenamed);
|
||||
const transformer = { checker, synthNamesMap, allVarNames, setOfExpressionsToReturn, constIdentifiers, originalTypeMap, isInJSFile };
|
||||
|
||||
if (!returnStatements.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
// add the async keyword
|
||||
changes.insertModifierBefore(sourceFile, SyntaxKind.AsyncKeyword, functionToConvert);
|
||||
|
||||
function startTransformation(node: CallExpression, nodeToReplace: Node) {
|
||||
const newNodes = transformExpression(node, transformer, node);
|
||||
changes.replaceNodeWithNodes(sourceFile, nodeToReplace, newNodes);
|
||||
}
|
||||
|
||||
for (const statement of returnStatements) {
|
||||
if (isCallExpression(statement)) {
|
||||
startTransformation(statement, statement);
|
||||
}
|
||||
else {
|
||||
forEachChild(statement, function visit(node: Node) {
|
||||
if (isCallExpression(node)) {
|
||||
startTransformation(node, statement);
|
||||
}
|
||||
else if (!isFunctionLike(node)) {
|
||||
forEachChild(node, visit);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the identifiers that are never reassigned in the refactor
|
||||
function getConstIdentifiers(synthNamesMap: Map<SynthIdentifier>): Identifier[] {
|
||||
const constIdentifiers: Identifier[] = [];
|
||||
synthNamesMap.forEach((val) => {
|
||||
if (val.numberOfAssignmentsOriginal === 0) {
|
||||
constIdentifiers.push(val.identifier);
|
||||
}
|
||||
});
|
||||
return constIdentifiers;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Finds all of the expressions of promise type that should not be saved in a variable during the refactor
|
||||
*/
|
||||
function getAllPromiseExpressionsToReturn(func: FunctionLikeDeclaration, checker: TypeChecker): Map<true> {
|
||||
if (!func.body) {
|
||||
return createMap<true>();
|
||||
}
|
||||
|
||||
const setOfExpressionsToReturn: Map<true> = createMap<true>();
|
||||
|
||||
forEachChild(func.body, function visit(node: Node) {
|
||||
if (isPromiseReturningExpression(node, checker, "then")) {
|
||||
setOfExpressionsToReturn.set(getNodeId(node).toString(), true);
|
||||
forEach((<CallExpression>node).arguments, visit);
|
||||
}
|
||||
else if (isPromiseReturningExpression(node, checker, "catch")) {
|
||||
setOfExpressionsToReturn.set(getNodeId(node).toString(), true);
|
||||
// if .catch() is the last call in the chain, move leftward in the chain until we hit something else that should be returned
|
||||
forEachChild(node, visit);
|
||||
}
|
||||
else if (isPromiseReturningExpression(node, checker)) {
|
||||
setOfExpressionsToReturn.set(getNodeId(node).toString(), true);
|
||||
// don't recurse here, since we won't refactor any children or arguments of the expression
|
||||
}
|
||||
else {
|
||||
forEachChild(node, visit);
|
||||
}
|
||||
});
|
||||
|
||||
return setOfExpressionsToReturn;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Returns true if node is a promise returning expression
|
||||
If name is not undefined, node is a promise returning call of name
|
||||
*/
|
||||
function isPromiseReturningExpression(node: Node, checker: TypeChecker, name?: string): boolean {
|
||||
const isNodeExpression = name ? isCallExpression(node) : isExpression(node);
|
||||
const isExpressionOfName = isNodeExpression && (!name || hasPropertyAccessExpressionWithName(node as CallExpression, name));
|
||||
const nodeType = isExpressionOfName && checker.getTypeAtLocation(node);
|
||||
return !!(nodeType && checker.getPromisedTypeOfPromise(nodeType));
|
||||
}
|
||||
|
||||
function declaredInFile(symbol: Symbol, sourceFile: SourceFile): boolean {
|
||||
return symbol.valueDeclaration && symbol.valueDeclaration.getSourceFile() === sourceFile;
|
||||
}
|
||||
|
||||
/*
|
||||
Renaming of identifiers may be neccesary as the refactor changes scopes -
|
||||
This function collects all existing identifier names and names of identifiers that will be created in the refactor.
|
||||
It then checks for any collisions and renames them through getSynthesizedDeepClone
|
||||
*/
|
||||
function renameCollidingVarNames(nodeToRename: FunctionLikeDeclaration, checker: TypeChecker, synthNamesMap: Map<SynthIdentifier>, context: CodeFixContextBase, setOfAllExpressionsToReturn: Map<true>, originalType: Map<Type>, allVarNames: SymbolAndIdentifier[]): FunctionLikeDeclaration {
|
||||
|
||||
const identsToRenameMap: Map<Identifier> = createMap(); // key is the symbol id
|
||||
forEachChild(nodeToRename, function visit(node: Node) {
|
||||
if (!isIdentifier(node)) {
|
||||
forEachChild(node, visit);
|
||||
return;
|
||||
}
|
||||
|
||||
const symbol = checker.getSymbolAtLocation(node);
|
||||
const isDefinedInFile = symbol && declaredInFile(symbol, context.sourceFile);
|
||||
|
||||
if (symbol && isDefinedInFile) {
|
||||
const type = checker.getTypeAtLocation(node);
|
||||
const lastCallSignature = getLastCallSignature(type, checker);
|
||||
const symbolIdString = getSymbolId(symbol).toString();
|
||||
|
||||
// if the identifier refers to a function we want to add the new synthesized variable for the declaration (ex. blob in let blob = res(arg))
|
||||
// Note - the choice of the last call signature is arbitrary
|
||||
if (lastCallSignature && lastCallSignature.parameters.length && !synthNamesMap.has(symbolIdString)) {
|
||||
const synthName = getNewNameIfConflict(createIdentifier(lastCallSignature.parameters[0].name), allVarNames);
|
||||
synthNamesMap.set(symbolIdString, synthName);
|
||||
allVarNames.push({ identifier: synthName.identifier, symbol });
|
||||
}
|
||||
// we only care about identifiers that are parameters and declarations (don't care about other uses)
|
||||
else if (node.parent && (isParameter(node.parent) || isVariableDeclaration(node.parent))) {
|
||||
|
||||
// if the identifier name conflicts with a different identifier that we've already seen
|
||||
if (allVarNames.some(ident => ident.identifier.text === node.text && ident.symbol !== symbol)) {
|
||||
const newName = getNewNameIfConflict(node, allVarNames);
|
||||
identsToRenameMap.set(symbolIdString, newName.identifier);
|
||||
synthNamesMap.set(symbolIdString, newName);
|
||||
allVarNames.push({ identifier: newName.identifier, symbol });
|
||||
}
|
||||
else {
|
||||
const identifier = getSynthesizedDeepClone(node);
|
||||
identsToRenameMap.set(symbolIdString, identifier);
|
||||
synthNamesMap.set(symbolIdString, { identifier, types: [], numberOfAssignmentsOriginal: allVarNames.filter(elem => elem.identifier.text === node.text).length/*, numberOfAssignmentsSynthesized: 0*/ });
|
||||
if ((isParameter(node.parent) && isExpressionOrCallOnTypePromise(node.parent.parent)) || isVariableDeclaration(node.parent)) {
|
||||
allVarNames.push({ identifier, symbol });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return getSynthesizedDeepCloneWithRenames(nodeToRename, /*includeTrivia*/ true, identsToRenameMap, checker, deepCloneCallback);
|
||||
|
||||
function isExpressionOrCallOnTypePromise(child: Node): boolean {
|
||||
const node = child.parent;
|
||||
if (isCallExpression(node) || isIdentifier(node) && !setOfAllExpressionsToReturn.get(getNodeId(node).toString())) {
|
||||
const nodeType = checker.getTypeAtLocation(node);
|
||||
const isPromise = nodeType && checker.getPromisedTypeOfPromise(nodeType);
|
||||
return !!isPromise;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function deepCloneCallback(node: Node, clone: Node) {
|
||||
if (isIdentifier(node)) {
|
||||
const symbol = checker.getSymbolAtLocation(node);
|
||||
const symboldIdString = symbol && getSymbolId(symbol).toString();
|
||||
const renameInfo = symbol && synthNamesMap.get(symboldIdString!);
|
||||
|
||||
if (renameInfo) {
|
||||
const type = checker.getTypeAtLocation(node);
|
||||
if (type) {
|
||||
originalType.set(getNodeId(clone).toString(), type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const val = setOfAllExpressionsToReturn.get(getNodeId(node).toString());
|
||||
if (val !== undefined) {
|
||||
setOfAllExpressionsToReturn.delete(getNodeId(node).toString());
|
||||
setOfAllExpressionsToReturn.set(getNodeId(clone).toString(), val);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function getNewNameIfConflict(name: Identifier, allVarNames: SymbolAndIdentifier[]): SynthIdentifier {
|
||||
const numVarsSameName = allVarNames.filter(elem => elem.identifier.text === name.text).length;
|
||||
const numberOfAssignmentsOriginal = 0;
|
||||
const identifier = numVarsSameName === 0 ? name : createIdentifier(name.text + "_" + numVarsSameName);
|
||||
return { identifier, types: [], numberOfAssignmentsOriginal };
|
||||
}
|
||||
|
||||
// dispatch function to recursively build the refactoring
|
||||
function transformExpression(node: Expression, transformer: Transformer, outermostParent: CallExpression, prevArgName?: SynthIdentifier): Statement[] {
|
||||
if (!node) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const originalType = isIdentifier(node) && transformer.originalTypeMap.get(getNodeId(node).toString());
|
||||
const nodeType = originalType || transformer.checker.getTypeAtLocation(node);
|
||||
|
||||
if (isCallExpression(node) && hasPropertyAccessExpressionWithName(node, "then") && nodeType && !!transformer.checker.getPromisedTypeOfPromise(nodeType)) {
|
||||
return transformThen(node, transformer, outermostParent, prevArgName);
|
||||
}
|
||||
else if (isCallExpression(node) && hasPropertyAccessExpressionWithName(node, "catch") && nodeType && !!transformer.checker.getPromisedTypeOfPromise(nodeType)) {
|
||||
return transformCatch(node, transformer, prevArgName);
|
||||
}
|
||||
else if (isPropertyAccessExpression(node)) {
|
||||
return transformExpression(node.expression, transformer, outermostParent, prevArgName);
|
||||
}
|
||||
else if (nodeType && transformer.checker.getPromisedTypeOfPromise(nodeType)) {
|
||||
return transformPromiseCall(node, transformer, prevArgName);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
function transformCatch(node: CallExpression, transformer: Transformer, prevArgName?: SynthIdentifier): Statement[] {
|
||||
const func = node.arguments[0];
|
||||
const argName = getArgName(func, transformer);
|
||||
const shouldReturn = transformer.setOfExpressionsToReturn.get(getNodeId(node).toString());
|
||||
|
||||
/*
|
||||
If there is another call in the chain after the .catch() we are transforming, we will need to save the result of both paths (try block and catch block)
|
||||
To do this, we will need to synthesize a variable that we were not aware of while we were adding identifiers to the synthNamesMap
|
||||
We will use the prevArgName and then update the synthNamesMap with a new variable name for the next transformation step
|
||||
*/
|
||||
if (prevArgName && !shouldReturn) {
|
||||
prevArgName.numberOfAssignmentsOriginal = 2; // Try block and catch block
|
||||
transformer.synthNamesMap.forEach((val, key) => {
|
||||
if (val.identifier.text === prevArgName.identifier.text) {
|
||||
transformer.synthNamesMap.set(key, getNewNameIfConflict(prevArgName.identifier, transformer.allVarNames));
|
||||
}
|
||||
});
|
||||
|
||||
// update the constIdentifiers list
|
||||
if (transformer.constIdentifiers.some(elem => elem.text === prevArgName.identifier.text)) {
|
||||
transformer.constIdentifiers.push(getNewNameIfConflict(prevArgName.identifier, transformer.allVarNames).identifier);
|
||||
}
|
||||
}
|
||||
|
||||
const tryBlock = createBlock(transformExpression(node.expression, transformer, node, prevArgName));
|
||||
|
||||
const transformationBody = getTransformationBody(func, prevArgName, argName, node, transformer);
|
||||
const catchArg = argName.identifier.text.length > 0 ? argName.identifier.text : "e";
|
||||
const catchClause = createCatchClause(catchArg, createBlock(transformationBody));
|
||||
|
||||
/*
|
||||
In order to avoid an implicit any, we will synthesize a type for the declaration using the unions of the types of both paths (try block and catch block)
|
||||
*/
|
||||
let varDeclList;
|
||||
if (prevArgName && !shouldReturn) {
|
||||
const typeArray: Type[] = prevArgName.types;
|
||||
const unionType = transformer.checker.getUnionType(typeArray, UnionReduction.Subtype);
|
||||
const unionTypeNode = transformer.isInJSFile ? undefined : transformer.checker.typeToTypeNode(unionType);
|
||||
const varDecl = [createVariableDeclaration(getSynthesizedDeepClone(prevArgName.identifier), unionTypeNode)];
|
||||
varDeclList = createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList(varDecl, NodeFlags.Let));
|
||||
}
|
||||
|
||||
const tryStatement = createTry(tryBlock, catchClause, /*finallyBlock*/ undefined);
|
||||
return varDeclList ? [varDeclList, tryStatement] : [tryStatement];
|
||||
}
|
||||
|
||||
function transformThen(node: CallExpression, transformer: Transformer, outermostParent: CallExpression, prevArgName?: SynthIdentifier): Statement[] {
|
||||
const [res, rej] = node.arguments;
|
||||
|
||||
if (!res) {
|
||||
return transformExpression(node.expression, transformer, outermostParent);
|
||||
}
|
||||
|
||||
const argNameRes = getArgName(res, transformer);
|
||||
const transformationBody = getTransformationBody(res, prevArgName, argNameRes, node, transformer);
|
||||
|
||||
if (rej) {
|
||||
const argNameRej = getArgName(rej, transformer);
|
||||
|
||||
const tryBlock = createBlock(transformExpression(node.expression, transformer, node, argNameRes).concat(transformationBody));
|
||||
|
||||
const transformationBody2 = getTransformationBody(rej, prevArgName, argNameRej, node, transformer);
|
||||
|
||||
const catchArg = argNameRej.identifier.text.length > 0 ? argNameRej.identifier.text : "e";
|
||||
const catchClause = createCatchClause(catchArg, createBlock(transformationBody2));
|
||||
|
||||
return [createTry(tryBlock, catchClause, /* finallyBlock */ undefined) as Statement];
|
||||
}
|
||||
else {
|
||||
return transformExpression(node.expression, transformer, node, argNameRes).concat(transformationBody);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
function getFlagOfIdentifier(node: Identifier, constIdentifiers: Identifier[]): NodeFlags {
|
||||
const inArr: boolean = constIdentifiers.some(elem => elem.text === node.text);
|
||||
return inArr ? NodeFlags.Const : NodeFlags.Let;
|
||||
}
|
||||
|
||||
function transformPromiseCall(node: Expression, transformer: Transformer, prevArgName?: SynthIdentifier): Statement[] {
|
||||
const shouldReturn = transformer.setOfExpressionsToReturn.get(getNodeId(node).toString());
|
||||
// the identifier is empty when the handler (.then()) ignores the argument - In this situation we do not need to save the result of the promise returning call
|
||||
const hasPrevArgName = prevArgName && prevArgName.identifier.text.length > 0;
|
||||
const originalNodeParent = node.original ? node.original.parent : node.parent;
|
||||
if (hasPrevArgName && !shouldReturn && (!originalNodeParent || isPropertyAccessExpression(originalNodeParent))) {
|
||||
return createVariableDeclarationOrAssignment(prevArgName!, createAwait(node), transformer).concat(); // hack to make the types match
|
||||
}
|
||||
else if (!hasPrevArgName && !shouldReturn && (!originalNodeParent || isPropertyAccessExpression(originalNodeParent))) {
|
||||
return [createStatement(createAwait(node))];
|
||||
}
|
||||
|
||||
return [createReturn(getSynthesizedDeepClone(node))];
|
||||
}
|
||||
|
||||
function createVariableDeclarationOrAssignment(prevArgName: SynthIdentifier, rightHandSide: Expression, transformer: Transformer): NodeArray<Statement> {
|
||||
|
||||
if (prevArgName.types.length < prevArgName.numberOfAssignmentsOriginal) {
|
||||
return createNodeArray([createStatement(createAssignment(getSynthesizedDeepClone(prevArgName.identifier), rightHandSide))]);
|
||||
}
|
||||
|
||||
return createNodeArray([createVariableStatement(/*modifiers*/ undefined,
|
||||
(createVariableDeclarationList([createVariableDeclaration(getSynthesizedDeepClone(prevArgName.identifier), /*type*/ undefined, rightHandSide)], getFlagOfIdentifier(prevArgName.identifier, transformer.constIdentifiers))))]);
|
||||
}
|
||||
|
||||
function getTransformationBody(func: Node, prevArgName: SynthIdentifier | undefined, argName: SynthIdentifier, parent: CallExpression, transformer: Transformer): NodeArray<Statement> {
|
||||
|
||||
const hasPrevArgName = prevArgName && prevArgName.identifier.text.length > 0;
|
||||
const hasArgName = argName && argName.identifier.text.length > 0;
|
||||
const shouldReturn = transformer.setOfExpressionsToReturn.get(getNodeId(parent).toString());
|
||||
switch (func.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
if (!hasArgName) break;
|
||||
|
||||
const synthCall = createCall(getSynthesizedDeepClone(func) as Identifier, /*typeArguments*/ undefined, [argName.identifier]);
|
||||
if (shouldReturn) {
|
||||
return createNodeArray([createReturn(synthCall)]);
|
||||
}
|
||||
|
||||
if (!hasPrevArgName) break;
|
||||
|
||||
const type = transformer.originalTypeMap.get(getNodeId(func).toString());
|
||||
const callSignatures = type && transformer.checker.getSignaturesOfType(type, SignatureKind.Call);
|
||||
const returnType = callSignatures && callSignatures[0].getReturnType();
|
||||
const varDeclOrAssignment = createVariableDeclarationOrAssignment(prevArgName!, createAwait(synthCall), transformer);
|
||||
prevArgName!.types.push(returnType!);
|
||||
return varDeclOrAssignment;
|
||||
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
// Arrow functions with block bodies { } will enter this control flow
|
||||
if (isFunctionLikeDeclaration(func) && func.body && isBlock(func.body) && func.body.statements) {
|
||||
let refactoredStmts: Statement[] = [];
|
||||
|
||||
for (const statement of func.body.statements) {
|
||||
if (getReturnStatementsWithPromiseHandlers(statement).length) {
|
||||
refactoredStmts = refactoredStmts.concat(getInnerTransformationBody(transformer, [statement], prevArgName));
|
||||
}
|
||||
else {
|
||||
refactoredStmts.push(statement);
|
||||
}
|
||||
}
|
||||
|
||||
return shouldReturn ? getSynthesizedDeepClones(createNodeArray(refactoredStmts)) :
|
||||
removeReturns(createNodeArray(refactoredStmts), prevArgName!.identifier, transformer.constIdentifiers);
|
||||
}
|
||||
else {
|
||||
const funcBody = (<ArrowFunction>func).body;
|
||||
const innerRetStmts = getReturnStatementsWithPromiseHandlers(createReturn(funcBody as Expression));
|
||||
const innerCbBody = getInnerTransformationBody(transformer, innerRetStmts, prevArgName);
|
||||
|
||||
if (innerCbBody.length > 0) {
|
||||
return createNodeArray(innerCbBody);
|
||||
}
|
||||
|
||||
if (hasPrevArgName && !shouldReturn) {
|
||||
const type = transformer.checker.getTypeAtLocation(func);
|
||||
const returnType = getLastCallSignature(type, transformer.checker).getReturnType();
|
||||
const varDeclOrAssignment = createVariableDeclarationOrAssignment(prevArgName!, getSynthesizedDeepClone(funcBody) as Expression, transformer);
|
||||
prevArgName!.types.push(returnType);
|
||||
return varDeclOrAssignment;
|
||||
}
|
||||
else {
|
||||
return createNodeArray([createReturn(getSynthesizedDeepClone(funcBody) as Expression)]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return createNodeArray([]);
|
||||
}
|
||||
|
||||
function getLastCallSignature(type: Type, checker: TypeChecker): Signature {
|
||||
const callSignatures = type && checker.getSignaturesOfType(type, SignatureKind.Call);
|
||||
return callSignatures && callSignatures[callSignatures.length - 1];
|
||||
}
|
||||
|
||||
|
||||
function removeReturns(stmts: NodeArray<Statement>, prevArgName: Identifier, constIdentifiers: Identifier[]): NodeArray<Statement> {
|
||||
const ret: Statement[] = [];
|
||||
for (const stmt of stmts) {
|
||||
if (isReturnStatement(stmt)) {
|
||||
if (stmt.expression) {
|
||||
ret.push(createVariableStatement(/*modifiers*/ undefined,
|
||||
(createVariableDeclarationList([createVariableDeclaration(prevArgName, /*type*/ undefined, stmt.expression)], getFlagOfIdentifier(prevArgName, constIdentifiers)))));
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret.push(getSynthesizedDeepClone(stmt));
|
||||
}
|
||||
}
|
||||
|
||||
return createNodeArray(ret);
|
||||
}
|
||||
|
||||
|
||||
function getInnerTransformationBody(transformer: Transformer, innerRetStmts: Node[], prevArgName?: SynthIdentifier) {
|
||||
|
||||
let innerCbBody: Statement[] = [];
|
||||
for (const stmt of innerRetStmts) {
|
||||
forEachChild(stmt, function visit(node: Node) {
|
||||
if (isCallExpression(node)) {
|
||||
const temp = transformExpression(node, transformer, node, prevArgName);
|
||||
innerCbBody = innerCbBody.concat(temp);
|
||||
if (innerCbBody.length > 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!isFunctionLike(node)) {
|
||||
forEachChild(node, visit);
|
||||
}
|
||||
});
|
||||
}
|
||||
return innerCbBody;
|
||||
}
|
||||
|
||||
function hasPropertyAccessExpressionWithName(node: CallExpression, funcName: string): boolean {
|
||||
if (!isPropertyAccessExpression(node.expression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return node.expression.name.text === funcName;
|
||||
}
|
||||
|
||||
function getArgName(funcNode: Node, transformer: Transformer): SynthIdentifier {
|
||||
|
||||
const numberOfAssignmentsOriginal = 0;
|
||||
const types: Type[] = [];
|
||||
|
||||
let name: SynthIdentifier | undefined;
|
||||
|
||||
if (isFunctionLikeDeclaration(funcNode)) {
|
||||
if (funcNode.parameters.length > 0) {
|
||||
const param = funcNode.parameters[0].name as Identifier;
|
||||
name = getMapEntryIfExists(param);
|
||||
}
|
||||
}
|
||||
else if (isCallExpression(funcNode) && funcNode.arguments.length > 0 && isIdentifier(funcNode.arguments[0])) {
|
||||
name = { identifier: funcNode.arguments[0] as Identifier, types, numberOfAssignmentsOriginal };
|
||||
}
|
||||
else if (isIdentifier(funcNode)) {
|
||||
name = getMapEntryIfExists(funcNode);
|
||||
}
|
||||
|
||||
if (!name || name.identifier === undefined || name.identifier.text === "_" || name.identifier.text === "undefined") {
|
||||
return { identifier: createIdentifier(""), types, numberOfAssignmentsOriginal };
|
||||
}
|
||||
|
||||
return name;
|
||||
|
||||
function getMapEntryIfExists(identifier: Identifier): SynthIdentifier {
|
||||
const originalNode = getOriginalNode(identifier);
|
||||
const symbol = getSymbol(originalNode);
|
||||
|
||||
if (!symbol) {
|
||||
return { identifier, types, numberOfAssignmentsOriginal };
|
||||
}
|
||||
|
||||
const mapEntry = transformer.synthNamesMap.get(getSymbolId(symbol).toString());
|
||||
return mapEntry || { identifier, types, numberOfAssignmentsOriginal };
|
||||
}
|
||||
|
||||
function getSymbol(node: Node): Symbol | undefined {
|
||||
return node.symbol ? node.symbol : transformer.checker.getSymbolAtLocation(node);
|
||||
}
|
||||
|
||||
function getOriginalNode(node: Node): Node {
|
||||
return node.original ? node.original : node;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,16 +12,16 @@ namespace ts.codefix {
|
||||
const info = getInfo(context.sourceFile, context.span.start, context.program.getTypeChecker());
|
||||
if (!info) return undefined;
|
||||
|
||||
if (info.kind === InfoKind.enum) {
|
||||
if (info.kind === InfoKind.Enum) {
|
||||
const { token, parentDeclaration } = info;
|
||||
const changes = textChanges.ChangeTracker.with(context, t => addEnumMemberDeclaration(t, context.program.getTypeChecker(), token, parentDeclaration));
|
||||
return [createCodeFixAction(fixName, changes, [Diagnostics.Add_missing_enum_member_0, token.text], fixId, Diagnostics.Add_all_missing_members)];
|
||||
}
|
||||
const { parentDeclaration, classDeclarationSourceFile, inJs, makeStatic, token, call } = info;
|
||||
const methodCodeAction = call && getActionForMethodDeclaration(context, classDeclarationSourceFile, parentDeclaration, token, call, makeStatic, inJs, context.preferences);
|
||||
const addMember = inJs ?
|
||||
singleElementArray(getActionsForAddMissingMemberInJavaScriptFile(context, classDeclarationSourceFile, parentDeclaration, token.text, makeStatic)) :
|
||||
getActionsForAddMissingMemberInTypeScriptFile(context, classDeclarationSourceFile, parentDeclaration, token, makeStatic);
|
||||
const { parentDeclaration, declSourceFile, inJs, makeStatic, token, call } = info;
|
||||
const methodCodeAction = call && getActionForMethodDeclaration(context, declSourceFile, parentDeclaration, token, call, makeStatic, inJs, context.preferences);
|
||||
const addMember = inJs && !isInterfaceDeclaration(parentDeclaration) ?
|
||||
singleElementArray(getActionsForAddMissingMemberInJavaScriptFile(context, declSourceFile, parentDeclaration, token.text, makeStatic)) :
|
||||
getActionsForAddMissingMemberInTypeScriptFile(context, declSourceFile, parentDeclaration, token, makeStatic);
|
||||
return concatenate(singleElementArray(methodCodeAction), addMember);
|
||||
},
|
||||
fixIds: [fixId],
|
||||
@@ -30,7 +30,7 @@ namespace ts.codefix {
|
||||
const checker = program.getTypeChecker();
|
||||
const seen = createMap<true>();
|
||||
|
||||
const classToMembers = new NodeMap<ClassLikeDeclaration, ClassInfo[]>();
|
||||
const typeDeclToMembers = new NodeMap<ClassOrInterface, ClassOrInterfaceInfo[]>();
|
||||
|
||||
return createCombinedCodeActions(textChanges.ChangeTracker.with(context, changes => {
|
||||
eachDiagnostic(context, errorCodes, diag => {
|
||||
@@ -39,39 +39,39 @@ namespace ts.codefix {
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.kind === InfoKind.enum) {
|
||||
if (info.kind === InfoKind.Enum) {
|
||||
const { token, parentDeclaration } = info;
|
||||
addEnumMemberDeclaration(changes, checker, token, parentDeclaration);
|
||||
}
|
||||
else {
|
||||
const { parentDeclaration, token } = info;
|
||||
const infos = classToMembers.getOrUpdate(parentDeclaration, () => []);
|
||||
const infos = typeDeclToMembers.getOrUpdate(parentDeclaration, () => []);
|
||||
if (!infos.some(i => i.token.text === token.text)) infos.push(info);
|
||||
}
|
||||
});
|
||||
|
||||
classToMembers.forEach((infos, classDeclaration) => {
|
||||
const superClasses = getAllSuperClasses(classDeclaration, checker);
|
||||
typeDeclToMembers.forEach((infos, classDeclaration) => {
|
||||
const supers = getAllSupers(classDeclaration, checker);
|
||||
for (const info of infos) {
|
||||
// If some superclass added this property, don't add it again.
|
||||
if (superClasses.some(superClass => {
|
||||
const superInfos = classToMembers.get(superClass);
|
||||
if (supers.some(superClassOrInterface => {
|
||||
const superInfos = typeDeclToMembers.get(superClassOrInterface);
|
||||
return !!superInfos && superInfos.some(({ token }) => token.text === info.token.text);
|
||||
})) continue;
|
||||
|
||||
const { parentDeclaration, classDeclarationSourceFile, inJs, makeStatic, token, call } = info;
|
||||
const { parentDeclaration, declSourceFile, inJs, makeStatic, token, call } = info;
|
||||
|
||||
// Always prefer to add a method declaration if possible.
|
||||
if (call) {
|
||||
addMethodDeclaration(context, changes, classDeclarationSourceFile, parentDeclaration, token, call, makeStatic, inJs, preferences);
|
||||
addMethodDeclaration(context, changes, declSourceFile, parentDeclaration, token, call, makeStatic, inJs, preferences);
|
||||
}
|
||||
else {
|
||||
if (inJs) {
|
||||
addMissingMemberInJs(changes, classDeclarationSourceFile, parentDeclaration, token.text, makeStatic);
|
||||
if (inJs && !isInterfaceDeclaration(parentDeclaration)) {
|
||||
addMissingMemberInJs(changes, declSourceFile, parentDeclaration, token.text, makeStatic);
|
||||
}
|
||||
else {
|
||||
const typeNode = getTypeNode(program.getTypeChecker(), parentDeclaration, token);
|
||||
addPropertyDeclaration(changes, classDeclarationSourceFile, parentDeclaration, token.text, typeNode, makeStatic);
|
||||
addPropertyDeclaration(changes, declSourceFile, parentDeclaration, token.text, typeNode, makeStatic);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,37 +80,35 @@ namespace ts.codefix {
|
||||
},
|
||||
});
|
||||
|
||||
function getAllSuperClasses(cls: ClassLikeDeclaration | undefined, checker: TypeChecker): ReadonlyArray<ClassLikeDeclaration> {
|
||||
function getAllSupers(decl: ClassOrInterface | undefined, checker: TypeChecker): ReadonlyArray<ClassOrInterface> {
|
||||
const res: ClassLikeDeclaration[] = [];
|
||||
while (cls) {
|
||||
const superElement = getClassExtendsHeritageElement(cls);
|
||||
while (decl) {
|
||||
const superElement = getClassExtendsHeritageElement(decl);
|
||||
const superSymbol = superElement && checker.getSymbolAtLocation(superElement.expression);
|
||||
const superDecl = superSymbol && find(superSymbol.declarations, isClassLike);
|
||||
if (superDecl) { res.push(superDecl); }
|
||||
cls = superDecl;
|
||||
decl = superDecl;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
interface InfoBase {
|
||||
readonly kind: InfoKind;
|
||||
type ClassOrInterface = ClassLikeDeclaration | InterfaceDeclaration;
|
||||
const enum InfoKind { Enum, ClassOrInterface }
|
||||
interface EnumInfo {
|
||||
readonly kind: InfoKind.Enum;
|
||||
readonly token: Identifier;
|
||||
readonly parentDeclaration: EnumDeclaration | ClassLikeDeclaration;
|
||||
}
|
||||
enum InfoKind { enum, class }
|
||||
interface EnumInfo extends InfoBase {
|
||||
readonly kind: InfoKind.enum;
|
||||
readonly parentDeclaration: EnumDeclaration;
|
||||
}
|
||||
interface ClassInfo extends InfoBase {
|
||||
readonly kind: InfoKind.class;
|
||||
readonly parentDeclaration: ClassLikeDeclaration;
|
||||
interface ClassOrInterfaceInfo {
|
||||
readonly kind: InfoKind.ClassOrInterface;
|
||||
readonly token: Identifier;
|
||||
readonly parentDeclaration: ClassOrInterface;
|
||||
readonly makeStatic: boolean;
|
||||
readonly classDeclarationSourceFile: SourceFile;
|
||||
readonly declSourceFile: SourceFile;
|
||||
readonly inJs: boolean;
|
||||
readonly call: CallExpression | undefined;
|
||||
}
|
||||
type Info = EnumInfo | ClassInfo;
|
||||
type Info = EnumInfo | ClassOrInterfaceInfo;
|
||||
|
||||
function getInfo(tokenSourceFile: SourceFile, tokenPos: number, checker: TypeChecker): Info | undefined {
|
||||
// The identifier of the missing property. eg:
|
||||
@@ -128,35 +126,36 @@ namespace ts.codefix {
|
||||
const { symbol } = leftExpressionType;
|
||||
if (!symbol || !symbol.declarations) return undefined;
|
||||
|
||||
const classDeclaration = find(symbol.declarations, isClassLike);
|
||||
if (classDeclaration) {
|
||||
const makeStatic = (leftExpressionType as TypeReference).target !== checker.getDeclaredTypeOfSymbol(symbol);
|
||||
const classDeclarationSourceFile = classDeclaration.getSourceFile();
|
||||
const inJs = isSourceFileJavaScript(classDeclarationSourceFile);
|
||||
// Prefer to change the class instead of the interface if they are merged
|
||||
const classOrInterface = find(symbol.declarations, isClassLike) || find(symbol.declarations, isInterfaceDeclaration);
|
||||
if (classOrInterface) {
|
||||
const makeStatic = ((leftExpressionType as TypeReference).target || leftExpressionType) !== checker.getDeclaredTypeOfSymbol(symbol);
|
||||
const declSourceFile = classOrInterface.getSourceFile();
|
||||
const inJs = isSourceFileJavaScript(declSourceFile);
|
||||
const call = tryCast(parent.parent, isCallExpression);
|
||||
return { kind: InfoKind.class, token, parentDeclaration: classDeclaration, makeStatic, classDeclarationSourceFile, inJs, call };
|
||||
return { kind: InfoKind.ClassOrInterface, token, parentDeclaration: classOrInterface, makeStatic, declSourceFile, inJs, call };
|
||||
}
|
||||
const enumDeclaration = find(symbol.declarations, isEnumDeclaration);
|
||||
if (enumDeclaration) {
|
||||
return { kind: InfoKind.enum, token, parentDeclaration: enumDeclaration };
|
||||
return { kind: InfoKind.Enum, token, parentDeclaration: enumDeclaration };
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getActionsForAddMissingMemberInJavaScriptFile(context: CodeFixContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, tokenName: string, makeStatic: boolean): CodeFixAction | undefined {
|
||||
const changes = textChanges.ChangeTracker.with(context, t => addMissingMemberInJs(t, classDeclarationSourceFile, classDeclaration, tokenName, makeStatic));
|
||||
function getActionsForAddMissingMemberInJavaScriptFile(context: CodeFixContext, declSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, tokenName: string, makeStatic: boolean): CodeFixAction | undefined {
|
||||
const changes = textChanges.ChangeTracker.with(context, t => addMissingMemberInJs(t, declSourceFile, classDeclaration, tokenName, makeStatic));
|
||||
return changes.length === 0 ? undefined
|
||||
: createCodeFixAction(fixName, changes, [makeStatic ? Diagnostics.Initialize_static_property_0 : Diagnostics.Initialize_property_0_in_the_constructor, tokenName], fixId, Diagnostics.Add_all_missing_members);
|
||||
}
|
||||
|
||||
function addMissingMemberInJs(changeTracker: textChanges.ChangeTracker, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, tokenName: string, makeStatic: boolean): void {
|
||||
function addMissingMemberInJs(changeTracker: textChanges.ChangeTracker, declSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, tokenName: string, makeStatic: boolean): void {
|
||||
if (makeStatic) {
|
||||
if (classDeclaration.kind === SyntaxKind.ClassExpression) {
|
||||
return;
|
||||
}
|
||||
const className = classDeclaration.name!.getText();
|
||||
const staticInitialization = initializePropertyToUndefined(createIdentifier(className), tokenName);
|
||||
changeTracker.insertNodeAfter(classDeclarationSourceFile, classDeclaration, staticInitialization);
|
||||
changeTracker.insertNodeAfter(declSourceFile, classDeclaration, staticInitialization);
|
||||
}
|
||||
else {
|
||||
const classConstructor = getFirstConstructorWithBody(classDeclaration);
|
||||
@@ -164,7 +163,7 @@ namespace ts.codefix {
|
||||
return;
|
||||
}
|
||||
const propertyInitialization = initializePropertyToUndefined(createThis(), tokenName);
|
||||
changeTracker.insertNodeAtConstructorEnd(classDeclarationSourceFile, classConstructor, propertyInitialization);
|
||||
changeTracker.insertNodeAtConstructorEnd(declSourceFile, classConstructor, propertyInitialization);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,13 +171,13 @@ namespace ts.codefix {
|
||||
return createStatement(createAssignment(createPropertyAccess(obj, propertyName), createIdentifier("undefined")));
|
||||
}
|
||||
|
||||
function getActionsForAddMissingMemberInTypeScriptFile(context: CodeFixContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, token: Identifier, makeStatic: boolean): CodeFixAction[] | undefined {
|
||||
function getActionsForAddMissingMemberInTypeScriptFile(context: CodeFixContext, declSourceFile: SourceFile, classDeclaration: ClassOrInterface, token: Identifier, makeStatic: boolean): CodeFixAction[] | undefined {
|
||||
const typeNode = getTypeNode(context.program.getTypeChecker(), classDeclaration, token);
|
||||
const addProp = createAddPropertyDeclarationAction(context, classDeclarationSourceFile, classDeclaration, makeStatic, token.text, typeNode);
|
||||
return makeStatic ? [addProp] : [addProp, createAddIndexSignatureAction(context, classDeclarationSourceFile, classDeclaration, token.text, typeNode)];
|
||||
const addProp = createAddPropertyDeclarationAction(context, declSourceFile, classDeclaration, makeStatic, token.text, typeNode);
|
||||
return makeStatic ? [addProp] : [addProp, createAddIndexSignatureAction(context, declSourceFile, classDeclaration, token.text, typeNode)];
|
||||
}
|
||||
|
||||
function getTypeNode(checker: TypeChecker, classDeclaration: ClassLikeDeclaration, token: Node) {
|
||||
function getTypeNode(checker: TypeChecker, classDeclaration: ClassOrInterface, token: Node) {
|
||||
let typeNode: TypeNode | undefined;
|
||||
if (token.parent.parent.kind === SyntaxKind.BinaryExpression) {
|
||||
const binaryExpression = token.parent.parent as BinaryExpression;
|
||||
@@ -189,12 +188,12 @@ namespace ts.codefix {
|
||||
return typeNode || createKeywordTypeNode(SyntaxKind.AnyKeyword);
|
||||
}
|
||||
|
||||
function createAddPropertyDeclarationAction(context: CodeFixContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, makeStatic: boolean, tokenName: string, typeNode: TypeNode): CodeFixAction {
|
||||
const changes = textChanges.ChangeTracker.with(context, t => addPropertyDeclaration(t, classDeclarationSourceFile, classDeclaration, tokenName, typeNode, makeStatic));
|
||||
function createAddPropertyDeclarationAction(context: CodeFixContext, declSourceFile: SourceFile, classDeclaration: ClassOrInterface, makeStatic: boolean, tokenName: string, typeNode: TypeNode): CodeFixAction {
|
||||
const changes = textChanges.ChangeTracker.with(context, t => addPropertyDeclaration(t, declSourceFile, classDeclaration, tokenName, typeNode, makeStatic));
|
||||
return createCodeFixAction(fixName, changes, [makeStatic ? Diagnostics.Declare_static_property_0 : Diagnostics.Declare_property_0, tokenName], fixId, Diagnostics.Add_all_missing_members);
|
||||
}
|
||||
|
||||
function addPropertyDeclaration(changeTracker: textChanges.ChangeTracker, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, tokenName: string, typeNode: TypeNode, makeStatic: boolean): void {
|
||||
function addPropertyDeclaration(changeTracker: textChanges.ChangeTracker, declSourceFile: SourceFile, classDeclaration: ClassOrInterface, tokenName: string, typeNode: TypeNode, makeStatic: boolean): void {
|
||||
const property = createProperty(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ makeStatic ? [createToken(SyntaxKind.StaticKeyword)] : undefined,
|
||||
@@ -205,15 +204,15 @@ namespace ts.codefix {
|
||||
|
||||
const lastProp = getNodeToInsertPropertyAfter(classDeclaration);
|
||||
if (lastProp) {
|
||||
changeTracker.insertNodeAfter(classDeclarationSourceFile, lastProp, property);
|
||||
changeTracker.insertNodeAfter(declSourceFile, lastProp, property);
|
||||
}
|
||||
else {
|
||||
changeTracker.insertNodeAtClassStart(classDeclarationSourceFile, classDeclaration, property);
|
||||
changeTracker.insertNodeAtClassStart(declSourceFile, classDeclaration, property);
|
||||
}
|
||||
}
|
||||
|
||||
// Gets the last of the first run of PropertyDeclarations, or undefined if the class does not start with a PropertyDeclaration.
|
||||
function getNodeToInsertPropertyAfter(cls: ClassLikeDeclaration): PropertyDeclaration | undefined {
|
||||
function getNodeToInsertPropertyAfter(cls: ClassOrInterface): PropertyDeclaration | undefined {
|
||||
let res: PropertyDeclaration | undefined;
|
||||
for (const member of cls.members) {
|
||||
if (!isPropertyDeclaration(member)) break;
|
||||
@@ -222,7 +221,7 @@ namespace ts.codefix {
|
||||
return res;
|
||||
}
|
||||
|
||||
function createAddIndexSignatureAction(context: CodeFixContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, tokenName: string, typeNode: TypeNode): CodeFixAction {
|
||||
function createAddIndexSignatureAction(context: CodeFixContext, declSourceFile: SourceFile, classDeclaration: ClassOrInterface, tokenName: string, typeNode: TypeNode): CodeFixAction {
|
||||
// Index signatures cannot have the static modifier.
|
||||
const stringTypeNode = createKeywordTypeNode(SyntaxKind.StringKeyword);
|
||||
const indexingParameter = createParameter(
|
||||
@@ -239,44 +238,44 @@ namespace ts.codefix {
|
||||
[indexingParameter],
|
||||
typeNode);
|
||||
|
||||
const changes = textChanges.ChangeTracker.with(context, t => t.insertNodeAtClassStart(classDeclarationSourceFile, classDeclaration, indexSignature));
|
||||
const changes = textChanges.ChangeTracker.with(context, t => t.insertNodeAtClassStart(declSourceFile, classDeclaration, indexSignature));
|
||||
// No fixId here because code-fix-all currently only works on adding individual named properties.
|
||||
return createCodeFixActionNoFixId(fixName, changes, [Diagnostics.Add_index_signature_for_property_0, tokenName]);
|
||||
}
|
||||
|
||||
function getActionForMethodDeclaration(
|
||||
context: CodeFixContext,
|
||||
classDeclarationSourceFile: SourceFile,
|
||||
classDeclaration: ClassLikeDeclaration,
|
||||
declSourceFile: SourceFile,
|
||||
classDeclaration: ClassOrInterface,
|
||||
token: Identifier,
|
||||
callExpression: CallExpression,
|
||||
makeStatic: boolean,
|
||||
inJs: boolean,
|
||||
preferences: UserPreferences,
|
||||
): CodeFixAction | undefined {
|
||||
const changes = textChanges.ChangeTracker.with(context, t => addMethodDeclaration(context, t, classDeclarationSourceFile, classDeclaration, token, callExpression, makeStatic, inJs, preferences));
|
||||
const changes = textChanges.ChangeTracker.with(context, t => addMethodDeclaration(context, t, declSourceFile, classDeclaration, token, callExpression, makeStatic, inJs, preferences));
|
||||
return createCodeFixAction(fixName, changes, [makeStatic ? Diagnostics.Declare_static_method_0 : Diagnostics.Declare_method_0, token.text], fixId, Diagnostics.Add_all_missing_members);
|
||||
}
|
||||
|
||||
function addMethodDeclaration(
|
||||
context: CodeFixContextBase,
|
||||
changeTracker: textChanges.ChangeTracker,
|
||||
classDeclarationSourceFile: SourceFile,
|
||||
classDeclaration: ClassLikeDeclaration,
|
||||
declSourceFile: SourceFile,
|
||||
typeDecl: ClassOrInterface,
|
||||
token: Identifier,
|
||||
callExpression: CallExpression,
|
||||
makeStatic: boolean,
|
||||
inJs: boolean,
|
||||
preferences: UserPreferences,
|
||||
): void {
|
||||
const methodDeclaration = createMethodFromCallExpression(context, callExpression, token.text, inJs, makeStatic, preferences);
|
||||
const methodDeclaration = createMethodFromCallExpression(context, callExpression, token.text, inJs, makeStatic, preferences, !isInterfaceDeclaration(typeDecl));
|
||||
const containingMethodDeclaration = getAncestor(callExpression, SyntaxKind.MethodDeclaration);
|
||||
|
||||
if (containingMethodDeclaration && containingMethodDeclaration.parent === classDeclaration) {
|
||||
changeTracker.insertNodeAfter(classDeclarationSourceFile, containingMethodDeclaration, methodDeclaration);
|
||||
if (containingMethodDeclaration && containingMethodDeclaration.parent === typeDecl) {
|
||||
changeTracker.insertNodeAfter(declSourceFile, containingMethodDeclaration, methodDeclaration);
|
||||
}
|
||||
else {
|
||||
changeTracker.insertNodeAtClassStart(classDeclarationSourceFile, classDeclaration, methodDeclaration);
|
||||
changeTracker.insertNodeAtClassStart(declSourceFile, typeDecl, methodDeclaration);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -112,26 +112,23 @@ namespace ts.codefix {
|
||||
|
||||
export function createMethodFromCallExpression(
|
||||
context: CodeFixContextBase,
|
||||
{ typeArguments, arguments: args, parent: parent }: CallExpression,
|
||||
call: CallExpression,
|
||||
methodName: string,
|
||||
inJs: boolean,
|
||||
makeStatic: boolean,
|
||||
preferences: UserPreferences,
|
||||
body: boolean,
|
||||
): MethodDeclaration {
|
||||
const { typeArguments, arguments: args, parent } = call;
|
||||
const checker = context.program.getTypeChecker();
|
||||
const types = map(args,
|
||||
arg => {
|
||||
let type = checker.getTypeAtLocation(arg);
|
||||
if (type === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
// Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {"
|
||||
type = checker.getBaseTypeOfLiteralType(type);
|
||||
return checker.typeToTypeNode(type);
|
||||
});
|
||||
const types = map(args, arg =>
|
||||
// Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {"
|
||||
checker.typeToTypeNode(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(arg))));
|
||||
const names = map(args, arg =>
|
||||
isIdentifier(arg) ? arg.text :
|
||||
isPropertyAccessExpression(arg) ? arg.name.text : undefined);
|
||||
isPropertyAccessExpression(arg) ? arg.name.text : undefined);
|
||||
const contextualType = checker.getContextualType(call);
|
||||
const returnType = inJs ? undefined : contextualType && checker.typeToTypeNode(contextualType, call) || createKeywordTypeNode(SyntaxKind.AnyKeyword);
|
||||
return createMethod(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ makeStatic ? [createToken(SyntaxKind.StaticKeyword)] : undefined,
|
||||
@@ -141,8 +138,8 @@ namespace ts.codefix {
|
||||
/*typeParameters*/ inJs ? undefined : map(typeArguments, (_, i) =>
|
||||
createTypeParameterDeclaration(CharacterCodes.T + typeArguments!.length - 1 <= CharacterCodes.Z ? String.fromCharCode(CharacterCodes.T + i) : `T${i}`)),
|
||||
/*parameters*/ createDummyParameters(args.length, names, types, /*minArgumentCount*/ undefined, inJs),
|
||||
/*type*/ inJs ? undefined : createKeywordTypeNode(SyntaxKind.AnyKeyword),
|
||||
createStubbedMethodBody(preferences));
|
||||
/*type*/ returnType,
|
||||
body ? createStubbedMethodBody(preferences) : undefined);
|
||||
}
|
||||
|
||||
function createDummyParameters(argCount: number, names: (string | undefined)[] | undefined, types: (TypeNode | undefined)[] | undefined, minArgumentCount: number | undefined, inJs: boolean): ParameterDeclaration[] {
|
||||
|
||||
@@ -168,8 +168,13 @@ namespace ts.codefix {
|
||||
// We sort the best codefixes first, so taking `first` is best for completions.
|
||||
const moduleSpecifier = first(getNewImportInfos(program, sourceFile, position, exportInfos, host, preferences)).moduleSpecifier;
|
||||
const fix = first(getFixForImport(exportInfos, symbolName, position, program, sourceFile, host, preferences));
|
||||
return { moduleSpecifier, codeAction: codeActionForFix({ host, formatContext }, sourceFile, symbolName, fix, getQuotePreference(sourceFile, preferences)) };
|
||||
return { moduleSpecifier, codeAction: codeFixActionToCodeAction(codeActionForFix({ host, formatContext }, sourceFile, symbolName, fix, getQuotePreference(sourceFile, preferences))) };
|
||||
}
|
||||
|
||||
function codeFixActionToCodeAction({ description, changes, commands }: CodeFixAction): CodeAction {
|
||||
return { description, changes, commands };
|
||||
}
|
||||
|
||||
function getAllReExportingModules(exportedSymbol: Symbol, exportingModuleSymbol: Symbol, symbolName: string, sourceFile: SourceFile, checker: TypeChecker, allSourceFiles: ReadonlyArray<SourceFile>): ReadonlyArray<SymbolExportInfo> {
|
||||
const result: SymbolExportInfo[] = [];
|
||||
forEachExternalModule(checker, allSourceFiles, (moduleSymbol, moduleFile) => {
|
||||
@@ -414,8 +419,6 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
function getDefaultExportInfo(defaultExport: Symbol, moduleSymbol: Symbol, program: Program): { readonly symbolForMeaning: Symbol, readonly name: string } | undefined {
|
||||
const checker = program.getTypeChecker();
|
||||
|
||||
const localSymbol = getLocalSymbolForExportDefault(defaultExport);
|
||||
if (localSymbol) return { symbolForMeaning: localSymbol, name: localSymbol.name };
|
||||
|
||||
@@ -423,12 +426,11 @@ namespace ts.codefix {
|
||||
if (name !== undefined) return { symbolForMeaning: defaultExport, name };
|
||||
|
||||
if (defaultExport.flags & SymbolFlags.Alias) {
|
||||
const aliased = checker.getAliasedSymbol(defaultExport);
|
||||
return getDefaultExportInfo(aliased, Debug.assertDefined(aliased.parent), program);
|
||||
const aliased = program.getTypeChecker().getImmediateAliasedSymbol(defaultExport);
|
||||
return aliased && getDefaultExportInfo(aliased, Debug.assertDefined(aliased.parent), program);
|
||||
}
|
||||
else {
|
||||
const moduleName = moduleSymbolToValidIdentifier(moduleSymbol, program.getCompilerOptions().target!);
|
||||
return moduleName === undefined ? undefined : { symbolForMeaning: defaultExport, name: moduleName };
|
||||
return { symbolForMeaning: defaultExport, name: moduleSymbolToValidIdentifier(moduleSymbol, program.getCompilerOptions().target!) };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -402,6 +402,8 @@ namespace ts.Completions {
|
||||
return stringLiteralCompletionsFromProperties(typeChecker.getTypeFromTypeNode((node.parent.parent as IndexedAccessTypeNode).objectType));
|
||||
case SyntaxKind.ImportType:
|
||||
return { kind: StringLiteralCompletionKind.Paths, paths: PathCompletions.getStringLiteralCompletionsFromModuleNames(sourceFile, node, compilerOptions, host, typeChecker) };
|
||||
case SyntaxKind.UnionType:
|
||||
return isTypeReferenceNode(node.parent.parent.parent) ? { kind: StringLiteralCompletionKind.Types, types: getStringLiteralTypes(typeChecker.getTypeArgumentConstraint(node.parent.parent as UnionTypeNode)), isNewIdentifier: false } : undefined;
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
@@ -2114,8 +2116,8 @@ namespace ts.Completions {
|
||||
const kind = stringToToken(entry.name)!;
|
||||
switch (keywordFilter) {
|
||||
case KeywordCompletionFilters.None:
|
||||
// "undefined" is a global variable, so don't need a keyword completion for it.
|
||||
return kind !== SyntaxKind.UndefinedKeyword;
|
||||
return kind === SyntaxKind.AsyncKeyword || !isContextualKeyword(kind) && !isClassMemberCompletionKeyword(kind) || kind === SyntaxKind.DeclareKeyword || kind === SyntaxKind.ModuleKeyword
|
||||
|| isTypeKeyword(kind) && kind !== SyntaxKind.UndefinedKeyword;
|
||||
case KeywordCompletionFilters.ClassElementKeywords:
|
||||
return isClassMemberCompletionKeyword(kind);
|
||||
case KeywordCompletionFilters.InterfaceElementKeywords:
|
||||
@@ -2150,7 +2152,7 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
function isFunctionLikeBodyKeyword(kind: SyntaxKind) {
|
||||
return kind === SyntaxKind.AsyncKeyword || !isClassMemberCompletionKeyword(kind);
|
||||
return kind === SyntaxKind.AsyncKeyword || !isContextualKeyword(kind) && !isClassMemberCompletionKeyword(kind);
|
||||
}
|
||||
|
||||
function keywordForNode(node: Node): SyntaxKind {
|
||||
|
||||
@@ -184,7 +184,7 @@ namespace ts {
|
||||
|
||||
const bucket = getBucketForCompilationSettings(key, /*createIfMissing*/ true);
|
||||
let entry = bucket.get(path);
|
||||
const scriptTarget = scriptKind === ScriptKind.JSON ? ScriptTarget.JSON : compilationSettings.target;
|
||||
const scriptTarget = scriptKind === ScriptKind.JSON ? ScriptTarget.JSON : compilationSettings.target || ScriptTarget.ES5;
|
||||
if (!entry && externalCache) {
|
||||
const sourceFile = externalCache.getDocument(key, path);
|
||||
if (sourceFile) {
|
||||
@@ -199,7 +199,7 @@ namespace ts {
|
||||
|
||||
if (!entry) {
|
||||
// Have never seen this file with these settings. Create a new source file for it.
|
||||
const sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, scriptTarget!, version, /*setNodeParents*/ false, scriptKind); // TODO: GH#18217
|
||||
const sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, scriptTarget, version, /*setNodeParents*/ false, scriptKind);
|
||||
if (externalCache) {
|
||||
externalCache.setDocument(key, path, sourceFile);
|
||||
}
|
||||
|
||||
@@ -136,9 +136,30 @@ namespace ts.GoToDefinition {
|
||||
}
|
||||
|
||||
const symbol = typeChecker.getSymbolAtLocation(node);
|
||||
const type = symbol && typeChecker.getTypeOfSymbolAtLocation(symbol, node);
|
||||
return type && flatMap(type.isUnion() && !(type.flags & TypeFlags.Enum) ? type.types : [type], t =>
|
||||
t.symbol && getDefinitionFromSymbol(typeChecker, t.symbol, node));
|
||||
if (!symbol) return undefined;
|
||||
|
||||
const typeAtLocation = typeChecker.getTypeOfSymbolAtLocation(symbol, node);
|
||||
const returnType = tryGetReturnTypeOfFunction(symbol, typeAtLocation, typeChecker);
|
||||
const fromReturnType = returnType && definitionFromType(returnType, typeChecker, node);
|
||||
// If a function returns 'void' or some other type with no definition, just return the function definition.
|
||||
return fromReturnType && fromReturnType.length !== 0 ? fromReturnType : definitionFromType(typeAtLocation, typeChecker, node);
|
||||
}
|
||||
|
||||
function definitionFromType(type: Type, checker: TypeChecker, node: Node): DefinitionInfo[] {
|
||||
return flatMap(type.isUnion() && !(type.flags & TypeFlags.Enum) ? type.types : [type], t =>
|
||||
t.symbol && getDefinitionFromSymbol(checker, t.symbol, node));
|
||||
}
|
||||
|
||||
function tryGetReturnTypeOfFunction(symbol: Symbol, type: Type, checker: TypeChecker): Type | undefined {
|
||||
// If the type is just a function's inferred type,
|
||||
// go-to-type should go to the return type instead, since go-to-definition takes you to the function anyway.
|
||||
if (type.symbol === symbol ||
|
||||
// At `const f = () => {}`, the symbol is `f` and the type symbol is at `() => {}`
|
||||
symbol.valueDeclaration && type.symbol && isVariableDeclaration(symbol.valueDeclaration) && symbol.valueDeclaration.initializer === type.symbol.valueDeclaration as Node) {
|
||||
const sigs = type.getCallSignatures();
|
||||
if (sigs.length === 1) return checker.getReturnTypeOfSignature(first(sigs));
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function getDefinitionAndBoundSpan(program: Program, sourceFile: SourceFile, position: number): DefinitionInfoAndBoundSpan | undefined {
|
||||
|
||||
@@ -367,7 +367,7 @@ namespace ts.JsDoc {
|
||||
const varStatement = <VariableStatement>commentOwner;
|
||||
const varDeclarations = varStatement.declarationList.declarations;
|
||||
const parameters = varDeclarations.length === 1 && varDeclarations[0].initializer
|
||||
? getParametersFromRightHandSideOfAssignment(varDeclarations[0].initializer!)
|
||||
? getParametersFromRightHandSideOfAssignment(varDeclarations[0].initializer)
|
||||
: undefined;
|
||||
return { commentOwner, parameters };
|
||||
}
|
||||
|
||||
@@ -416,7 +416,7 @@ namespace ts.NavigationBar {
|
||||
}
|
||||
|
||||
const declName = getNameOfDeclaration(<Declaration>node);
|
||||
if (declName) {
|
||||
if (declName && isPropertyName(declName)) {
|
||||
return unescapeLeadingUnderscores(getPropertyNameForPropertyNameNode(declName)!); // TODO: GH#18217
|
||||
}
|
||||
switch (node.kind) {
|
||||
|
||||
@@ -340,7 +340,7 @@ namespace ts.refactor {
|
||||
const { name, namedBindings } = importDecl.importClause;
|
||||
const defaultUnused = !name || isUnused(name);
|
||||
const namedBindingsUnused = !namedBindings ||
|
||||
(namedBindings.kind === SyntaxKind.NamespaceImport ? isUnused(namedBindings.name) : namedBindings.elements.every(e => isUnused(e.name)));
|
||||
(namedBindings.kind === SyntaxKind.NamespaceImport ? isUnused(namedBindings.name) : namedBindings.elements.length !== 0 && namedBindings.elements.every(e => isUnused(e.name)));
|
||||
if (defaultUnused && namedBindingsUnused) {
|
||||
changes.delete(sourceFile, importDecl);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace ts.Rename {
|
||||
if (isStringLiteralLike(node) && tryGetImportFromModuleSpecifier(node)) return undefined;
|
||||
|
||||
const kind = SymbolDisplay.getSymbolKind(typeChecker, symbol, node);
|
||||
const specifierName = (isImportOrExportSpecifierName(node) || isStringOrNumericLiteral(node) && node.parent.kind === SyntaxKind.ComputedPropertyName)
|
||||
const specifierName = (isImportOrExportSpecifierName(node) || isStringOrNumericLiteralLike(node) && node.parent.kind === SyntaxKind.ComputedPropertyName)
|
||||
? stripQuotes(getTextOfIdentifierOrLiteral(node))
|
||||
: undefined;
|
||||
const displayName = specifierName || typeChecker.symbolToString(symbol);
|
||||
|
||||
@@ -2142,7 +2142,7 @@ namespace ts {
|
||||
function initializeNameTable(sourceFile: SourceFile): void {
|
||||
const nameTable = sourceFile.nameTable = createUnderscoreEscapedMap<number>();
|
||||
sourceFile.forEachChild(function walk(node) {
|
||||
if (isIdentifier(node) && node.escapedText || isStringOrNumericLiteral(node) && literalIsName(node)) {
|
||||
if (isIdentifier(node) && node.escapedText || isStringOrNumericLiteralLike(node) && literalIsName(node)) {
|
||||
const text = getEscapedTextOfIdentifierOrLiteral(node);
|
||||
nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1);
|
||||
}
|
||||
@@ -2162,7 +2162,7 @@ namespace ts {
|
||||
* then we want 'something' to be in the name table. Similarly, if we have
|
||||
* "a['propname']" then we want to store "propname" in the name table.
|
||||
*/
|
||||
function literalIsName(node: StringLiteral | NumericLiteral): boolean {
|
||||
function literalIsName(node: StringLiteralLike | NumericLiteral): boolean {
|
||||
return isDeclarationName(node) ||
|
||||
node.parent.kind === SyntaxKind.ExternalModuleReference ||
|
||||
isArgumentOfElementAccessExpression(node) ||
|
||||
|
||||
@@ -328,7 +328,6 @@ namespace ts {
|
||||
}
|
||||
|
||||
export class LanguageServiceShimHostAdapter implements LanguageServiceHost {
|
||||
private files: string[];
|
||||
private loggingEnabled = false;
|
||||
private tracingEnabled = false;
|
||||
|
||||
@@ -408,7 +407,7 @@ namespace ts {
|
||||
|
||||
public getScriptFileNames(): string[] {
|
||||
const encoded = this.shimHost.getScriptFileNames();
|
||||
return this.files = JSON.parse(encoded);
|
||||
return JSON.parse(encoded);
|
||||
}
|
||||
|
||||
public getScriptSnapshot(fileName: string): IScriptSnapshot | undefined {
|
||||
|
||||
+145
-77
@@ -1,22 +1,23 @@
|
||||
/* @internal */
|
||||
namespace ts.SignatureHelp {
|
||||
const enum ArgumentListKind {
|
||||
TypeArguments,
|
||||
CallArguments,
|
||||
TaggedTemplateArguments,
|
||||
JSXAttributesArguments
|
||||
const enum InvocationKind { Call, TypeArgs, Contextual }
|
||||
interface CallInvocation { readonly kind: InvocationKind.Call; readonly node: CallLikeExpression; }
|
||||
interface TypeArgsInvocation { readonly kind: InvocationKind.TypeArgs; readonly called: Expression; }
|
||||
interface ContextualInvocation {
|
||||
readonly kind: InvocationKind.Contextual;
|
||||
readonly signature: Signature;
|
||||
readonly node: Node; // Just for enclosingDeclaration for printing types
|
||||
readonly symbol: Symbol;
|
||||
}
|
||||
|
||||
const enum InvocationKind { Call, TypeArgs }
|
||||
type Invocation = { kind: InvocationKind.Call, node: CallLikeExpression } | { kind: InvocationKind.TypeArgs, called: Expression };
|
||||
type Invocation = CallInvocation | TypeArgsInvocation | ContextualInvocation;
|
||||
|
||||
interface ArgumentListInfo {
|
||||
kind: ArgumentListKind;
|
||||
invocation: Invocation;
|
||||
argumentsSpan: TextSpan;
|
||||
argumentIndex: number;
|
||||
readonly isTypeParameterList: boolean;
|
||||
readonly invocation: Invocation;
|
||||
readonly argumentsSpan: TextSpan;
|
||||
readonly argumentIndex: number;
|
||||
/** argumentCount is the *apparent* number of arguments. */
|
||||
argumentCount: number;
|
||||
readonly argumentCount: number;
|
||||
}
|
||||
|
||||
export function getSignatureHelpItems(program: Program, sourceFile: SourceFile, position: number, triggerReason: SignatureHelpTriggerReason | undefined, cancellationToken: CancellationToken): SignatureHelpItems | undefined {
|
||||
@@ -37,7 +38,7 @@ namespace ts.SignatureHelp {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const argumentInfo = getContainingArgumentInfo(startingToken, position, sourceFile);
|
||||
const argumentInfo = getContainingArgumentInfo(startingToken, position, sourceFile, typeChecker);
|
||||
if (!argumentInfo) return undefined;
|
||||
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
@@ -49,35 +50,34 @@ namespace ts.SignatureHelp {
|
||||
if (!candidateInfo) {
|
||||
// We didn't have any sig help items produced by the TS compiler. If this is a JS
|
||||
// file, then see if we can figure out anything better.
|
||||
if (isSourceFileJavaScript(sourceFile)) {
|
||||
return createJavaScriptSignatureHelpItems(argumentInfo, program, cancellationToken);
|
||||
}
|
||||
return undefined;
|
||||
return isSourceFileJavaScript(sourceFile) ? createJavaScriptSignatureHelpItems(argumentInfo, program, cancellationToken) : undefined;
|
||||
}
|
||||
|
||||
return typeChecker.runWithCancellationToken(cancellationToken, typeChecker => createSignatureHelpItems(candidateInfo.candidates, candidateInfo.resolvedSignature, argumentInfo, sourceFile, typeChecker));
|
||||
}
|
||||
|
||||
interface CandidateInfo { readonly candidates: ReadonlyArray<Signature>; readonly resolvedSignature: Signature; }
|
||||
function getCandidateInfo(argumentInfo: ArgumentListInfo, checker: TypeChecker, sourceFile: SourceFile, startingToken: Node, onlyUseSyntacticOwners: boolean): CandidateInfo | undefined {
|
||||
const { invocation } = argumentInfo;
|
||||
if (invocation.kind === InvocationKind.Call) {
|
||||
if (onlyUseSyntacticOwners && !isSyntacticOwner(startingToken, invocation.node, sourceFile)) {
|
||||
return undefined;
|
||||
function getCandidateInfo({ invocation, argumentCount }: ArgumentListInfo, checker: TypeChecker, sourceFile: SourceFile, startingToken: Node, onlyUseSyntacticOwners: boolean): CandidateInfo | undefined {
|
||||
switch (invocation.kind) {
|
||||
case InvocationKind.Call: {
|
||||
if (onlyUseSyntacticOwners && !isSyntacticOwner(startingToken, invocation.node, sourceFile)) {
|
||||
return undefined;
|
||||
}
|
||||
const candidates: Signature[] = [];
|
||||
const resolvedSignature = checker.getResolvedSignatureForSignatureHelp(invocation.node, candidates, argumentCount)!; // TODO: GH#18217
|
||||
return candidates.length === 0 ? undefined : { candidates, resolvedSignature };
|
||||
}
|
||||
const candidates: Signature[] = [];
|
||||
const resolvedSignature = checker.getResolvedSignatureForSignatureHelp(invocation.node, candidates, argumentInfo.argumentCount)!; // TODO: GH#18217
|
||||
return candidates.length === 0 ? undefined : { candidates, resolvedSignature };
|
||||
}
|
||||
else if (invocation.kind === InvocationKind.TypeArgs) {
|
||||
if (onlyUseSyntacticOwners && !lessThanFollowsCalledExpression(startingToken, sourceFile, invocation.called)) {
|
||||
return undefined;
|
||||
case InvocationKind.TypeArgs: {
|
||||
if (onlyUseSyntacticOwners && !lessThanFollowsCalledExpression(startingToken, sourceFile, invocation.called)) {
|
||||
return undefined;
|
||||
}
|
||||
const candidates = getPossibleGenericSignatures(invocation.called, argumentCount, checker);
|
||||
return candidates.length === 0 ? undefined : { candidates, resolvedSignature: first(candidates) };
|
||||
}
|
||||
const candidates = getPossibleGenericSignatures(invocation.called, argumentInfo.argumentCount, checker);
|
||||
return candidates.length === 0 ? undefined : { candidates, resolvedSignature: first(candidates) };
|
||||
}
|
||||
else {
|
||||
Debug.assertNever(invocation);
|
||||
case InvocationKind.Contextual:
|
||||
return { candidates: [invocation.signature], resolvedSignature: invocation.signature };
|
||||
default:
|
||||
return Debug.assertNever(invocation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,6 +99,7 @@ namespace ts.SignatureHelp {
|
||||
}
|
||||
|
||||
function createJavaScriptSignatureHelpItems(argumentInfo: ArgumentListInfo, program: Program, cancellationToken: CancellationToken): SignatureHelpItems | undefined {
|
||||
if (argumentInfo.invocation.kind === InvocationKind.Contextual) return undefined;
|
||||
// See if we can find some symbol with the call expression name that has call signatures.
|
||||
const expression = getExpressionFromInvocation(argumentInfo.invocation);
|
||||
const name = isIdentifier(expression) ? expression.text : isPropertyAccessExpression(expression) ? expression.name.text : undefined;
|
||||
@@ -128,10 +129,40 @@ namespace ts.SignatureHelp {
|
||||
}
|
||||
export function getArgumentInfoForCompletions(node: Node, position: number, sourceFile: SourceFile): ArgumentInfoForCompletions | undefined {
|
||||
const info = getImmediatelyContainingArgumentInfo(node, position, sourceFile);
|
||||
return !info || info.kind === ArgumentListKind.TypeArguments || info.invocation.kind === InvocationKind.TypeArgs ? undefined
|
||||
return !info || info.isTypeParameterList || info.invocation.kind !== InvocationKind.Call ? undefined
|
||||
: { invocation: info.invocation.node, argumentCount: info.argumentCount, argumentIndex: info.argumentIndex };
|
||||
}
|
||||
|
||||
function getArgumentOrParameterListInfo(node: Node, sourceFile: SourceFile): { readonly list: Node, readonly argumentIndex: number, readonly argumentCount: number, readonly argumentsSpan: TextSpan } | undefined {
|
||||
const info = getArgumentOrParameterListAndIndex(node, sourceFile);
|
||||
if (!info) return undefined;
|
||||
const { list, argumentIndex } = info;
|
||||
|
||||
const argumentCount = getArgumentCount(list);
|
||||
if (argumentIndex !== 0) {
|
||||
Debug.assertLessThan(argumentIndex, argumentCount);
|
||||
}
|
||||
const argumentsSpan = getApplicableSpanForArguments(list, sourceFile);
|
||||
return { list, argumentIndex, argumentCount, argumentsSpan };
|
||||
}
|
||||
function getArgumentOrParameterListAndIndex(node: Node, sourceFile: SourceFile): { readonly list: Node, readonly argumentIndex: number } | undefined {
|
||||
if (node.kind === SyntaxKind.LessThanToken || node.kind === SyntaxKind.OpenParenToken) {
|
||||
// Find the list that starts right *after* the < or ( token.
|
||||
// If the user has just opened a list, consider this item 0.
|
||||
return { list: getChildListThatStartsWithOpenerToken(node.parent, node, sourceFile), argumentIndex: 0 };
|
||||
}
|
||||
else {
|
||||
// findListItemInfo can return undefined if we are not in parent's argument list
|
||||
// or type argument list. This includes cases where the cursor is:
|
||||
// - To the right of the closing parenthesis, non-substitution template, or template tail.
|
||||
// - Between the type arguments and the arguments (greater than token)
|
||||
// - On the target of the call (parent.func)
|
||||
// - On the 'new' keyword in a 'new' expression
|
||||
const list = findContainingList(node);
|
||||
return list && { list, argumentIndex: getArgumentIndex(list, node) };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns relevant information for the argument list and the current argument if we are
|
||||
* in the argument of an invocation; returns undefined otherwise.
|
||||
@@ -140,8 +171,6 @@ namespace ts.SignatureHelp {
|
||||
const { parent } = node;
|
||||
if (isCallOrNewExpression(parent)) {
|
||||
const invocation = parent;
|
||||
let list: Node | undefined;
|
||||
let argumentIndex: number;
|
||||
|
||||
// There are 3 cases to handle:
|
||||
// 1. The token introduces a list, and should begin a signature help session
|
||||
@@ -157,32 +186,11 @@ namespace ts.SignatureHelp {
|
||||
// Case 3:
|
||||
// foo<T#, U#>(a#, #b#) -> The token is buried inside a list, and should give signature help
|
||||
// Find out if 'node' is an argument, a type argument, or neither
|
||||
if (node.kind === SyntaxKind.LessThanToken || node.kind === SyntaxKind.OpenParenToken) {
|
||||
// Find the list that starts right *after* the < or ( token.
|
||||
// If the user has just opened a list, consider this item 0.
|
||||
list = getChildListThatStartsWithOpenerToken(parent, node, sourceFile);
|
||||
Debug.assert(list !== undefined);
|
||||
argumentIndex = 0;
|
||||
}
|
||||
else {
|
||||
// findListItemInfo can return undefined if we are not in parent's argument list
|
||||
// or type argument list. This includes cases where the cursor is:
|
||||
// - To the right of the closing parenthesis, non-substitution template, or template tail.
|
||||
// - Between the type arguments and the arguments (greater than token)
|
||||
// - On the target of the call (parent.func)
|
||||
// - On the 'new' keyword in a 'new' expression
|
||||
list = findContainingList(node);
|
||||
if (!list) return undefined;
|
||||
argumentIndex = getArgumentIndex(list, node);
|
||||
}
|
||||
|
||||
const kind = parent.typeArguments && parent.typeArguments.pos === list.pos ? ArgumentListKind.TypeArguments : ArgumentListKind.CallArguments;
|
||||
const argumentCount = getArgumentCount(list);
|
||||
if (argumentIndex !== 0) {
|
||||
Debug.assertLessThan(argumentIndex, argumentCount);
|
||||
}
|
||||
const argumentsSpan = getApplicableSpanForArguments(list, sourceFile);
|
||||
return { kind, invocation: { kind: InvocationKind.Call, node: invocation }, argumentsSpan, argumentIndex, argumentCount };
|
||||
const info = getArgumentOrParameterListInfo(node, sourceFile);
|
||||
if (!info) return undefined;
|
||||
const { list, argumentIndex, argumentCount, argumentsSpan } = info;
|
||||
const isTypeParameterList = !!parent.typeArguments && parent.typeArguments.pos === list.pos;
|
||||
return { isTypeParameterList, invocation: { kind: InvocationKind.Call, node: invocation }, argumentsSpan, argumentIndex, argumentCount };
|
||||
}
|
||||
else if (isNoSubstitutionTemplateLiteral(node) && isTaggedTemplateExpression(parent)) {
|
||||
// Check if we're actually inside the template;
|
||||
@@ -190,6 +198,7 @@ namespace ts.SignatureHelp {
|
||||
if (isInsideTemplateLiteral(node, position, sourceFile)) {
|
||||
return getArgumentListInfoForTemplate(parent, /*argumentIndex*/ 0, sourceFile);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
else if (isTemplateHead(node) && parent.parent.kind === SyntaxKind.TaggedTemplateExpression) {
|
||||
const templateExpression = <TemplateExpression>parent;
|
||||
@@ -223,7 +232,7 @@ namespace ts.SignatureHelp {
|
||||
const attributeSpanStart = parent.attributes.pos;
|
||||
const attributeSpanEnd = skipTrivia(sourceFile.text, parent.attributes.end, /*stopAfterLineBreak*/ false);
|
||||
return {
|
||||
kind: ArgumentListKind.JSXAttributesArguments,
|
||||
isTypeParameterList: false,
|
||||
invocation: { kind: InvocationKind.Call, node: parent },
|
||||
argumentsSpan: createTextSpan(attributeSpanStart, attributeSpanEnd - attributeSpanStart),
|
||||
argumentIndex: 0,
|
||||
@@ -236,11 +245,67 @@ namespace ts.SignatureHelp {
|
||||
const { called, nTypeArguments } = typeArgInfo;
|
||||
const invocation: Invocation = { kind: InvocationKind.TypeArgs, called };
|
||||
const argumentsSpan = createTextSpanFromBounds(called.getStart(sourceFile), node.end);
|
||||
return { kind: ArgumentListKind.TypeArguments, invocation, argumentsSpan, argumentIndex: nTypeArguments, argumentCount: nTypeArguments + 1 };
|
||||
return { isTypeParameterList: true, invocation, argumentsSpan, argumentIndex: nTypeArguments, argumentCount: nTypeArguments + 1 };
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
function getImmediatelyContainingArgumentOrContextualParameterInfo(node: Node, position: number, sourceFile: SourceFile, checker: TypeChecker): ArgumentListInfo | undefined {
|
||||
return tryGetParameterInfo(node, position, sourceFile, checker) || getImmediatelyContainingArgumentInfo(node, position, sourceFile);
|
||||
}
|
||||
|
||||
function getHighestBinary(b: BinaryExpression): BinaryExpression {
|
||||
return isBinaryExpression(b.parent) ? getHighestBinary(b.parent) : b;
|
||||
}
|
||||
|
||||
function countBinaryExpressionParameters(b: BinaryExpression): number {
|
||||
return isBinaryExpression(b.left) ? countBinaryExpressionParameters(b.left) + 1 : 2;
|
||||
}
|
||||
|
||||
function tryGetParameterInfo(startingToken: Node, _position: number, sourceFile: SourceFile, checker: TypeChecker): ArgumentListInfo | undefined {
|
||||
const info = getContextualSignatureLocationInfo(startingToken, sourceFile, checker);
|
||||
if (!info) return undefined;
|
||||
const { contextualType, argumentIndex, argumentCount, argumentsSpan } = info;
|
||||
|
||||
const signatures = contextualType.getCallSignatures();
|
||||
if (signatures.length !== 1) return undefined;
|
||||
|
||||
const invocation: ContextualInvocation = { kind: InvocationKind.Contextual, signature: first(signatures), node: startingToken, symbol: chooseBetterSymbol(contextualType.symbol) };
|
||||
return { isTypeParameterList: false, invocation, argumentsSpan, argumentIndex, argumentCount };
|
||||
}
|
||||
|
||||
interface ContextualSignatureLocationInfo {readonly contextualType: Type; readonly argumentIndex: number; readonly argumentCount: number; readonly argumentsSpan: TextSpan; }
|
||||
function getContextualSignatureLocationInfo(startingToken: Node, sourceFile: SourceFile, checker: TypeChecker): ContextualSignatureLocationInfo | undefined {
|
||||
if (startingToken.kind !== SyntaxKind.OpenParenToken && startingToken.kind !== SyntaxKind.CommaToken) return undefined;
|
||||
const { parent } = startingToken;
|
||||
switch (parent.kind) {
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
const info = getArgumentOrParameterListInfo(startingToken, sourceFile);
|
||||
if (!info) return undefined;
|
||||
const { argumentIndex, argumentCount, argumentsSpan } = info;
|
||||
const contextualType = isMethodDeclaration(parent) ? checker.getContextualTypeForObjectLiteralElement(parent) : checker.getContextualType(parent as ParenthesizedExpression | FunctionExpression | ArrowFunction);
|
||||
return contextualType && { contextualType, argumentIndex, argumentCount, argumentsSpan };
|
||||
case SyntaxKind.BinaryExpression: {
|
||||
const highestBinary = getHighestBinary(parent as BinaryExpression);
|
||||
const contextualType = checker.getContextualType(highestBinary);
|
||||
const argumentIndex = startingToken.kind === SyntaxKind.OpenParenToken ? 0 : countBinaryExpressionParameters(parent as BinaryExpression) - 1;
|
||||
const argumentCount = countBinaryExpressionParameters(highestBinary);
|
||||
return contextualType && { contextualType, argumentIndex, argumentCount, argumentsSpan: createTextSpanFromNode(parent) };
|
||||
}
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
// The type of a function type node has a symbol at that node, but it's better to use the symbol for a parameter or type alias.
|
||||
function chooseBetterSymbol(s: Symbol): Symbol {
|
||||
return s.name === InternalSymbolName.Type
|
||||
? firstDefined(s.declarations, d => isFunctionTypeNode(d) ? d.parent.symbol : undefined) || s
|
||||
: s;
|
||||
}
|
||||
|
||||
function getArgumentIndex(argumentsList: Node, node: Node) {
|
||||
@@ -323,7 +388,7 @@ namespace ts.SignatureHelp {
|
||||
Debug.assertLessThan(argumentIndex, argumentCount);
|
||||
}
|
||||
return {
|
||||
kind: ArgumentListKind.TaggedTemplateArguments,
|
||||
isTypeParameterList: false,
|
||||
invocation: { kind: InvocationKind.Call, node: tagExpression },
|
||||
argumentsSpan: getApplicableSpanForTaggedTemplate(tagExpression, sourceFile),
|
||||
argumentIndex,
|
||||
@@ -368,12 +433,12 @@ namespace ts.SignatureHelp {
|
||||
return createTextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart);
|
||||
}
|
||||
|
||||
function getContainingArgumentInfo(node: Node, position: number, sourceFile: SourceFile): ArgumentListInfo | undefined {
|
||||
function getContainingArgumentInfo(node: Node, position: number, sourceFile: SourceFile, checker: TypeChecker): ArgumentListInfo | undefined {
|
||||
for (let n = node; !isBlock(n) && !isSourceFile(n); n = n.parent) {
|
||||
// If the node is not a subspan of its parent, this is a big problem.
|
||||
// There have been crashes that might be caused by this violation.
|
||||
Debug.assert(rangeContainsRange(n.parent, n), "Not a subspan", () => `Child: ${Debug.showSyntaxKind(n)}, parent: ${Debug.showSyntaxKind(n.parent)}`);
|
||||
const argumentInfo = getImmediatelyContainingArgumentInfo(n, position, sourceFile);
|
||||
const argumentInfo = getImmediatelyContainingArgumentOrContextualParameterInfo(n, position, sourceFile, checker);
|
||||
if (argumentInfo) {
|
||||
return argumentInfo;
|
||||
}
|
||||
@@ -388,17 +453,20 @@ namespace ts.SignatureHelp {
|
||||
return children[indexOfOpenerToken + 1];
|
||||
}
|
||||
|
||||
function getExpressionFromInvocation(invocation: Invocation): Expression {
|
||||
function getExpressionFromInvocation(invocation: CallInvocation | TypeArgsInvocation): Expression {
|
||||
return invocation.kind === InvocationKind.Call ? getInvokedExpression(invocation.node) : invocation.called;
|
||||
}
|
||||
|
||||
const signatureHelpNodeBuilderFlags = NodeBuilderFlags.OmitParameterModifiers | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope;
|
||||
function createSignatureHelpItems(candidates: ReadonlyArray<Signature>, resolvedSignature: Signature, argumentListInfo: ArgumentListInfo, sourceFile: SourceFile, typeChecker: TypeChecker): SignatureHelpItems {
|
||||
const { argumentCount, argumentsSpan: applicableSpan, invocation, argumentIndex } = argumentListInfo;
|
||||
const isTypeParameterList = argumentListInfo.kind === ArgumentListKind.TypeArguments;
|
||||
|
||||
const enclosingDeclaration = invocation.kind === InvocationKind.Call ? invocation.node : invocation.called;
|
||||
const callTargetSymbol = typeChecker.getSymbolAtLocation(getExpressionFromInvocation(invocation));
|
||||
function createSignatureHelpItems(
|
||||
candidates: ReadonlyArray<Signature>,
|
||||
resolvedSignature: Signature,
|
||||
{ isTypeParameterList, argumentCount, argumentsSpan: applicableSpan, invocation, argumentIndex }: ArgumentListInfo,
|
||||
sourceFile: SourceFile,
|
||||
typeChecker: TypeChecker,
|
||||
): SignatureHelpItems {
|
||||
const enclosingDeclaration = invocation.kind === InvocationKind.Call ? invocation.node : invocation.kind === InvocationKind.TypeArgs ? invocation.called : invocation.node;
|
||||
const callTargetSymbol = invocation.kind === InvocationKind.Contextual ? invocation.symbol : typeChecker.getSymbolAtLocation(getExpressionFromInvocation(invocation));
|
||||
const callTargetDisplayParts = callTargetSymbol ? symbolToDisplayParts(typeChecker, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined) : emptyArray;
|
||||
const items = candidates.map(candidateSignature => getSignatureHelpItem(candidateSignature, callTargetDisplayParts, isTypeParameterList, typeChecker, enclosingDeclaration, sourceFile));
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ namespace ts {
|
||||
export function computeSuggestionDiagnostics(sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken): DiagnosticWithLocation[] {
|
||||
program.getSemanticDiagnostics(sourceFile, cancellationToken);
|
||||
const diags: DiagnosticWithLocation[] = [];
|
||||
const checker = program.getDiagnosticsProducingTypeChecker();
|
||||
|
||||
if (sourceFile.commonJsModuleIndicator &&
|
||||
(programContainsEs6Modules(program) || compilerOptionsIndicateEs6Modules(program.getCompilerOptions())) &&
|
||||
@@ -68,6 +69,9 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (isFunctionLikeDeclaration(node)) {
|
||||
addConvertToAsyncFunctionDiagnostics(node, checker, diags);
|
||||
}
|
||||
node.forEachChild(check);
|
||||
}
|
||||
}
|
||||
@@ -109,7 +113,64 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function addConvertToAsyncFunctionDiagnostics(node: FunctionLikeDeclaration, checker: TypeChecker, diags: DiagnosticWithLocation[]): void {
|
||||
|
||||
const functionType = node.type ? checker.getTypeFromTypeNode(node.type) : undefined;
|
||||
if (isAsyncFunction(node) || !node.body || !functionType) {
|
||||
return;
|
||||
}
|
||||
|
||||
const callSignatures = checker.getSignaturesOfType(functionType, SignatureKind.Call);
|
||||
const returnType = callSignatures.length ? checker.getReturnTypeOfSignature(callSignatures[0]) : undefined;
|
||||
|
||||
if (!returnType || !checker.getPromisedTypeOfPromise(returnType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// collect all the return statements
|
||||
// check that a property access expression exists in there and that it is a handler
|
||||
const returnStatements = getReturnStatementsWithPromiseHandlers(node);
|
||||
if (returnStatements.length > 0) {
|
||||
diags.push(createDiagnosticForNode(isVariableDeclaration(node.parent) ? node.parent.name : node, Diagnostics.This_may_be_converted_to_an_async_function));
|
||||
}
|
||||
}
|
||||
|
||||
function getErrorNodeFromCommonJsIndicator(commonJsModuleIndicator: Node): Node {
|
||||
return isBinaryExpression(commonJsModuleIndicator) ? commonJsModuleIndicator.left : commonJsModuleIndicator;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function getReturnStatementsWithPromiseHandlers(node: Node): Node[] {
|
||||
const returnStatements: Node[] = [];
|
||||
if (isFunctionLike(node)) {
|
||||
forEachChild(node, visit);
|
||||
}
|
||||
else {
|
||||
visit(node);
|
||||
}
|
||||
|
||||
function visit(child: Node) {
|
||||
if (isFunctionLike(child)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isReturnStatement(child)) {
|
||||
forEachChild(child, addHandlers);
|
||||
}
|
||||
|
||||
function addHandlers(returnChild: Node) {
|
||||
if (isPromiseHandler(returnChild)) {
|
||||
returnStatements.push(child as ReturnStatement);
|
||||
}
|
||||
}
|
||||
|
||||
forEachChild(child, visit);
|
||||
}
|
||||
return returnStatements;
|
||||
}
|
||||
|
||||
function isPromiseHandler(node: Node): boolean {
|
||||
return (isCallExpression(node) && isPropertyAccessExpression(node.expression) &&
|
||||
(node.expression.name.text === "then" || node.expression.name.text === "catch"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -611,7 +611,8 @@ namespace ts.SymbolDisplay {
|
||||
displayParts.push(textPart(allSignatures.length === 2 ? "overload" : "overloads"));
|
||||
displayParts.push(punctuationPart(SyntaxKind.CloseParenToken));
|
||||
}
|
||||
documentation = signature.getDocumentationComment(typeChecker);
|
||||
const docComment = signature.getDocumentationComment(typeChecker);
|
||||
documentation = docComment.length === 0 ? undefined : docComment;
|
||||
tags = signature.getJsDocTags();
|
||||
}
|
||||
|
||||
|
||||
@@ -409,14 +409,14 @@ namespace ts.textChanges {
|
||||
});
|
||||
}
|
||||
|
||||
public insertNodeAtClassStart(sourceFile: SourceFile, cls: ClassLikeDeclaration, newElement: ClassElement): void {
|
||||
public insertNodeAtClassStart(sourceFile: SourceFile, cls: ClassLikeDeclaration | InterfaceDeclaration, newElement: ClassElement): void {
|
||||
const clsStart = cls.getStart(sourceFile);
|
||||
const indentation = formatting.SmartIndenter.findFirstNonWhitespaceColumn(getLineStartPositionForPosition(clsStart, sourceFile), clsStart, sourceFile, this.formatContext.options)
|
||||
+ this.formatContext.options.indentSize!;
|
||||
this.insertNodeAt(sourceFile, cls.members.pos, newElement, { indentation, ...this.getInsertNodeAtClassStartPrefixSuffix(sourceFile, cls) });
|
||||
}
|
||||
|
||||
private getInsertNodeAtClassStartPrefixSuffix(sourceFile: SourceFile, cls: ClassLikeDeclaration): { prefix: string, suffix: string } {
|
||||
private getInsertNodeAtClassStartPrefixSuffix(sourceFile: SourceFile, cls: ClassLikeDeclaration | InterfaceDeclaration): { prefix: string, suffix: string } {
|
||||
if (cls.members.length === 0) {
|
||||
if (addToSeen(this.classesWithNodesInsertedAtStart, getNodeId(cls), cls)) {
|
||||
// For `class C {\n}`, don't add the trailing "\n"
|
||||
@@ -708,7 +708,7 @@ namespace ts.textChanges {
|
||||
return skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, node, {}, Position.FullStart), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
|
||||
}
|
||||
|
||||
function getClassBraceEnds(cls: ClassLikeDeclaration, sourceFile: SourceFile): [number, number] {
|
||||
function getClassBraceEnds(cls: ClassLikeDeclaration | InterfaceDeclaration, sourceFile: SourceFile): [number, number] {
|
||||
return [findChildOfKind(cls, SyntaxKind.OpenBraceToken, sourceFile)!.end, findChildOfKind(cls, SyntaxKind.CloseBraceToken, sourceFile)!.end];
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
"codefixes/addMissingInvocationForDecorator.ts",
|
||||
"codefixes/annotateWithTypeFromJSDoc.ts",
|
||||
"codefixes/convertFunctionToEs6Class.ts",
|
||||
"codefixes/convertToAsyncFunction.ts",
|
||||
"codefixes/convertToEs6Module.ts",
|
||||
"codefixes/correctQualifiedNameToIndexedAccessType.ts",
|
||||
"codefixes/fixClassIncorrectlyImplementsInterface.ts",
|
||||
|
||||
@@ -226,7 +226,7 @@ namespace ts {
|
||||
|
||||
export function isJumpStatementTarget(node: Node): node is Identifier & { parent: BreakOrContinueStatement } {
|
||||
return node.kind === SyntaxKind.Identifier && isBreakOrContinueStatement(node.parent) && node.parent.label === node;
|
||||
}
|
||||
}
|
||||
|
||||
export function isLabelOfLabeledStatement(node: Node): node is Identifier {
|
||||
return node.kind === SyntaxKind.Identifier && isLabeledStatement(node.parent) && node.parent.label === node;
|
||||
@@ -396,7 +396,7 @@ namespace ts {
|
||||
export function isThis(node: Node): boolean {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ThisKeyword:
|
||||
// case SyntaxKind.ThisType: TODO: GH#9267
|
||||
// case SyntaxKind.ThisType: TODO: GH#9267
|
||||
return true;
|
||||
case SyntaxKind.Identifier:
|
||||
// 'this' as a parameter
|
||||
@@ -1187,6 +1187,7 @@ namespace ts {
|
||||
export const typeKeywords: ReadonlyArray<SyntaxKind> = [
|
||||
SyntaxKind.AnyKeyword,
|
||||
SyntaxKind.BooleanKeyword,
|
||||
SyntaxKind.FalseKeyword,
|
||||
SyntaxKind.KeyOfKeyword,
|
||||
SyntaxKind.NeverKeyword,
|
||||
SyntaxKind.NullKeyword,
|
||||
@@ -1194,6 +1195,7 @@ namespace ts {
|
||||
SyntaxKind.ObjectKeyword,
|
||||
SyntaxKind.StringKeyword,
|
||||
SyntaxKind.SymbolKeyword,
|
||||
SyntaxKind.TrueKeyword,
|
||||
SyntaxKind.VoidKeyword,
|
||||
SyntaxKind.UndefinedKeyword,
|
||||
SyntaxKind.UniqueKeyword,
|
||||
@@ -1232,13 +1234,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function skipConstraint(type: Type): Type {
|
||||
return type.isTypeParameter() ? type.getConstraint()! : type; // TODO: GH#18217
|
||||
return type.isTypeParameter() ? type.getConstraint() || type : type;
|
||||
}
|
||||
|
||||
export function getNameFromPropertyName(name: PropertyName): string | undefined {
|
||||
return name.kind === SyntaxKind.ComputedPropertyName
|
||||
// treat computed property names where expression is string/numeric literal as just string/numeric literal
|
||||
? isStringOrNumericLiteral(name.expression) ? name.expression.text : undefined
|
||||
? isStringOrNumericLiteralLike(name.expression) ? name.expression.text : undefined
|
||||
: getTextOfIdentifierOrLiteral(name);
|
||||
}
|
||||
|
||||
@@ -1654,8 +1656,34 @@ namespace ts {
|
||||
return clone;
|
||||
}
|
||||
|
||||
function getSynthesizedDeepCloneWorker<T extends Node>(node: T): T {
|
||||
const visited = visitEachChild(node, getSynthesizedDeepClone, nullTransformationContext);
|
||||
export function getSynthesizedDeepCloneWithRenames<T extends Node | undefined>(node: T, includeTrivia = true, renameMap?: Map<Identifier>, checker?: TypeChecker, callback?: (originalNode: Node, clone: Node) => any): T {
|
||||
|
||||
let clone;
|
||||
if (node && isIdentifier(node!) && renameMap && checker) {
|
||||
const symbol = checker.getSymbolAtLocation(node!);
|
||||
const renameInfo = symbol && renameMap.get(String(getSymbolId(symbol)));
|
||||
|
||||
if (renameInfo) {
|
||||
clone = createIdentifier(renameInfo.text);
|
||||
}
|
||||
}
|
||||
|
||||
if (!clone) {
|
||||
clone = node && getSynthesizedDeepCloneWorker(node as NonNullable<T>, renameMap, checker, callback);
|
||||
}
|
||||
|
||||
if (clone && !includeTrivia) suppressLeadingAndTrailingTrivia(clone);
|
||||
if (callback && node) callback(node!, clone);
|
||||
|
||||
return clone as T;
|
||||
}
|
||||
|
||||
|
||||
function getSynthesizedDeepCloneWorker<T extends Node>(node: T, renameMap?: Map<Identifier>, checker?: TypeChecker, callback?: (originalNode: Node, clone: Node) => any): T {
|
||||
const visited = (renameMap || checker || callback) ?
|
||||
visitEachChild(node, wrapper, nullTransformationContext) :
|
||||
visitEachChild(node, getSynthesizedDeepClone, nullTransformationContext);
|
||||
|
||||
if (visited === node) {
|
||||
// This only happens for leaf nodes - internal nodes always see their children change.
|
||||
const clone = getSynthesizedClone(node);
|
||||
@@ -1673,6 +1701,10 @@ namespace ts {
|
||||
// would have made.
|
||||
visited.parent = undefined!;
|
||||
return visited;
|
||||
|
||||
function wrapper(node: T) {
|
||||
return getSynthesizedDeepCloneWithRenames(node, /*includeTrivia*/ true, renameMap, checker, callback);
|
||||
}
|
||||
}
|
||||
|
||||
export function getSynthesizedDeepClones<T extends Node>(nodes: NodeArray<T>, includeTrivia?: boolean): NodeArray<T>;
|
||||
|
||||
@@ -207,24 +207,19 @@ class CompilerTest {
|
||||
|
||||
public verifyModuleResolution() {
|
||||
if (this.options.traceResolution) {
|
||||
Harness.Baseline.runBaseline(this.justName.replace(/\.tsx?$/, ".trace.json"), () => {
|
||||
return utils.removeTestPathPrefixes(JSON.stringify(this.result.traces, undefined, 4));
|
||||
});
|
||||
Harness.Baseline.runBaseline(this.justName.replace(/\.tsx?$/, ".trace.json"),
|
||||
utils.removeTestPathPrefixes(JSON.stringify(this.result.traces, undefined, 4)));
|
||||
}
|
||||
}
|
||||
|
||||
public verifySourceMapRecord() {
|
||||
if (this.options.sourceMap || this.options.inlineSourceMap || this.options.declarationMap) {
|
||||
Harness.Baseline.runBaseline(this.justName.replace(/\.tsx?$/, ".sourcemap.txt"), () => {
|
||||
const record = utils.removeTestPathPrefixes(this.result.getSourceMapRecord()!);
|
||||
if ((this.options.noEmitOnError && this.result.diagnostics.length !== 0) || record === undefined) {
|
||||
// Because of the noEmitOnError option no files are created. We need to return null because baselining isn't required.
|
||||
/* tslint:disable:no-null-keyword */
|
||||
return null;
|
||||
/* tslint:enable:no-null-keyword */
|
||||
}
|
||||
return record;
|
||||
});
|
||||
const record = utils.removeTestPathPrefixes(this.result.getSourceMapRecord()!);
|
||||
const baseline = (this.options.noEmitOnError && this.result.diagnostics.length !== 0) || record === undefined
|
||||
// Because of the noEmitOnError option no files are created. We need to return null because baselining isn't required.
|
||||
? null // tslint:disable-line no-null-keyword
|
||||
: record;
|
||||
Harness.Baseline.runBaseline(this.justName.replace(/\.tsx?$/, ".sourcemap.txt"), baseline);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,7 +253,13 @@ class CompilerTest {
|
||||
Harness.Compiler.doTypeAndSymbolBaseline(
|
||||
this.justName,
|
||||
this.result.program!,
|
||||
this.toBeCompiled.concat(this.otherFiles).filter(file => !!this.result.program!.getSourceFile(file.unitName)));
|
||||
this.toBeCompiled.concat(this.otherFiles).filter(file => !!this.result.program!.getSourceFile(file.unitName)),
|
||||
/*opts*/ undefined,
|
||||
/*multifile*/ undefined,
|
||||
/*skipTypeBaselines*/ undefined,
|
||||
/*skipSymbolBaselines*/ undefined,
|
||||
!!ts.length(this.result.diagnostics)
|
||||
);
|
||||
}
|
||||
|
||||
private makeUnitName(name: string, root: string) {
|
||||
|
||||
@@ -80,9 +80,7 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
|
||||
if (install.status !== 0) throw new Error(`NPM Install types for ${directoryName} failed: ${install.stderr.toString()}`);
|
||||
}
|
||||
args.push("--noEmit");
|
||||
Harness.Baseline.runBaseline(`${cls.kind()}/${directoryName}.log`, () => {
|
||||
return cls.report(cp.spawnSync(`node`, args, { cwd, timeout, shell: true }), cwd);
|
||||
});
|
||||
Harness.Baseline.runBaseline(`${cls.kind()}/${directoryName}.log`, cls.report(cp.spawnSync(`node`, args, { cwd, timeout, shell: true }), cwd));
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -138,7 +136,8 @@ function compareErrorStrings(a: string[], b: string[]) {
|
||||
return ts.comparePathsCaseSensitive(errorFileA, errorFileB) ||
|
||||
ts.compareValues(parseInt(lineNumberStringA), parseInt(lineNumberStringB)) ||
|
||||
ts.compareValues(parseInt(columnNumberStringA), parseInt(columnNumberStringB)) ||
|
||||
ts.compareStringsCaseSensitive(remainderA, remainderB);
|
||||
ts.compareStringsCaseSensitive(remainderA, remainderB) ||
|
||||
ts.compareStringsCaseSensitive(a.slice(1).join("\n"), b.slice(1).join("\n"));
|
||||
}
|
||||
|
||||
class DefinitelyTypedRunner extends ExternalCompileRunnerBase {
|
||||
|
||||
@@ -211,14 +211,12 @@ namespace project {
|
||||
.map(output => utils.removeTestPathPrefixes(vpath.isAbsolute(output) ? vpath.relative(cwd, output, ignoreCase) : output));
|
||||
|
||||
const content = JSON.stringify(resolutionInfo, undefined, " ");
|
||||
Harness.Baseline.runBaseline(this.getBaselineFolder(this.compilerResult.moduleKind) + this.testCaseJustName + ".json", () => content);
|
||||
Harness.Baseline.runBaseline(this.getBaselineFolder(this.compilerResult.moduleKind) + this.testCaseJustName + ".json", content);
|
||||
}
|
||||
|
||||
public verifyDiagnostics() {
|
||||
if (this.compilerResult.errors.length) {
|
||||
Harness.Baseline.runBaseline(this.getBaselineFolder(this.compilerResult.moduleKind) + this.testCaseJustName + ".errors.txt", () => {
|
||||
return getErrorsBaseline(this.compilerResult);
|
||||
});
|
||||
Harness.Baseline.runBaseline(this.getBaselineFolder(this.compilerResult.moduleKind) + this.testCaseJustName + ".errors.txt", getErrorsBaseline(this.compilerResult));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,7 +242,7 @@ namespace project {
|
||||
}
|
||||
|
||||
const content = utils.removeTestPathPrefixes(output.text, /*retainTrailingDirectorySeparator*/ true);
|
||||
Harness.Baseline.runBaseline(this.getBaselineFolder(this.compilerResult.moduleKind) + diskRelativeName, () => content as string | null); // TODO: GH#18217
|
||||
Harness.Baseline.runBaseline(this.getBaselineFolder(this.compilerResult.moduleKind) + diskRelativeName, content as string | null); // TODO: GH#18217
|
||||
}
|
||||
catch (e) {
|
||||
errs.push(e);
|
||||
@@ -271,9 +269,7 @@ namespace project {
|
||||
if (!this.compilerResult.errors.length && this.testCase.declaration) {
|
||||
const dTsCompileResult = this.compileDeclarations(this.compilerResult);
|
||||
if (dTsCompileResult && dTsCompileResult.errors.length) {
|
||||
Harness.Baseline.runBaseline(this.getBaselineFolder(this.compilerResult.moduleKind) + this.testCaseJustName + ".dts.errors.txt", () => {
|
||||
return getErrorsBaseline(dTsCompileResult);
|
||||
});
|
||||
Harness.Baseline.runBaseline(this.getBaselineFolder(this.compilerResult.moduleKind) + this.testCaseJustName + ".dts.errors.txt", getErrorsBaseline(dTsCompileResult));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,21 +63,14 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
});
|
||||
|
||||
it("has the expected emitted code", () => {
|
||||
Harness.Baseline.runBaseline(testState.filename + ".output.js", () => {
|
||||
const files = Array.from(testState.compilerResult.js.values()).filter(f => f.file !== Test262BaselineRunner.helpersFilePath);
|
||||
return Harness.Compiler.collateOutputs(files);
|
||||
}, Test262BaselineRunner.baselineOptions);
|
||||
const files = Array.from(testState.compilerResult.js.values()).filter(f => f.file !== Test262BaselineRunner.helpersFilePath);
|
||||
Harness.Baseline.runBaseline(testState.filename + ".output.js", Harness.Compiler.collateOutputs(files), Test262BaselineRunner.baselineOptions);
|
||||
});
|
||||
|
||||
it("has the expected errors", () => {
|
||||
Harness.Baseline.runBaseline(testState.filename + ".errors.txt", () => {
|
||||
const errors = testState.compilerResult.diagnostics;
|
||||
if (errors.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Harness.Compiler.getErrorBaseline(testState.inputFiles, errors);
|
||||
}, Test262BaselineRunner.baselineOptions);
|
||||
const errors = testState.compilerResult.diagnostics;
|
||||
const baseline = errors.length === 0 ? null : Harness.Compiler.getErrorBaseline(testState.inputFiles, errors);
|
||||
Harness.Baseline.runBaseline(testState.filename + ".errors.txt", baseline, Test262BaselineRunner.baselineOptions);
|
||||
});
|
||||
|
||||
it("satisfies invariants", () => {
|
||||
@@ -86,10 +79,8 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
});
|
||||
|
||||
it("has the expected AST", () => {
|
||||
Harness.Baseline.runBaseline(testState.filename + ".AST.txt", () => {
|
||||
const sourceFile = testState.compilerResult.program!.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename))!;
|
||||
return Utils.sourceFileToJSON(sourceFile);
|
||||
}, Test262BaselineRunner.baselineOptions);
|
||||
const sourceFile = testState.compilerResult.program!.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename))!;
|
||||
Harness.Baseline.runBaseline(testState.filename + ".AST.txt", Utils.sourceFileToJSON(sourceFile), Test262BaselineRunner.baselineOptions);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
"unittests/compileOnSave.ts",
|
||||
"unittests/configurationExtension.ts",
|
||||
"unittests/convertCompilerOptionsFromJson.ts",
|
||||
"unittests/convertToAsyncFunction.ts",
|
||||
"unittests/convertToBase64.ts",
|
||||
"unittests/convertTypeAcquisitionFromJson.ts",
|
||||
"unittests/customTransforms.ts",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,15 +20,13 @@ namespace ts {
|
||||
|
||||
const program = createProgram(arrayFrom(fileMap.keys()), options, host);
|
||||
program.emit(/*targetSourceFile*/ undefined, host.writeFile, /*cancellationToken*/ undefined, /*emitOnlyDtsFiles*/ false, customTransformers);
|
||||
Harness.Baseline.runBaseline(`customTransforms/${name}.js`, () => {
|
||||
let content = "";
|
||||
for (const [file, text] of arrayFrom(outputs.entries())) {
|
||||
if (content) content += "\n\n";
|
||||
content += `// [${file}]\n`;
|
||||
content += text;
|
||||
}
|
||||
return content;
|
||||
});
|
||||
let content = "";
|
||||
for (const [file, text] of arrayFrom(outputs.entries())) {
|
||||
if (content) content += "\n\n";
|
||||
content += `// [${file}]\n`;
|
||||
content += text;
|
||||
}
|
||||
Harness.Baseline.runBaseline(`customTransforms/${name}.js`, content);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ namespace ts {
|
||||
placeOpenBraceOnNewLineForControlBlocks: false,
|
||||
};
|
||||
|
||||
const notImplementedHost: LanguageServiceHost = {
|
||||
export const notImplementedHost: LanguageServiceHost = {
|
||||
getCompilationSettings: notImplemented,
|
||||
getScriptFileNames: notImplemented,
|
||||
getScriptVersion: notImplemented,
|
||||
@@ -131,23 +131,21 @@ namespace ts {
|
||||
const infos = refactor.extractSymbol.getAvailableActions(context)!;
|
||||
const actions = find(infos, info => info.description === description.message)!.actions;
|
||||
|
||||
Harness.Baseline.runBaseline(`${baselineFolder}/${caption}${extension}`, () => {
|
||||
const data: string[] = [];
|
||||
data.push(`// ==ORIGINAL==`);
|
||||
data.push(text.replace("[#|", "/*[#|*/").replace("|]", "/*|]*/"));
|
||||
for (const action of actions) {
|
||||
const { renameLocation, edits } = refactor.extractSymbol.getEditsForAction(context, action.name)!;
|
||||
assert.lengthOf(edits, 1);
|
||||
data.push(`// ==SCOPE::${action.description}==`);
|
||||
const newText = textChanges.applyChanges(sourceFile.text, edits[0].textChanges);
|
||||
const newTextWithRename = newText.slice(0, renameLocation) + "/*RENAME*/" + newText.slice(renameLocation);
|
||||
data.push(newTextWithRename);
|
||||
const data: string[] = [];
|
||||
data.push(`// ==ORIGINAL==`);
|
||||
data.push(text.replace("[#|", "/*[#|*/").replace("|]", "/*|]*/"));
|
||||
for (const action of actions) {
|
||||
const { renameLocation, edits } = refactor.extractSymbol.getEditsForAction(context, action.name)!;
|
||||
assert.lengthOf(edits, 1);
|
||||
data.push(`// ==SCOPE::${action.description}==`);
|
||||
const newText = textChanges.applyChanges(sourceFile.text, edits[0].textChanges);
|
||||
const newTextWithRename = newText.slice(0, renameLocation) + "/*RENAME*/" + newText.slice(renameLocation);
|
||||
data.push(newTextWithRename);
|
||||
|
||||
const diagProgram = makeProgram({ path, content: newText }, includeLib);
|
||||
assert.isFalse(hasSyntacticDiagnostics(diagProgram));
|
||||
}
|
||||
return data.join(newLineCharacter);
|
||||
});
|
||||
const diagProgram = makeProgram({ path, content: newText }, includeLib);
|
||||
assert.isFalse(hasSyntacticDiagnostics(diagProgram));
|
||||
}
|
||||
Harness.Baseline.runBaseline(`${baselineFolder}/${caption}${extension}`, data.join(newLineCharacter));
|
||||
}
|
||||
|
||||
function makeProgram(f: {path: string, content: string }, includeLib?: boolean) {
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace ts {
|
||||
const outputFileName = `tsConfig/${name.replace(/[^a-z0-9\-. ]/ig, "")}/tsconfig.json`;
|
||||
|
||||
it(`Correct output for ${outputFileName}`, () => {
|
||||
Harness.Baseline.runBaseline(outputFileName, () => initResult);
|
||||
Harness.Baseline.runBaseline(outputFileName, initResult);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace ts {
|
||||
assert.isTrue(typeAndDiagnostics && typeAndDiagnostics.diagnostics.length === 0, "no errors issued");
|
||||
|
||||
Harness.Baseline.runBaseline("JSDocParsing/TypeExpressions.parsesCorrectly." + name + ".json",
|
||||
() => Utils.sourceFileToJSON(typeAndDiagnostics!.jsDocTypeExpression.type));
|
||||
Utils.sourceFileToJSON(typeAndDiagnostics!.jsDocTypeExpression.type));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
Harness.Baseline.runBaseline("JSDocParsing/DocComments.parsesCorrectly." + name + ".json",
|
||||
() => JSON.stringify(comment.jsDoc,
|
||||
JSON.stringify(comment.jsDoc,
|
||||
(_, v) => v && v.pos !== undefined ? JSON.parse(Utils.sourceFileToJSON(v)) : v, 4));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -194,6 +194,88 @@ namespace ts {
|
||||
});
|
||||
|
||||
describe("Node module resolution - non-relative paths", () => {
|
||||
it("computes correct commonPrefix for moduleName cache", () => {
|
||||
const resolutionCache = createModuleResolutionCache("/", (f) => f);
|
||||
let cache = resolutionCache.getOrCreateCacheForModuleName("a");
|
||||
cache.set("/sub", {
|
||||
resolvedModule: {
|
||||
originalPath: undefined,
|
||||
resolvedFileName: "/sub/node_modules/a/index.ts",
|
||||
isExternalLibraryImport: true,
|
||||
extension: Extension.Ts,
|
||||
},
|
||||
failedLookupLocations: [],
|
||||
});
|
||||
assert.isDefined(cache.get("/sub"));
|
||||
assert.isUndefined(cache.get("/"));
|
||||
|
||||
cache = resolutionCache.getOrCreateCacheForModuleName("b");
|
||||
cache.set("/sub/dir/foo", {
|
||||
resolvedModule: {
|
||||
originalPath: undefined,
|
||||
resolvedFileName: "/sub/directory/node_modules/b/index.ts",
|
||||
isExternalLibraryImport: true,
|
||||
extension: Extension.Ts,
|
||||
},
|
||||
failedLookupLocations: [],
|
||||
});
|
||||
assert.isDefined(cache.get("/sub/dir/foo"));
|
||||
assert.isDefined(cache.get("/sub/dir"));
|
||||
assert.isDefined(cache.get("/sub"));
|
||||
assert.isUndefined(cache.get("/"));
|
||||
|
||||
cache = resolutionCache.getOrCreateCacheForModuleName("c");
|
||||
cache.set("/foo/bar", {
|
||||
resolvedModule: {
|
||||
originalPath: undefined,
|
||||
resolvedFileName: "/bar/node_modules/c/index.ts",
|
||||
isExternalLibraryImport: true,
|
||||
extension: Extension.Ts,
|
||||
},
|
||||
failedLookupLocations: [],
|
||||
});
|
||||
assert.isDefined(cache.get("/foo/bar"));
|
||||
assert.isDefined(cache.get("/foo"));
|
||||
assert.isDefined(cache.get("/"));
|
||||
|
||||
cache = resolutionCache.getOrCreateCacheForModuleName("d");
|
||||
cache.set("/foo", {
|
||||
resolvedModule: {
|
||||
originalPath: undefined,
|
||||
resolvedFileName: "/foo/index.ts",
|
||||
isExternalLibraryImport: true,
|
||||
extension: Extension.Ts,
|
||||
},
|
||||
failedLookupLocations: [],
|
||||
});
|
||||
assert.isDefined(cache.get("/foo"));
|
||||
assert.isUndefined(cache.get("/"));
|
||||
|
||||
cache = resolutionCache.getOrCreateCacheForModuleName("e");
|
||||
cache.set("c:/foo", {
|
||||
resolvedModule: {
|
||||
originalPath: undefined,
|
||||
resolvedFileName: "d:/bar/node_modules/e/index.ts",
|
||||
isExternalLibraryImport: true,
|
||||
extension: Extension.Ts,
|
||||
},
|
||||
failedLookupLocations: [],
|
||||
});
|
||||
assert.isDefined(cache.get("c:/foo"));
|
||||
assert.isDefined(cache.get("c:/"));
|
||||
assert.isUndefined(cache.get("d:/"));
|
||||
|
||||
cache = resolutionCache.getOrCreateCacheForModuleName("f");
|
||||
cache.set("/foo/bar/baz", {
|
||||
resolvedModule: undefined,
|
||||
failedLookupLocations: [],
|
||||
});
|
||||
assert.isDefined(cache.get("/foo/bar/baz"));
|
||||
assert.isDefined(cache.get("/foo/bar"));
|
||||
assert.isDefined(cache.get("/foo"));
|
||||
assert.isDefined(cache.get("/"));
|
||||
});
|
||||
|
||||
it("load module as file - ts files not loaded", () => {
|
||||
test(/*hasDirectoryExists*/ false);
|
||||
test(/*hasDirectoryExists*/ true);
|
||||
@@ -321,6 +403,47 @@ namespace ts {
|
||||
checkResolvedModule(resolution.resolvedModule, createResolvedModule(resolvedFileName, /*isExternalLibraryImport*/ true));
|
||||
});
|
||||
}
|
||||
|
||||
it("uses originalPath for caching", () => {
|
||||
const host = createModuleResolutionHost(
|
||||
/*hasDirectoryExists*/ true,
|
||||
{
|
||||
name: "/modules/a.ts",
|
||||
symlinks: ["/sub/node_modules/a/index.ts"],
|
||||
},
|
||||
{
|
||||
name: "/sub/node_modules/a/package.json",
|
||||
content: '{"version": "0.0.0", "main": "./index"}'
|
||||
}
|
||||
);
|
||||
const compilerOptions: CompilerOptions = { moduleResolution: ModuleResolutionKind.NodeJs };
|
||||
const cache = createModuleResolutionCache("/", (f) => f);
|
||||
let resolution = resolveModuleName("a", "/sub/dir/foo.ts", compilerOptions, host, cache);
|
||||
checkResolvedModule(resolution.resolvedModule, createResolvedModule("/modules/a.ts", /*isExternalLibraryImport*/ true));
|
||||
|
||||
resolution = resolveModuleName("a", "/sub/foo.ts", compilerOptions, host, cache);
|
||||
checkResolvedModule(resolution.resolvedModule, createResolvedModule("/modules/a.ts", /*isExternalLibraryImport*/ true));
|
||||
|
||||
resolution = resolveModuleName("a", "/foo.ts", compilerOptions, host, cache);
|
||||
assert.isUndefined(resolution.resolvedModule, "lookup in parent directory doesn't hit the cache");
|
||||
});
|
||||
|
||||
it("preserves originalPath on cache hit", () => {
|
||||
const host = createModuleResolutionHost(
|
||||
/*hasDirectoryExists*/ true,
|
||||
{ name: "/linked/index.d.ts", symlinks: ["/app/node_modules/linked/index.d.ts"] },
|
||||
{ name: "/app/node_modules/linked/package.json", content: '{"version": "0.0.0", "main": "./index"}' },
|
||||
);
|
||||
const cache = createModuleResolutionCache("/", (f) => f);
|
||||
const compilerOptions: CompilerOptions = { moduleResolution: ModuleResolutionKind.NodeJs };
|
||||
checkResolution(resolveModuleName("linked", "/app/src/app.ts", compilerOptions, host, cache));
|
||||
checkResolution(resolveModuleName("linked", "/app/lib/main.ts", compilerOptions, host, cache));
|
||||
|
||||
function checkResolution(resolution: ResolvedModuleWithFailedLookupLocations) {
|
||||
checkResolvedModule(resolution.resolvedModule, createResolvedModule("/linked/index.d.ts", /*isExternalLibraryImport*/ true));
|
||||
assert.strictEqual(resolution.resolvedModule!.originalPath, "/app/node_modules/linked/index.d.ts");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("Module resolution - relative imports", () => {
|
||||
|
||||
@@ -745,15 +745,13 @@ export * from "lib";
|
||||
assert.equal(changes.length, 1);
|
||||
assert.equal(changes[0].fileName, testPath);
|
||||
|
||||
Harness.Baseline.runBaseline(baselinePath, () => {
|
||||
const newText = textChanges.applyChanges(testContent, changes[0].textChanges);
|
||||
return [
|
||||
"// ==ORIGINAL==",
|
||||
testContent,
|
||||
"// ==ORGANIZED==",
|
||||
newText,
|
||||
].join(newLineCharacter);
|
||||
});
|
||||
const newText = textChanges.applyChanges(testContent, changes[0].textChanges);
|
||||
Harness.Baseline.runBaseline(baselinePath, [
|
||||
"// ==ORIGINAL==",
|
||||
testContent,
|
||||
"// ==ORGANIZED==",
|
||||
newText,
|
||||
].join(newLineCharacter));
|
||||
}
|
||||
|
||||
function makeLanguageService(...files: TestFSWithWatch.File[]) {
|
||||
|
||||
@@ -3,7 +3,7 @@ namespace ts {
|
||||
function makePrintsCorrectly(prefix: string) {
|
||||
return function printsCorrectly(name: string, options: PrinterOptions, printCallback: (printer: Printer) => string) {
|
||||
it(name, () => {
|
||||
Harness.Baseline.runBaseline(`printerApi/${prefix}.${name}.js`, () =>
|
||||
Harness.Baseline.runBaseline(`printerApi/${prefix}.${name}.js`,
|
||||
printCallback(createPrinter({ newLine: NewLineKind.CarriageReturnLineFeed, ...options })));
|
||||
});
|
||||
};
|
||||
|
||||
@@ -10,7 +10,7 @@ describe("Public APIs", () => {
|
||||
});
|
||||
|
||||
it("should be acknowledged when they change", () => {
|
||||
Harness.Baseline.runBaseline(api, () => fileContent);
|
||||
Harness.Baseline.runBaseline(api, fileContent);
|
||||
});
|
||||
|
||||
it("should compile", () => {
|
||||
|
||||
@@ -68,6 +68,7 @@ namespace ts.projectSystem {
|
||||
}, "/hunter2/foo.csproj");
|
||||
|
||||
// Also test that opening an external project only sends an event once.
|
||||
et.service.closeClientFile(file1.path);
|
||||
|
||||
et.service.closeExternalProject(projectFileName);
|
||||
checkNumberOfProjects(et.service, { externalProjects: 0 });
|
||||
@@ -82,6 +83,7 @@ namespace ts.projectSystem {
|
||||
projectFileName,
|
||||
});
|
||||
checkNumberOfProjects(et.service, { externalProjects: 1 });
|
||||
et.service.openClientFile(file1.path); // Only on file open the project will be updated
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -47,17 +47,15 @@ namespace ts {
|
||||
|
||||
function runSingleFileTest(caption: string, placeOpenBraceOnNewLineForFunctions: boolean, text: string, validateNodes: boolean, testBlock: (sourceFile: SourceFile, changeTracker: textChanges.ChangeTracker) => void) {
|
||||
it(caption, () => {
|
||||
Harness.Baseline.runBaseline(`textChanges/${caption}.js`, () => {
|
||||
const sourceFile = createSourceFile("source.ts", text, ScriptTarget.ES2015, /*setParentNodes*/ true);
|
||||
const rulesProvider = getRuleProvider(placeOpenBraceOnNewLineForFunctions);
|
||||
const changeTracker = new textChanges.ChangeTracker(newLineCharacter, rulesProvider);
|
||||
testBlock(sourceFile, changeTracker);
|
||||
const changes = changeTracker.getChanges(validateNodes ? verifyPositions : undefined);
|
||||
assert.equal(changes.length, 1);
|
||||
assert.equal(changes[0].fileName, sourceFile.fileName);
|
||||
const modified = textChanges.applyChanges(sourceFile.text, changes[0].textChanges);
|
||||
return `===ORIGINAL===${newLineCharacter}${text}${newLineCharacter}===MODIFIED===${newLineCharacter}${modified}`;
|
||||
});
|
||||
const sourceFile = createSourceFile("source.ts", text, ScriptTarget.ES2015, /*setParentNodes*/ true);
|
||||
const rulesProvider = getRuleProvider(placeOpenBraceOnNewLineForFunctions);
|
||||
const changeTracker = new textChanges.ChangeTracker(newLineCharacter, rulesProvider);
|
||||
testBlock(sourceFile, changeTracker);
|
||||
const changes = changeTracker.getChanges(validateNodes ? verifyPositions : undefined);
|
||||
assert.equal(changes.length, 1);
|
||||
assert.equal(changes[0].fileName, sourceFile.fileName);
|
||||
const modified = textChanges.applyChanges(sourceFile.text, changes[0].textChanges);
|
||||
Harness.Baseline.runBaseline(`textChanges/${caption}.js`, `===ORIGINAL===${newLineCharacter}${text}${newLineCharacter}===MODIFIED===${newLineCharacter}${modified}`);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -13,9 +13,9 @@ namespace ts.textStorage {
|
||||
it("text based storage should be have exactly the same as script version cache", () => {
|
||||
|
||||
const host = projectSystem.createServerHost([f]);
|
||||
|
||||
const ts1 = new server.TextStorage(host, server.asNormalizedPath(f.path));
|
||||
const ts2 = new server.TextStorage(host, server.asNormalizedPath(f.path));
|
||||
// Since script info is not used in these tests, just cheat by passing undefined
|
||||
const ts1 = new server.TextStorage(host, server.asNormalizedPath(f.path), /*initialVersion*/ undefined, /*info*/undefined!);
|
||||
const ts2 = new server.TextStorage(host, server.asNormalizedPath(f.path), /*initialVersion*/ undefined, /*info*/undefined!);
|
||||
|
||||
ts1.useScriptVersionCache_TestOnly();
|
||||
ts2.useText();
|
||||
@@ -48,7 +48,8 @@ namespace ts.textStorage {
|
||||
|
||||
it("should switch to script version cache if necessary", () => {
|
||||
const host = projectSystem.createServerHost([f]);
|
||||
const ts1 = new server.TextStorage(host, server.asNormalizedPath(f.path));
|
||||
// Since script info is not used in these tests, just cheat by passing undefined
|
||||
const ts1 = new server.TextStorage(host, server.asNormalizedPath(f.path), /*initialVersion*/ undefined, /*info*/undefined!);
|
||||
|
||||
ts1.getSnapshot();
|
||||
assert.isTrue(!ts1.hasScriptVersionCache_TestOnly(), "should not have script version cache - 1");
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace ts {
|
||||
|
||||
function testBaseline(testName: string, test: () => string) {
|
||||
it(testName, () => {
|
||||
Harness.Baseline.runBaseline(`transformApi/transformsCorrectly.${testName}.js`, test);
|
||||
Harness.Baseline.runBaseline(`transformApi/transformsCorrectly.${testName}.js`, test());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -57,50 +57,26 @@ namespace ts {
|
||||
});
|
||||
|
||||
it("Correct errors for " + justName, () => {
|
||||
Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ".errors.txt"), () => {
|
||||
if (transpileResult.diagnostics!.length === 0) {
|
||||
/* tslint:disable:no-null-keyword */
|
||||
return null;
|
||||
/* tslint:enable:no-null-keyword */
|
||||
}
|
||||
|
||||
return Harness.Compiler.getErrorBaseline(toBeCompiled, transpileResult.diagnostics!);
|
||||
});
|
||||
Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ".errors.txt"),
|
||||
// tslint:disable-next-line no-null-keyword
|
||||
transpileResult.diagnostics!.length === 0 ? null : Harness.Compiler.getErrorBaseline(toBeCompiled, transpileResult.diagnostics!));
|
||||
});
|
||||
|
||||
if (canUseOldTranspile) {
|
||||
it("Correct errors (old transpile) for " + justName, () => {
|
||||
Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ".oldTranspile.errors.txt"), () => {
|
||||
if (oldTranspileDiagnostics.length === 0) {
|
||||
/* tslint:disable:no-null-keyword */
|
||||
return null;
|
||||
/* tslint:enable:no-null-keyword */
|
||||
}
|
||||
|
||||
return Harness.Compiler.getErrorBaseline(toBeCompiled, oldTranspileDiagnostics);
|
||||
});
|
||||
Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ".oldTranspile.errors.txt"),
|
||||
// tslint:disable-next-line no-null-keyword
|
||||
oldTranspileDiagnostics.length === 0 ? null : Harness.Compiler.getErrorBaseline(toBeCompiled, oldTranspileDiagnostics));
|
||||
});
|
||||
}
|
||||
|
||||
it("Correct output for " + justName, () => {
|
||||
Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, Extension.Js), () => {
|
||||
if (transpileResult.outputText) {
|
||||
return transpileResult.outputText;
|
||||
}
|
||||
else {
|
||||
// This can happen if compiler recieve invalid compiler-options
|
||||
/* tslint:disable:no-null-keyword */
|
||||
return null;
|
||||
/* tslint:enable:no-null-keyword */
|
||||
}
|
||||
});
|
||||
Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, Extension.Js), transpileResult.outputText);
|
||||
});
|
||||
|
||||
if (canUseOldTranspile) {
|
||||
it("Correct output (old transpile) for " + justName, () => {
|
||||
Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ".oldTranspile.js"), () => {
|
||||
return oldTranspileResult;
|
||||
});
|
||||
Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ".oldTranspile.js"), oldTranspileResult);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user