From 57f2fbde95cb814e4a073765f47a4ac02bb68786 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 7 Feb 2017 21:54:56 -0800 Subject: [PATCH 001/164] Make sure all options have descriptions --- src/compiler/commandLineParser.ts | 66 +++++++++++++++-------- src/compiler/diagnosticMessages.json | 81 ++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 22 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 4ee76d7b81..74640a318e 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -12,6 +12,7 @@ namespace ts { { name: "charset", type: "string", + description: Diagnostics.The_character_set_of_the_input_files }, compileOnSaveCommandLineOption, { @@ -25,19 +26,23 @@ namespace ts { type: "string", isFilePath: true, paramType: Diagnostics.DIRECTORY, + description: Diagnostics.Output_directory_for_generated_declaration_files }, { name: "diagnostics", type: "boolean", + description: Diagnostics.Show_diagnostic_information }, { name: "extendedDiagnostics", type: "boolean", - experimental: true + experimental: true, + description: Diagnostics.Show_extended_diagnostic_information }, { name: "emitBOM", - type: "boolean" + type: "boolean", + description:Diagnostics.Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files }, { name: "help", @@ -58,10 +63,12 @@ namespace ts { { name: "inlineSourceMap", type: "boolean", + description: Diagnostics.Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file }, { name: "inlineSources", type: "boolean", + description:Diagnostics.Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set }, { name: "jsx", @@ -86,17 +93,19 @@ namespace ts { { name: "listFiles", type: "boolean", + description: Diagnostics.Print_names_of_files_part_of_the_compilation }, { name: "locale", type: "string", + description: Diagnostics.The_locale_to_use_to_show_error_messages_e_g_en_us }, { name: "mapRoot", type: "string", isFilePath: true, - description: Diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations, paramType: Diagnostics.LOCATION, + description: Diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations, }, { name: "module", @@ -110,8 +119,8 @@ namespace ts { "es6": ModuleKind.ES2015, "es2015": ModuleKind.ES2015, }), - description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015, paramType: Diagnostics.KIND, + description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015, }, { name: "newLine", @@ -119,8 +128,8 @@ namespace ts { "crlf": NewLineKind.CarriageReturnLineFeed, "lf": NewLineKind.LineFeed }), - description: Diagnostics.Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix, paramType: Diagnostics.NEWLINE, + description: Diagnostics.Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix, }, { name: "noEmit", @@ -129,7 +138,8 @@ namespace ts { }, { name: "noEmitHelpers", - type: "boolean" + type: "boolean", + description: Diagnostics.Do_not_generate_custom_helper_functions_like_extends_in_compiled_output }, { name: "noEmitOnError", @@ -138,7 +148,8 @@ namespace ts { }, { name: "noErrorTruncation", - type: "boolean" + type: "boolean", + description: Diagnostics.Do_not_truncation_error_messages }, { name: "noImplicitAny", @@ -163,14 +174,17 @@ namespace ts { { name: "noLib", type: "boolean", + description: Diagnostics.Do_not_include_the_default_library_file_lib_d_ts }, { name: "noResolve", type: "boolean", + description:Diagnostics.Do_not_add_triple_slash_references_or_module_import_targets_to_the_list_of_compiled_files }, { name: "skipDefaultLibCheck", type: "boolean", + description: Diagnostics.Skip_type_checking_of_default_library_declaration_files }, { name: "skipLibCheck", @@ -183,20 +197,21 @@ namespace ts { isFilePath: false, // This is intentionally broken to support compatability with existing tsconfig files // for correct behaviour, please use outFile paramType: Diagnostics.FILE, + description: Diagnostics.Concatenate_and_emit_output_to_single_file, }, { name: "outFile", type: "string", isFilePath: true, - description: Diagnostics.Concatenate_and_emit_output_to_single_file, paramType: Diagnostics.FILE, + description: Diagnostics.Concatenate_and_emit_output_to_single_file, }, { name: "outDir", type: "string", isFilePath: true, - description: Diagnostics.Redirect_output_structure_to_the_directory, paramType: Diagnostics.DIRECTORY, + description: Diagnostics.Redirect_output_structure_to_the_directory, }, { name: "preserveConstEnums", @@ -205,16 +220,16 @@ namespace ts { }, { name: "pretty", - description: Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental, - type: "boolean" + type: "boolean", + description: Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental }, { name: "project", shortName: "p", type: "string", isFilePath: true, + paramType: Diagnostics.FILE_OR_DIRECTORY, description: Diagnostics.Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json, - paramType: Diagnostics.FILE_OR_DIRECTORY }, { name: "removeComments", @@ -231,6 +246,7 @@ namespace ts { { name: "isolatedModules", type: "boolean", + description: Diagnostics.Unconditionally_emit_imports_for_unresolved_files }, { name: "sourceMap", @@ -241,14 +257,14 @@ namespace ts { name: "sourceRoot", type: "string", isFilePath: true, - description: Diagnostics.Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations, paramType: Diagnostics.LOCATION, + description: Diagnostics.Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations, }, { name: "suppressExcessPropertyErrors", type: "boolean", + experimental: true, description: Diagnostics.Suppress_excess_property_checks_for_object_literals, - experimental: true }, { name: "suppressImplicitAnyIndexErrors", @@ -258,8 +274,8 @@ namespace ts { { name: "stripInternal", type: "boolean", + experimental: true, description: Diagnostics.Do_not_emit_declarations_for_code_that_has_an_internal_annotation, - experimental: true }, { name: "target", @@ -273,8 +289,8 @@ namespace ts { "es2017": ScriptTarget.ES2017, "esnext": ScriptTarget.ESNext, }), - description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT, paramType: Diagnostics.VERSION, + description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT, }, { name: "version", @@ -305,8 +321,8 @@ namespace ts { "node": ModuleResolutionKind.NodeJs, "classic": ModuleResolutionKind.Classic, }), - description: Diagnostics.Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6, paramType: Diagnostics.STRATEGY, + description: Diagnostics.Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6, }, { name: "allowUnusedLabels", @@ -344,7 +360,9 @@ namespace ts { // use type = object to copy the value as-is name: "paths", type: "object", - isTSConfigOnly: true + isTSConfigOnly: true, + description: Diagnostics.List_of_path_mapping_entries_for_module_names_to_locations_relative_to_the_baseUrl + }, { // this option can only be specified in tsconfig.json @@ -356,7 +374,8 @@ namespace ts { name: "rootDirs", type: "string", isFilePath: true - } + }, + description: Diagnostics.List_of_root_folders_whose_combined_content_represent_the_structure_of_the_project_at_runtime }, { name: "typeRoots", @@ -365,7 +384,8 @@ namespace ts { name: "typeRoots", type: "string", isFilePath: true - } + }, + description: Diagnostics.List_of_folders_to_include_type_definitions_from }, { name: "types", @@ -403,7 +423,8 @@ namespace ts { }, { name: "listEmittedFiles", - type: "boolean" + type: "boolean", + description: Diagnostics.Print_names_of_generated_files_part_of_the_compilation }, { name: "lib", @@ -443,7 +464,8 @@ namespace ts { }, { name: "disableSizeLimit", - type: "boolean" + type: "boolean", + description: Diagnostics.Disable_size_limitation_on_JavaScript_project }, { name: "strictNullChecks", diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 93953a3b90..cae9ad0a3a 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2997,6 +2997,87 @@ "category": "Message", "code": 6148 }, + "Show diagnostic information.": { + "category": "Message", + "code": 6149 + }, + "Show extended diagnostic information.": { + "category": "Message", + "code": 6150 + }, + "Emit a single file with source maps instead of having a separate file.": { + "category": "Message", + "code": 6151 + }, + "Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set.": { + "category": "Message", + "code": 6152 + }, + "Unconditionally emit imports for unresolved files.": { + "category": "Message", + "code": 6153 + }, + "Print names of generated files part of the compilation.": { + "category": "Message", + "code": 6154 + }, + "Print names of files part of the compilation.": { + "category": "Message", + "code": 6155 + }, + "The locale to use to show error messages, e.g. 'en-us'.": { + "category": "Message", + "code": 6156 + }, + "Do not generate custom helper functions like __extends in compiled output.": { + "category": "Message", + "code": 6157 + }, + "Do not include the default library file (lib.d.ts).": { + "category": "Message", + "code": 6158 + }, + "Do not add triple-slash references or module import targets to the list of compiled files.": { + "category": "Message", + "code": 6159 + }, + "Skip type checking of default library declaration files.": { + "category": "Message", + "code": 6160 + }, + "List of folders to include type definitions from.": { + "category": "Message", + "code": 6161 + }, + "Disable size limitation on JavaScript project.": { + "category": "Message", + "code": 6162 + }, + "The character set of the input files.": { + "category": "Message", + "code": 6163 + }, + "Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files.": { + "category": "Message", + "code": 6164 + }, + "Do not truncation error messages.": { + "category": "Message", + "code": 6165 + }, + "Output directory for generated declaration files.": { + "category": "Message", + "code": 6166 + }, + "List of path mapping entries for module names to locations relative to the 'baseUrl'.": { + "category": "Message", + "code": 6167 + }, + "List of root folders whose combined content represent the structure of the project at runtime.": { + "category": "Message", + "code": 6168 + }, + "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", "code": 7005 From 34597198720500ab600042ad227bb3ec052f3e71 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 7 Feb 2017 23:10:43 -0800 Subject: [PATCH 002/164] Manually order options --- src/compiler/commandLineParser.ts | 584 +++++++++++++++--------------- src/compiler/tsc.ts | 2 +- 2 files changed, 301 insertions(+), 285 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 74640a318e..26f6014987 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -9,41 +9,7 @@ namespace ts { export const compileOnSaveCommandLineOption: CommandLineOption = { name: "compileOnSave", type: "boolean" }; /* @internal */ export const optionDeclarations: CommandLineOption[] = [ - { - name: "charset", - type: "string", - description: Diagnostics.The_character_set_of_the_input_files - }, - compileOnSaveCommandLineOption, - { - name: "declaration", - shortName: "d", - type: "boolean", - description: Diagnostics.Generates_corresponding_d_ts_file, - }, - { - name: "declarationDir", - type: "string", - isFilePath: true, - paramType: Diagnostics.DIRECTORY, - description: Diagnostics.Output_directory_for_generated_declaration_files - }, - { - name: "diagnostics", - type: "boolean", - description: Diagnostics.Show_diagnostic_information - }, - { - name: "extendedDiagnostics", - type: "boolean", - experimental: true, - description: Diagnostics.Show_extended_diagnostic_information - }, - { - name: "emitBOM", - type: "boolean", - description:Diagnostics.Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files - }, + // Basic options { name: "help", shortName: "h", @@ -55,57 +21,39 @@ namespace ts { shortName: "?", type: "boolean" }, + { + name: "version", + shortName: "v", + type: "boolean", + description: Diagnostics.Print_the_compiler_s_version, + }, { name: "init", type: "boolean", description: Diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file, }, { - name: "inlineSourceMap", - type: "boolean", - description: Diagnostics.Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file - }, - { - name: "inlineSources", - type: "boolean", - description:Diagnostics.Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set - }, - { - name: "jsx", - type: createMapFromTemplate({ - "preserve": JsxEmit.Preserve, - "react-native": JsxEmit.ReactNative, - "react": JsxEmit.React - }), - paramType: Diagnostics.KIND, - description: Diagnostics.Specify_JSX_code_generation_Colon_preserve_react_native_or_react, - }, - { - name: "reactNamespace", - type: "string", - description: Diagnostics.Specify_the_object_invoked_for_createElement_and_spread_when_targeting_react_JSX_emit - }, - { - name: "jsxFactory", - type: "string", - description: Diagnostics.Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h - }, - { - name: "listFiles", - type: "boolean", - description: Diagnostics.Print_names_of_files_part_of_the_compilation - }, - { - name: "locale", - type: "string", - description: Diagnostics.The_locale_to_use_to_show_error_messages_e_g_en_us - }, - { - name: "mapRoot", + name: "project", + shortName: "p", type: "string", isFilePath: true, - paramType: Diagnostics.LOCATION, - description: Diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations, + paramType: Diagnostics.FILE_OR_DIRECTORY, + description: Diagnostics.Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json, + }, + { + name: "target", + shortName: "t", + type: createMapFromTemplate({ + "es3": ScriptTarget.ES3, + "es5": ScriptTarget.ES5, + "es6": ScriptTarget.ES2015, + "es2015": ScriptTarget.ES2015, + "es2016": ScriptTarget.ES2016, + "es2017": ScriptTarget.ES2017, + "esnext": ScriptTarget.ESNext, + }), + paramType: Diagnostics.VERSION, + description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT, }, { name: "module", @@ -123,73 +71,66 @@ namespace ts { description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015, }, { - name: "newLine", + name: "lib", + type: "list", + element: { + name: "lib", + type: createMapFromTemplate({ + // JavaScript only + "es5": "lib.es5.d.ts", + "es6": "lib.es2015.d.ts", + "es2015": "lib.es2015.d.ts", + "es7": "lib.es2016.d.ts", + "es2016": "lib.es2016.d.ts", + "es2017": "lib.es2017.d.ts", + // Host only + "dom": "lib.dom.d.ts", + "dom.iterable": "lib.dom.iterable.d.ts", + "webworker": "lib.webworker.d.ts", + "scripthost": "lib.scripthost.d.ts", + // ES2015 Or ESNext By-feature options + "es2015.core": "lib.es2015.core.d.ts", + "es2015.collection": "lib.es2015.collection.d.ts", + "es2015.generator": "lib.es2015.generator.d.ts", + "es2015.iterable": "lib.es2015.iterable.d.ts", + "es2015.promise": "lib.es2015.promise.d.ts", + "es2015.proxy": "lib.es2015.proxy.d.ts", + "es2015.reflect": "lib.es2015.reflect.d.ts", + "es2015.symbol": "lib.es2015.symbol.d.ts", + "es2015.symbol.wellknown": "lib.es2015.symbol.wellknown.d.ts", + "es2016.array.include": "lib.es2016.array.include.d.ts", + "es2017.object": "lib.es2017.object.d.ts", + "es2017.sharedmemory": "lib.es2017.sharedmemory.d.ts", + "es2017.string": "lib.es2017.string.d.ts", + }), + }, + description: Diagnostics.Specify_library_files_to_be_included_in_the_compilation_Colon + }, + { + name: "allowJs", + type: "boolean", + description: Diagnostics.Allow_javascript_files_to_be_compiled + }, + { + name: "jsx", type: createMapFromTemplate({ - "crlf": NewLineKind.CarriageReturnLineFeed, - "lf": NewLineKind.LineFeed + "preserve": JsxEmit.Preserve, + "react-native": JsxEmit.ReactNative, + "react": JsxEmit.React }), - paramType: Diagnostics.NEWLINE, - description: Diagnostics.Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix, + paramType: Diagnostics.KIND, + description: Diagnostics.Specify_JSX_code_generation_Colon_preserve_react_native_or_react, }, { - name: "noEmit", + name: "declaration", + shortName: "d", type: "boolean", - description: Diagnostics.Do_not_emit_outputs, + description: Diagnostics.Generates_corresponding_d_ts_file, }, { - name: "noEmitHelpers", + name: "sourceMap", type: "boolean", - description: Diagnostics.Do_not_generate_custom_helper_functions_like_extends_in_compiled_output - }, - { - name: "noEmitOnError", - type: "boolean", - description: Diagnostics.Do_not_emit_outputs_if_any_errors_were_reported, - }, - { - name: "noErrorTruncation", - type: "boolean", - description: Diagnostics.Do_not_truncation_error_messages - }, - { - name: "noImplicitAny", - type: "boolean", - description: Diagnostics.Raise_error_on_expressions_and_declarations_with_an_implied_any_type, - }, - { - name: "noImplicitThis", - type: "boolean", - description: Diagnostics.Raise_error_on_this_expressions_with_an_implied_any_type, - }, - { - name: "noUnusedLocals", - type: "boolean", - description: Diagnostics.Report_errors_on_unused_locals, - }, - { - name: "noUnusedParameters", - type: "boolean", - description: Diagnostics.Report_errors_on_unused_parameters, - }, - { - name: "noLib", - type: "boolean", - description: Diagnostics.Do_not_include_the_default_library_file_lib_d_ts - }, - { - name: "noResolve", - type: "boolean", - description:Diagnostics.Do_not_add_triple_slash_references_or_module_import_targets_to_the_list_of_compiled_files - }, - { - name: "skipDefaultLibCheck", - type: "boolean", - description: Diagnostics.Skip_type_checking_of_default_library_declaration_files - }, - { - name: "skipLibCheck", - type: "boolean", - description: Diagnostics.Skip_type_checking_of_declaration_files, + description: Diagnostics.Generates_corresponding_map_file, }, { name: "out", @@ -213,29 +154,6 @@ namespace ts { paramType: Diagnostics.DIRECTORY, description: Diagnostics.Redirect_output_structure_to_the_directory, }, - { - name: "preserveConstEnums", - type: "boolean", - description: Diagnostics.Do_not_erase_const_enum_declarations_in_generated_code - }, - { - name: "pretty", - type: "boolean", - description: Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental - }, - { - name: "project", - shortName: "p", - type: "string", - isFilePath: true, - paramType: Diagnostics.FILE_OR_DIRECTORY, - description: Diagnostics.Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json, - }, - { - name: "removeComments", - type: "boolean", - description: Diagnostics.Do_not_emit_comments_to_output, - }, { name: "rootDir", type: "string", @@ -243,22 +161,116 @@ namespace ts { paramType: Diagnostics.LOCATION, description: Diagnostics.Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir, }, + { + name: "declarationDir", + type: "string", + isFilePath: true, + paramType: Diagnostics.DIRECTORY, + description: Diagnostics.Output_directory_for_generated_declaration_files + }, + { + name: "removeComments", + type: "boolean", + description: Diagnostics.Do_not_emit_comments_to_output, + }, + { + name: "noEmit", + type: "boolean", + description: Diagnostics.Do_not_emit_outputs, + }, + { + name: "noEmitHelpers", + type: "boolean", + description: Diagnostics.Do_not_generate_custom_helper_functions_like_extends_in_compiled_output + }, + { + name: "noEmitOnError", + type: "boolean", + description: Diagnostics.Do_not_emit_outputs_if_any_errors_were_reported, + }, + { + name: "importHelpers", + type: "boolean", + description: Diagnostics.Import_emit_helpers_from_tslib + }, + { + name: "skipLibCheck", + type: "boolean", + description: Diagnostics.Skip_type_checking_of_declaration_files, + }, + { + name: "preserveConstEnums", + type: "boolean", + description: Diagnostics.Do_not_erase_const_enum_declarations_in_generated_code + }, { name: "isolatedModules", type: "boolean", description: Diagnostics.Unconditionally_emit_imports_for_unresolved_files }, { - name: "sourceMap", + name: "pretty", type: "boolean", - description: Diagnostics.Generates_corresponding_map_file, + description: Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental }, { - name: "sourceRoot", - type: "string", - isFilePath: true, - paramType: Diagnostics.LOCATION, - description: Diagnostics.Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations, + name: "watch", + shortName: "w", + type: "boolean", + description: Diagnostics.Watch_input_files, + }, + + // Strict Checks + { + name: "noImplicitAny", + type: "boolean", + description: Diagnostics.Raise_error_on_expressions_and_declarations_with_an_implied_any_type, + }, + { + name: "strictNullChecks", + type: "boolean", + description: Diagnostics.Enable_strict_null_checks + }, + { + name: "noImplicitThis", + type: "boolean", + description: Diagnostics.Raise_error_on_this_expressions_with_an_implied_any_type, + }, + { + name: "noUnusedLocals", + type: "boolean", + description: Diagnostics.Report_errors_on_unused_locals, + }, + { + name: "noUnusedParameters", + type: "boolean", + description: Diagnostics.Report_errors_on_unused_parameters, + }, + { + name: "alwaysStrict", + type: "boolean", + description: Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file + }, + { + name: "noImplicitReturns", + type: "boolean", + description: Diagnostics.Report_error_when_not_all_code_paths_in_function_return_a_value + }, + { + name: "noFallthroughCasesInSwitch", + type: "boolean", + description: Diagnostics.Report_errors_for_fallthrough_cases_in_switch_statement + }, + + { + name: "allowUnusedLabels", + type: "boolean", + description: Diagnostics.Do_not_report_errors_on_unused_labels + }, + { + name: "allowUnreachableCode", + type: "boolean", + description: Diagnostics.Do_not_report_errors_on_unreachable_code }, { name: "suppressExcessPropertyErrors", @@ -272,49 +284,50 @@ namespace ts { description: Diagnostics.Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures, }, { - name: "stripInternal", + name: "forceConsistentCasingInFileNames", type: "boolean", - experimental: true, - description: Diagnostics.Do_not_emit_declarations_for_code_that_has_an_internal_annotation, + description: Diagnostics.Disallow_inconsistently_cased_references_to_the_same_file + }, + + // Source Maps + { + name: "sourceRoot", + type: "string", + isFilePath: true, + paramType: Diagnostics.LOCATION, + description: Diagnostics.Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations, }, { - name: "target", - shortName: "t", - type: createMapFromTemplate({ - "es3": ScriptTarget.ES3, - "es5": ScriptTarget.ES5, - "es6": ScriptTarget.ES2015, - "es2015": ScriptTarget.ES2015, - "es2016": ScriptTarget.ES2016, - "es2017": ScriptTarget.ES2017, - "esnext": ScriptTarget.ESNext, - }), - paramType: Diagnostics.VERSION, - description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT, + name: "mapRoot", + type: "string", + isFilePath: true, + paramType: Diagnostics.LOCATION, + description: Diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations, }, { - name: "version", - shortName: "v", + name: "inlineSourceMap", type: "boolean", - description: Diagnostics.Print_the_compiler_s_version, + description: Diagnostics.Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file }, { - name: "watch", - shortName: "w", + name: "inlineSources", type: "boolean", - description: Diagnostics.Watch_input_files, + description:Diagnostics.Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set + }, + + // JSX + { + name: "reactNamespace", + type: "string", + description: Diagnostics.Specify_the_object_invoked_for_createElement_and_spread_when_targeting_react_JSX_emit }, { - name: "experimentalDecorators", - type: "boolean", - description: Diagnostics.Enables_experimental_support_for_ES7_decorators - }, - { - name: "emitDecoratorMetadata", - type: "boolean", - experimental: true, - description: Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators + name: "jsxFactory", + type: "string", + description: Diagnostics.Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h }, + + // Module Resolution { name: "moduleResolution", type: createMapFromTemplate({ @@ -324,31 +337,6 @@ namespace ts { paramType: Diagnostics.STRATEGY, description: Diagnostics.Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6, }, - { - name: "allowUnusedLabels", - type: "boolean", - description: Diagnostics.Do_not_report_errors_on_unused_labels - }, - { - name: "noImplicitReturns", - type: "boolean", - description: Diagnostics.Report_error_when_not_all_code_paths_in_function_return_a_value - }, - { - name: "noFallthroughCasesInSwitch", - type: "boolean", - description: Diagnostics.Report_errors_for_fallthrough_cases_in_switch_statement - }, - { - name: "allowUnreachableCode", - type: "boolean", - description: Diagnostics.Do_not_report_errors_on_unreachable_code - }, - { - name: "forceConsistentCasingInFileNames", - type: "boolean", - description: Diagnostics.Disallow_inconsistently_cased_references_to_the_same_file - }, { name: "baseUrl", type: "string", @@ -396,71 +384,109 @@ namespace ts { }, description: Diagnostics.Type_declaration_files_to_be_included_in_compilation }, - { - name: "traceResolution", - type: "boolean", - description: Diagnostics.Enable_tracing_of_the_name_resolution_process - }, - { - name: "allowJs", - type: "boolean", - description: Diagnostics.Allow_javascript_files_to_be_compiled - }, { name: "allowSyntheticDefaultImports", type: "boolean", description: Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking }, - { - name: "noImplicitUseStrict", - type: "boolean", - description: Diagnostics.Do_not_emit_use_strict_directives_in_module_output - }, { name: "maxNodeModuleJsDepth", type: "number", description: Diagnostics.The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files }, + + // Experimental + { + name: "experimentalDecorators", + type: "boolean", + description: Diagnostics.Enables_experimental_support_for_ES7_decorators + }, + { + name: "emitDecoratorMetadata", + type: "boolean", + experimental: true, + description: Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators + }, + + // Diagnostic + { + name: "diagnostics", + type: "boolean", + description: Diagnostics.Show_diagnostic_information + }, + { + name: "extendedDiagnostics", + type: "boolean", + experimental: true, + description: Diagnostics.Show_extended_diagnostic_information + }, + { + name: "traceResolution", + type: "boolean", + description: Diagnostics.Enable_tracing_of_the_name_resolution_process + }, + { + name: "listFiles", + type: "boolean", + description: Diagnostics.Print_names_of_files_part_of_the_compilation + }, { name: "listEmittedFiles", type: "boolean", description: Diagnostics.Print_names_of_generated_files_part_of_the_compilation }, + + // Other { - name: "lib", - type: "list", - element: { - name: "lib", - type: createMapFromTemplate({ - // JavaScript only - "es5": "lib.es5.d.ts", - "es6": "lib.es2015.d.ts", - "es2015": "lib.es2015.d.ts", - "es7": "lib.es2016.d.ts", - "es2016": "lib.es2016.d.ts", - "es2017": "lib.es2017.d.ts", - // Host only - "dom": "lib.dom.d.ts", - "dom.iterable": "lib.dom.iterable.d.ts", - "webworker": "lib.webworker.d.ts", - "scripthost": "lib.scripthost.d.ts", - // ES2015 Or ESNext By-feature options - "es2015.core": "lib.es2015.core.d.ts", - "es2015.collection": "lib.es2015.collection.d.ts", - "es2015.generator": "lib.es2015.generator.d.ts", - "es2015.iterable": "lib.es2015.iterable.d.ts", - "es2015.promise": "lib.es2015.promise.d.ts", - "es2015.proxy": "lib.es2015.proxy.d.ts", - "es2015.reflect": "lib.es2015.reflect.d.ts", - "es2015.symbol": "lib.es2015.symbol.d.ts", - "es2015.symbol.wellknown": "lib.es2015.symbol.wellknown.d.ts", - "es2016.array.include": "lib.es2016.array.include.d.ts", - "es2017.object": "lib.es2017.object.d.ts", - "es2017.sharedmemory": "lib.es2017.sharedmemory.d.ts", - "es2017.string": "lib.es2017.string.d.ts", - }), - }, - description: Diagnostics.Specify_library_files_to_be_included_in_the_compilation_Colon + name: "charset", + type: "string", + description: Diagnostics.The_character_set_of_the_input_files + }, + compileOnSaveCommandLineOption, + { + name: "emitBOM", + type: "boolean", + description:Diagnostics.Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files + }, + { + name: "locale", + type: "string", + description: Diagnostics.The_locale_to_use_to_show_error_messages_e_g_en_us + }, + { + name: "newLine", + type: createMapFromTemplate({ + "crlf": NewLineKind.CarriageReturnLineFeed, + "lf": NewLineKind.LineFeed + }), + paramType: Diagnostics.NEWLINE, + description: Diagnostics.Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix, + }, + { + name: "noErrorTruncation", + type: "boolean", + description: Diagnostics.Do_not_truncation_error_messages + }, + { + name: "noLib", + type: "boolean", + description: Diagnostics.Do_not_include_the_default_library_file_lib_d_ts + }, + { + name: "noResolve", + type: "boolean", + description:Diagnostics.Do_not_add_triple_slash_references_or_module_import_targets_to_the_list_of_compiled_files + }, + { + name: "skipDefaultLibCheck", + type: "boolean", + description: Diagnostics.Skip_type_checking_of_default_library_declaration_files + }, + { + name: "stripInternal", + type: "boolean", + experimental: true, + description: Diagnostics.Do_not_emit_declarations_for_code_that_has_an_internal_annotation, }, { name: "disableSizeLimit", @@ -468,20 +494,10 @@ namespace ts { description: Diagnostics.Disable_size_limitation_on_JavaScript_project }, { - name: "strictNullChecks", + name: "noImplicitUseStrict", type: "boolean", - description: Diagnostics.Enable_strict_null_checks + description: Diagnostics.Do_not_emit_use_strict_directives_in_module_output }, - { - name: "importHelpers", - type: "boolean", - description: Diagnostics.Import_emit_helpers_from_tslib - }, - { - name: "alwaysStrict", - type: "boolean", - description: Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file - } ]; /* @internal */ diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index b1ffcff43a..936a6d69c6 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -644,7 +644,7 @@ namespace ts { // Sort our options by their names, (e.g. "--noImplicitAny" comes before "--watch") const optsList = filter(optionDeclarations.slice(), v => !v.experimental); - optsList.sort((a, b) => compareValues(a.name.toLowerCase(), b.name.toLowerCase())); + //optsList.sort((a, b) => compareValues(a.name.toLowerCase(), b.name.toLowerCase())); // We want our descriptions to align at the same column in our output, // so we keep track of the longest option usage string. From 486757f51f557b9fcdb3dfa666f9f8252ea88964 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 8 Feb 2017 12:14:43 -0800 Subject: [PATCH 003/164] Add simplified help view and full help view --- src/compiler/commandLineParser.ts | 272 ++++++++++++++++++--------- src/compiler/diagnosticMessages.json | 4 + src/compiler/tsc.ts | 11 +- src/compiler/types.ts | 5 +- 4 files changed, 201 insertions(+), 91 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 26f6014987..c161aa55bb 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -9,11 +9,13 @@ namespace ts { export const compileOnSaveCommandLineOption: CommandLineOption = { name: "compileOnSave", type: "boolean" }; /* @internal */ export const optionDeclarations: CommandLineOption[] = [ - // Basic options + // CommandLine only options { name: "help", shortName: "h", type: "boolean", + showInSimplifiedHelpView: true, + category: "CommandLine", description: Diagnostics.Print_this_message, }, { @@ -21,15 +23,26 @@ namespace ts { shortName: "?", type: "boolean" }, + { + name: "all", + type: "boolean", + showInSimplifiedHelpView: true, + category: "CommandLine", + description: Diagnostics.Show_all_compiler_options, + }, { name: "version", shortName: "v", type: "boolean", + showInSimplifiedHelpView: true, + category: "CommandLine", description: Diagnostics.Print_the_compiler_s_version, }, { name: "init", type: "boolean", + showInSimplifiedHelpView: true, + category: "CommandLine", description: Diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file, }, { @@ -37,9 +50,28 @@ namespace ts { shortName: "p", type: "string", isFilePath: true, + showInSimplifiedHelpView: true, + category: "CommandLine", paramType: Diagnostics.FILE_OR_DIRECTORY, description: Diagnostics.Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json, }, + { + name: "pretty", + type: "boolean", + showInSimplifiedHelpView: true, + category: "CommandLine", + description: Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental + }, + { + name: "watch", + shortName: "w", + type: "boolean", + showInSimplifiedHelpView: true, + category: "CommandLine", + description: Diagnostics.Watch_input_files, + }, + + // Basic { name: "target", shortName: "t", @@ -53,6 +85,8 @@ namespace ts { "esnext": ScriptTarget.ESNext, }), paramType: Diagnostics.VERSION, + showInSimplifiedHelpView: true, + category: "Basic", description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT, }, { @@ -68,6 +102,8 @@ namespace ts { "es2015": ModuleKind.ES2015, }), paramType: Diagnostics.KIND, + showInSimplifiedHelpView: true, + category: "Basic", description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015, }, { @@ -104,11 +140,15 @@ namespace ts { "es2017.string": "lib.es2017.string.d.ts", }), }, + showInSimplifiedHelpView: true, + category: "Basic", description: Diagnostics.Specify_library_files_to_be_included_in_the_compilation_Colon }, { name: "allowJs", type: "boolean", + showInSimplifiedHelpView: true, + category: "Basic", description: Diagnostics.Allow_javascript_files_to_be_compiled }, { @@ -119,32 +159,32 @@ namespace ts { "react": JsxEmit.React }), paramType: Diagnostics.KIND, + showInSimplifiedHelpView: true, + category: "Basic", description: Diagnostics.Specify_JSX_code_generation_Colon_preserve_react_native_or_react, }, { name: "declaration", shortName: "d", type: "boolean", + showInSimplifiedHelpView: true, + category: "Basic", description: Diagnostics.Generates_corresponding_d_ts_file, }, { name: "sourceMap", type: "boolean", + showInSimplifiedHelpView: true, + category: "Basic", description: Diagnostics.Generates_corresponding_map_file, }, - { - name: "out", - type: "string", - isFilePath: false, // This is intentionally broken to support compatability with existing tsconfig files - // for correct behaviour, please use outFile - paramType: Diagnostics.FILE, - description: Diagnostics.Concatenate_and_emit_output_to_single_file, - }, { name: "outFile", type: "string", isFilePath: true, paramType: Diagnostics.FILE, + showInSimplifiedHelpView: true, + category: "Basic", description: Diagnostics.Concatenate_and_emit_output_to_single_file, }, { @@ -152,6 +192,8 @@ namespace ts { type: "string", isFilePath: true, paramType: Diagnostics.DIRECTORY, + showInSimplifiedHelpView: true, + category: "Basic", description: Diagnostics.Redirect_output_structure_to_the_directory, }, { @@ -159,6 +201,7 @@ namespace ts { type: "string", isFilePath: true, paramType: Diagnostics.LOCATION, + category: "Basic", description: Diagnostics.Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir, }, { @@ -166,167 +209,130 @@ namespace ts { type: "string", isFilePath: true, paramType: Diagnostics.DIRECTORY, + category: "Basic", description: Diagnostics.Output_directory_for_generated_declaration_files }, { name: "removeComments", type: "boolean", + showInSimplifiedHelpView: true, + category: "Basic", description: Diagnostics.Do_not_emit_comments_to_output, }, { name: "noEmit", type: "boolean", + showInSimplifiedHelpView: true, + category: "Basic", description: Diagnostics.Do_not_emit_outputs, }, - { - name: "noEmitHelpers", - type: "boolean", - description: Diagnostics.Do_not_generate_custom_helper_functions_like_extends_in_compiled_output - }, - { - name: "noEmitOnError", - type: "boolean", - description: Diagnostics.Do_not_emit_outputs_if_any_errors_were_reported, - }, { name: "importHelpers", type: "boolean", + category: "Basic", description: Diagnostics.Import_emit_helpers_from_tslib }, { name: "skipLibCheck", type: "boolean", + category: "Basic", description: Diagnostics.Skip_type_checking_of_declaration_files, }, - { - name: "preserveConstEnums", - type: "boolean", - description: Diagnostics.Do_not_erase_const_enum_declarations_in_generated_code - }, { name: "isolatedModules", type: "boolean", + category: "Basic", description: Diagnostics.Unconditionally_emit_imports_for_unresolved_files }, - { - name: "pretty", - type: "boolean", - description: Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental - }, - { - name: "watch", - shortName: "w", - type: "boolean", - description: Diagnostics.Watch_input_files, - }, // Strict Checks { name: "noImplicitAny", type: "boolean", + showInSimplifiedHelpView: true, + category: "StrictChecks", description: Diagnostics.Raise_error_on_expressions_and_declarations_with_an_implied_any_type, }, { name: "strictNullChecks", type: "boolean", + showInSimplifiedHelpView: true, + category: "StrictChecks", description: Diagnostics.Enable_strict_null_checks }, { name: "noImplicitThis", type: "boolean", + showInSimplifiedHelpView: true, + category: "StrictChecks", description: Diagnostics.Raise_error_on_this_expressions_with_an_implied_any_type, }, { name: "noUnusedLocals", type: "boolean", + showInSimplifiedHelpView: true, + category: "StrictChecks", description: Diagnostics.Report_errors_on_unused_locals, }, { name: "noUnusedParameters", type: "boolean", + showInSimplifiedHelpView: true, + category: "StrictChecks", description: Diagnostics.Report_errors_on_unused_parameters, }, { name: "alwaysStrict", type: "boolean", + showInSimplifiedHelpView: true, + category: "StrictChecks", description: Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file }, { name: "noImplicitReturns", type: "boolean", + showInSimplifiedHelpView: true, + category: "StrictChecks", description: Diagnostics.Report_error_when_not_all_code_paths_in_function_return_a_value }, { name: "noFallthroughCasesInSwitch", type: "boolean", + showInSimplifiedHelpView: true, + category: "StrictChecks", description: Diagnostics.Report_errors_for_fallthrough_cases_in_switch_statement }, - { name: "allowUnusedLabels", type: "boolean", + category: "StrictChecks", description: Diagnostics.Do_not_report_errors_on_unused_labels }, { name: "allowUnreachableCode", type: "boolean", + category: "StrictChecks", description: Diagnostics.Do_not_report_errors_on_unreachable_code }, { name: "suppressExcessPropertyErrors", type: "boolean", - experimental: true, + category: "StrictChecks", description: Diagnostics.Suppress_excess_property_checks_for_object_literals, }, { name: "suppressImplicitAnyIndexErrors", type: "boolean", + category: "StrictChecks", description: Diagnostics.Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures, }, { name: "forceConsistentCasingInFileNames", type: "boolean", + category: "StrictChecks", description: Diagnostics.Disallow_inconsistently_cased_references_to_the_same_file }, - // Source Maps - { - name: "sourceRoot", - type: "string", - isFilePath: true, - paramType: Diagnostics.LOCATION, - description: Diagnostics.Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations, - }, - { - name: "mapRoot", - type: "string", - isFilePath: true, - paramType: Diagnostics.LOCATION, - description: Diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations, - }, - { - name: "inlineSourceMap", - type: "boolean", - description: Diagnostics.Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file - }, - { - name: "inlineSources", - type: "boolean", - description:Diagnostics.Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set - }, - - // JSX - { - name: "reactNamespace", - type: "string", - description: Diagnostics.Specify_the_object_invoked_for_createElement_and_spread_when_targeting_react_JSX_emit - }, - { - name: "jsxFactory", - type: "string", - description: Diagnostics.Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h - }, - // Module Resolution { name: "moduleResolution", @@ -335,12 +341,14 @@ namespace ts { "classic": ModuleResolutionKind.Classic, }), paramType: Diagnostics.STRATEGY, + category: "ModuleResolution", description: Diagnostics.Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6, }, { name: "baseUrl", type: "string", isFilePath: true, + category: "ModuleResolution", description: Diagnostics.Base_directory_to_resolve_non_absolute_module_names }, { @@ -349,6 +357,7 @@ namespace ts { name: "paths", type: "object", isTSConfigOnly: true, + category: "ModuleResolution", description: Diagnostics.List_of_path_mapping_entries_for_module_names_to_locations_relative_to_the_baseUrl }, @@ -363,6 +372,7 @@ namespace ts { type: "string", isFilePath: true }, + category: "ModuleResolution", description: Diagnostics.List_of_root_folders_whose_combined_content_represent_the_structure_of_the_project_at_runtime }, { @@ -373,6 +383,7 @@ namespace ts { type: "string", isFilePath: true }, + category: "ModuleResolution", description: Diagnostics.List_of_folders_to_include_type_definitions_from }, { @@ -382,75 +393,146 @@ namespace ts { name: "types", type: "string" }, + showInSimplifiedHelpView: true, + category: "ModuleResolution", description: Diagnostics.Type_declaration_files_to_be_included_in_compilation }, { name: "allowSyntheticDefaultImports", type: "boolean", + category: "ModuleResolution", description: Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking }, { name: "maxNodeModuleJsDepth", type: "number", + category: "ModuleResolution", description: Diagnostics.The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files }, + // Source Maps + { + name: "sourceRoot", + type: "string", + isFilePath: true, + paramType: Diagnostics.LOCATION, + category: "SourceMaps", + description: Diagnostics.Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations, + }, + { + name: "mapRoot", + type: "string", + isFilePath: true, + paramType: Diagnostics.LOCATION, + category: "SourceMaps", + description: Diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations, + }, + { + name: "inlineSourceMap", + type: "boolean", + category: "SourceMaps", + description: Diagnostics.Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file + }, + { + name: "inlineSources", + type: "boolean", + category: "SourceMaps", + description:Diagnostics.Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set + }, + + // JSX + { + name: "jsxFactory", + type: "string", + category: "JSX", + description: Diagnostics.Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h + }, + // Experimental { name: "experimentalDecorators", type: "boolean", + category: "Experimental", description: Diagnostics.Enables_experimental_support_for_ES7_decorators }, { name: "emitDecoratorMetadata", type: "boolean", - experimental: true, + category: "Experimental", description: Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators }, - // Diagnostic + // Advanced { name: "diagnostics", type: "boolean", + category: "Advanced", description: Diagnostics.Show_diagnostic_information }, { name: "extendedDiagnostics", type: "boolean", - experimental: true, + category: "Advanced", description: Diagnostics.Show_extended_diagnostic_information }, { name: "traceResolution", type: "boolean", + category: "Advanced", description: Diagnostics.Enable_tracing_of_the_name_resolution_process }, { name: "listFiles", type: "boolean", + category: "Advanced", description: Diagnostics.Print_names_of_files_part_of_the_compilation }, { name: "listEmittedFiles", type: "boolean", + category: "Advanced", description: Diagnostics.Print_names_of_generated_files_part_of_the_compilation }, - // Other + { + name: "out", + type: "string", + isFilePath: false, // This is intentionally broken to support compatability with existing tsconfig files + // for correct behaviour, please use outFile + category: "Advanced", + paramType: Diagnostics.FILE, + description: Diagnostics.Concatenate_and_emit_output_to_single_file, + }, + { + name: "reactNamespace", + type: "string", + category: "Advanced", + description: Diagnostics.Specify_the_object_invoked_for_createElement_and_spread_when_targeting_react_JSX_emit + }, + { + name: "skipDefaultLibCheck", + type: "boolean", + category: "Advanced", + description: Diagnostics.Skip_type_checking_of_default_library_declaration_files + }, + { name: "charset", type: "string", + category: "Advanced", description: Diagnostics.The_character_set_of_the_input_files }, compileOnSaveCommandLineOption, { name: "emitBOM", type: "boolean", + category: "Advanced", description:Diagnostics.Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files }, { name: "locale", type: "string", + category: "Advanced", description: Diagnostics.The_locale_to_use_to_show_error_messages_e_g_en_us }, { @@ -460,44 +542,63 @@ namespace ts { "lf": NewLineKind.LineFeed }), paramType: Diagnostics.NEWLINE, + category: "Advanced", description: Diagnostics.Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix, }, { name: "noErrorTruncation", type: "boolean", + category: "Advanced", description: Diagnostics.Do_not_truncation_error_messages }, { name: "noLib", type: "boolean", + category: "Advanced", description: Diagnostics.Do_not_include_the_default_library_file_lib_d_ts }, { name: "noResolve", type: "boolean", + category: "Advanced", description:Diagnostics.Do_not_add_triple_slash_references_or_module_import_targets_to_the_list_of_compiled_files }, - { - name: "skipDefaultLibCheck", - type: "boolean", - description: Diagnostics.Skip_type_checking_of_default_library_declaration_files - }, { name: "stripInternal", type: "boolean", - experimental: true, + category: "Advanced", description: Diagnostics.Do_not_emit_declarations_for_code_that_has_an_internal_annotation, }, { name: "disableSizeLimit", type: "boolean", + category: "Advanced", description: Diagnostics.Disable_size_limitation_on_JavaScript_project }, { name: "noImplicitUseStrict", type: "boolean", + category: "Advanced", description: Diagnostics.Do_not_emit_use_strict_directives_in_module_output }, + { + name: "noEmitHelpers", + type: "boolean", + category: "Advanced", + description: Diagnostics.Do_not_generate_custom_helper_functions_like_extends_in_compiled_output + }, + { + name: "noEmitOnError", + type: "boolean", + category: "Advanced", + description: Diagnostics.Do_not_emit_outputs_if_any_errors_were_reported, + }, + { + name: "preserveConstEnums", + type: "boolean", + category: "Advanced", + description: Diagnostics.Do_not_erase_const_enum_declarations_in_generated_code + }, ]; /* @internal */ @@ -813,6 +914,7 @@ namespace ts { case "version": case "help": case "project": + case "all": break; default: const value = options[name]; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index cae9ad0a3a..166417118c 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3077,6 +3077,10 @@ "category": "Message", "code": 6168 }, + "Show all compiler options.": { + "category": "Message", + "code": 6169 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 936a6d69c6..474e5af8e1 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -227,7 +227,7 @@ namespace ts { if (commandLine.options.help) { printVersion(); - printHelp(); + printHelp(commandLine.options.all); return sys.exit(ExitStatus.Success); } @@ -264,7 +264,7 @@ namespace ts { if (commandLine.fileNames.length === 0 && !configFileName) { printVersion(); - printHelp(); + printHelp(commandLine.options.all); return sys.exit(ExitStatus.Success); } @@ -618,7 +618,7 @@ namespace ts { sys.write(getDiagnosticText(Diagnostics.Version_0, ts.version) + sys.newLine); } - function printHelp() { + function printHelp(showAllOptions: boolean) { const output: string[] = []; // We want to align our "syntax" and "examples" commands to a certain margin. @@ -643,8 +643,9 @@ namespace ts { output.push(getDiagnosticText(Diagnostics.Options_Colon) + sys.newLine); // Sort our options by their names, (e.g. "--noImplicitAny" comes before "--watch") - const optsList = filter(optionDeclarations.slice(), v => !v.experimental); - //optsList.sort((a, b) => compareValues(a.name.toLowerCase(), b.name.toLowerCase())); + const optsList = showAllOptions ? + optionDeclarations.slice().sort((a, b) => compareValues(a.name.toLowerCase(), b.name.toLowerCase())) : + filter(optionDeclarations.slice(), v => v.showInSimplifiedHelpView); // We want our descriptions to align at the same column in our output, // so we keep track of the longest option usage string. diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 49e744682b..69c8d7a5c9 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3194,6 +3194,7 @@ export type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike; export interface CompilerOptions { + /*@internal*/ all?: boolean; allowJs?: boolean; /*@internal*/ allowNonTsExtensions?: boolean; allowSyntheticDefaultImports?: boolean; @@ -3382,8 +3383,10 @@ shortName?: string; // A short mnemonic for convenience - for instance, 'h' can be used in place of 'help' description?: DiagnosticMessage; // The message describing what the command line switch does paramType?: DiagnosticMessage; // The name to be used for a non-boolean option's parameter - experimental?: boolean; isTSConfigOnly?: boolean; // True if option can only be specified via tsconfig.json file + isCommandLineOnly?: boolean; + showInSimplifiedHelpView?:boolean; + category?: "CommandLine" | "Basic" | "StrictChecks" | "ModuleResolution" | "JSX" | "SourceMaps" | "Experimental" | "Advanced"; } /* @internal */ From 6837125657f9f04321aa39767276b257d5639f2e Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 8 Feb 2017 12:25:38 -0800 Subject: [PATCH 004/164] Add deprecation notice for some options --- src/compiler/commandLineParser.ts | 6 +++--- src/compiler/diagnosticMessages.json | 8 ++++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index c161aa55bb..3b5b7cbba2 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -501,19 +501,19 @@ namespace ts { // for correct behaviour, please use outFile category: "Advanced", paramType: Diagnostics.FILE, - description: Diagnostics.Concatenate_and_emit_output_to_single_file, + description: Diagnostics.Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file, }, { name: "reactNamespace", type: "string", category: "Advanced", - description: Diagnostics.Specify_the_object_invoked_for_createElement_and_spread_when_targeting_react_JSX_emit + description: Diagnostics.Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react_JSX_emit }, { name: "skipDefaultLibCheck", type: "boolean", category: "Advanced", - description: Diagnostics.Skip_type_checking_of_default_library_declaration_files + description: Diagnostics.Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files }, { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 166417118c..b487b47b10 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2737,7 +2737,7 @@ "category": "Message", "code": 6083 }, - "Specify the object invoked for createElement and __spread when targeting 'react' JSX emit": { + "[Deprecated] Use '--jsxFactory' instead. Specify the object invoked for createElement when targeting 'react' JSX emit": { "category": "Message", "code": 6084 }, @@ -3041,7 +3041,7 @@ "category": "Message", "code": 6159 }, - "Skip type checking of default library declaration files.": { + "[Deprecated] Use '--skipLibCheck' instead. Skip type checking of default library declaration files.": { "category": "Message", "code": 6160 }, @@ -3081,6 +3081,10 @@ "category": "Message", "code": 6169 }, + "[Deprecated] Use '--outFile' instead. Concatenate and emit output to single file": { + "category": "Message", + "code": 6170 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", From f53eeae4d8332b6aa800d867287c46011bb979de Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 8 Feb 2017 12:35:31 -0800 Subject: [PATCH 005/164] use category in serializeCompilerOptions --- src/compiler/commandLineParser.ts | 54 +++++++++++++------------------ 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 3b5b7cbba2..d3940b6342 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -908,39 +908,31 @@ namespace ts { if (hasProperty(options, name)) { // tsconfig only options cannot be specified via command line, // so we can assume that only types that can appear here string | number | boolean - switch (name) { - case "init": - case "watch": - case "version": - case "help": - case "project": - case "all": - break; - default: - const value = options[name]; - const optionDefinition = optionsNameMap.get(name.toLowerCase()); - if (optionDefinition) { - const customTypeMap = getCustomTypeMapOfCommandLineOption(optionDefinition); - if (!customTypeMap) { - // There is no map associated with this compiler option then use the value as-is - // This is the case if the value is expect to be string, number, boolean or list of string - result[name] = value; - } - else { - if (optionDefinition.type === "list") { - const convertedValue: string[] = []; - for (const element of value as (string | number)[]) { - convertedValue.push(getNameOfCompilerOptionValue(element, customTypeMap)); - } - result[name] = convertedValue; - } - else { - // There is a typeMap associated with this command-line option so use it to map value back to its name - result[name] = getNameOfCompilerOptionValue(value, customTypeMap); - } + if (optionsNameMap.has(name) && optionsNameMap.get(name).category === "CommandLine") { + continue; + } + const value = options[name]; + const optionDefinition = optionsNameMap.get(name.toLowerCase()); + if (optionDefinition) { + const customTypeMap = getCustomTypeMapOfCommandLineOption(optionDefinition); + if (!customTypeMap) { + // There is no map associated with this compiler option then use the value as-is + // This is the case if the value is expect to be string, number, boolean or list of string + result[name] = value; + } + else { + if (optionDefinition.type === "list") { + const convertedValue: string[] = []; + for (const element of value as (string | number)[]) { + convertedValue.push(getNameOfCompilerOptionValue(element, customTypeMap)); } + result[name] = convertedValue; } - break; + else { + // There is a typeMap associated with this command-line option so use it to map value back to its name + result[name] = getNameOfCompilerOptionValue(value, customTypeMap); + } + } } } } From 0bc2840af4695dcd96e1d50d08672d36b21e6165 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 8 Feb 2017 12:41:40 -0800 Subject: [PATCH 006/164] Make generateTSConfig return a string --- src/compiler/commandLineParser.ts | 4 ++-- src/compiler/tsc.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index d3940b6342..d8a6f402a1 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -866,7 +866,7 @@ namespace ts { * @param fileNames array of filenames to be generated into tsconfig.json */ /* @internal */ - export function generateTSConfig(options: CompilerOptions, fileNames: string[]): { compilerOptions: MapLike } { + export function generateTSConfig(options: CompilerOptions, fileNames: string[]): string { const compilerOptions = extend(options, defaultInitCompilerOptions); const configurations: any = { compilerOptions: serializeCompilerOptions(compilerOptions) @@ -876,7 +876,7 @@ namespace ts { configurations.files = fileNames; } - return configurations; + return JSON.stringify(configurations, undefined, 4); function getCustomTypeMapOfCommandLineOption(optionDefinition: CommandLineOption): Map | undefined { if (optionDefinition.type === "string" || optionDefinition.type === "number" || optionDefinition.type === "boolean") { diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 474e5af8e1..3800ed91aa 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -739,7 +739,7 @@ namespace ts { reportDiagnostic(createCompilerDiagnostic(Diagnostics.A_tsconfig_json_file_is_already_defined_at_Colon_0, file), /* host */ undefined); } else { - sys.writeFile(file, JSON.stringify(generateTSConfig(options, fileNames), undefined, 4)); + sys.writeFile(file, generateTSConfig(options, fileNames)); reportDiagnostic(createCompilerDiagnostic(Diagnostics.Successfully_created_a_tsconfig_json_file), /* host */ undefined); } From 9fc4f6e1b9175f2649f4b14f46285ab889764285 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 8 Feb 2017 19:07:15 -0800 Subject: [PATCH 007/164] Write comments for compiler options in `tsc --init` output --- src/compiler/commandLineParser.ts | 71 ++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index d8a6f402a1..1a388c9e96 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -868,7 +868,7 @@ namespace ts { /* @internal */ export function generateTSConfig(options: CompilerOptions, fileNames: string[]): string { const compilerOptions = extend(options, defaultInitCompilerOptions); - const configurations: any = { + const configurations: { compilerOptions: MapLike; files?: string[] } = { compilerOptions: serializeCompilerOptions(compilerOptions) }; if (fileNames && fileNames.length) { @@ -876,7 +876,8 @@ namespace ts { configurations.files = fileNames; } - return JSON.stringify(configurations, undefined, 4); + + return writeConfigurations(); function getCustomTypeMapOfCommandLineOption(optionDefinition: CommandLineOption): Map | undefined { if (optionDefinition.type === "string" || optionDefinition.type === "number" || optionDefinition.type === "boolean") { @@ -938,6 +939,72 @@ namespace ts { } return result; } + + function getDefaultValueForOption(option: CommandLineOption) { + switch (option.type) { + case "number": + return 1; + case "boolean": + return true; + case "string": + return option.isFilePath ? "./" : ""; + case "list": + return []; + case "object": + return {}; + default: + return arrayFrom((option).type.keys())[0]; + } + } + + function writeConfigurations() { + const categorizedOptions = reduceLeft( + filter(optionDeclarations, o => o.category !== "CommandLine" && o.category !== "Advanced"), + (memo, value) => { + if (value.category) { + (memo[value.category] || (memo[value.category] = [])).push(value); + } + return memo; + }, >{}); + const knownKesyCount = getOwnKeys(configurations.compilerOptions).length; + + const newLine = "\n"; + const tab = " "; + + let result = ""; + let seenKnownKeys = 0; + result += `{${newLine}`; + result += `${tab}"compilerOptions": {${newLine}`; + for (const category in categorizedOptions) { + result += `${tab}${tab}// ${category}${newLine}`; + result += `${newLine}`; + for (const option of categorizedOptions[category]) { + result += `${tab}${tab}// ${option.description && option.description.message || option.name}${newLine}`; + if (option.name in configurations.compilerOptions) { + result += `${tab}${tab}"${option.name}": ${JSON.stringify(configurations.compilerOptions[option.name])}${++seenKnownKeys === knownKesyCount ? "" : ","}${newLine}`; + } + else { + result += `${tab}${tab}// "${option.name}": ${JSON.stringify(getDefaultValueForOption(option))},${newLine}`; + } + result += `${newLine}`; + } + result += `${newLine}`; + } + if (configurations.files && configurations.files.length) { + result += `${tab}},${newLine}`; + result += `${tab}"files": [${newLine}`; + for (let i = 0; i < configurations.files.length; i++) { + result += `${tab}${tab}${JSON.stringify(configurations.files[i])}${i === configurations.files.length - 1 ? "" : ","}${newLine}`; + } + result += `${tab}]${newLine}`; + } + else { + result += `${tab}}${newLine}`; + } + result += `}${newLine}`; + + return result; + } } /** From 1c0ca7ce1d9f8a147e1ff00c63ed15475437fa98 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 8 Feb 2017 19:09:22 -0800 Subject: [PATCH 008/164] Remove properties from tsconfig.json that defaults to false --- src/compiler/commandLineParser.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 1a388c9e96..adbb879d5e 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -641,9 +641,7 @@ namespace ts { /* @internal */ export const defaultInitCompilerOptions: CompilerOptions = { module: ModuleKind.CommonJS, - target: ScriptTarget.ES5, - noImplicitAny: false, - sourceMap: false, + target: ScriptTarget.ES5 }; let optionNameMapCache: OptionNameMap; From c97673c55cf12b880d6177a143aa2b4dc112fded Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 8 Feb 2017 19:25:08 -0800 Subject: [PATCH 009/164] Make categories localizable --- src/compiler/commandLineParser.ts | 153 ++++++++++++++------------- src/compiler/diagnosticMessages.json | 33 ++++++ src/compiler/types.ts | 2 +- 3 files changed, 111 insertions(+), 77 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index adbb879d5e..46327668f2 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -15,7 +15,7 @@ namespace ts { shortName: "h", type: "boolean", showInSimplifiedHelpView: true, - category: "CommandLine", + category: Diagnostics.CommandLine_Options, description: Diagnostics.Print_this_message, }, { @@ -27,7 +27,7 @@ namespace ts { name: "all", type: "boolean", showInSimplifiedHelpView: true, - category: "CommandLine", + category: Diagnostics.CommandLine_Options, description: Diagnostics.Show_all_compiler_options, }, { @@ -35,14 +35,14 @@ namespace ts { shortName: "v", type: "boolean", showInSimplifiedHelpView: true, - category: "CommandLine", + category: Diagnostics.CommandLine_Options, description: Diagnostics.Print_the_compiler_s_version, }, { name: "init", type: "boolean", showInSimplifiedHelpView: true, - category: "CommandLine", + category: Diagnostics.CommandLine_Options, description: Diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file, }, { @@ -51,7 +51,7 @@ namespace ts { type: "string", isFilePath: true, showInSimplifiedHelpView: true, - category: "CommandLine", + category: Diagnostics.CommandLine_Options, paramType: Diagnostics.FILE_OR_DIRECTORY, description: Diagnostics.Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json, }, @@ -59,7 +59,7 @@ namespace ts { name: "pretty", type: "boolean", showInSimplifiedHelpView: true, - category: "CommandLine", + category: Diagnostics.CommandLine_Options, description: Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental }, { @@ -67,7 +67,7 @@ namespace ts { shortName: "w", type: "boolean", showInSimplifiedHelpView: true, - category: "CommandLine", + category: Diagnostics.CommandLine_Options, description: Diagnostics.Watch_input_files, }, @@ -86,7 +86,7 @@ namespace ts { }), paramType: Diagnostics.VERSION, showInSimplifiedHelpView: true, - category: "Basic", + category: Diagnostics.Basic_Options, description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT, }, { @@ -103,7 +103,7 @@ namespace ts { }), paramType: Diagnostics.KIND, showInSimplifiedHelpView: true, - category: "Basic", + category: Diagnostics.Basic_Options, description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015, }, { @@ -141,14 +141,14 @@ namespace ts { }), }, showInSimplifiedHelpView: true, - category: "Basic", + category: Diagnostics.Basic_Options, description: Diagnostics.Specify_library_files_to_be_included_in_the_compilation_Colon }, { name: "allowJs", type: "boolean", showInSimplifiedHelpView: true, - category: "Basic", + category: Diagnostics.Basic_Options, description: Diagnostics.Allow_javascript_files_to_be_compiled }, { @@ -160,7 +160,7 @@ namespace ts { }), paramType: Diagnostics.KIND, showInSimplifiedHelpView: true, - category: "Basic", + category: Diagnostics.Basic_Options, description: Diagnostics.Specify_JSX_code_generation_Colon_preserve_react_native_or_react, }, { @@ -168,14 +168,14 @@ namespace ts { shortName: "d", type: "boolean", showInSimplifiedHelpView: true, - category: "Basic", + category: Diagnostics.Basic_Options, description: Diagnostics.Generates_corresponding_d_ts_file, }, { name: "sourceMap", type: "boolean", showInSimplifiedHelpView: true, - category: "Basic", + category: Diagnostics.Basic_Options, description: Diagnostics.Generates_corresponding_map_file, }, { @@ -184,7 +184,7 @@ namespace ts { isFilePath: true, paramType: Diagnostics.FILE, showInSimplifiedHelpView: true, - category: "Basic", + category: Diagnostics.Basic_Options, description: Diagnostics.Concatenate_and_emit_output_to_single_file, }, { @@ -193,7 +193,7 @@ namespace ts { isFilePath: true, paramType: Diagnostics.DIRECTORY, showInSimplifiedHelpView: true, - category: "Basic", + category: Diagnostics.Basic_Options, description: Diagnostics.Redirect_output_structure_to_the_directory, }, { @@ -201,7 +201,7 @@ namespace ts { type: "string", isFilePath: true, paramType: Diagnostics.LOCATION, - category: "Basic", + category: Diagnostics.Basic_Options, description: Diagnostics.Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir, }, { @@ -209,39 +209,39 @@ namespace ts { type: "string", isFilePath: true, paramType: Diagnostics.DIRECTORY, - category: "Basic", + category: Diagnostics.Basic_Options, description: Diagnostics.Output_directory_for_generated_declaration_files }, { name: "removeComments", type: "boolean", showInSimplifiedHelpView: true, - category: "Basic", + category: Diagnostics.Basic_Options, description: Diagnostics.Do_not_emit_comments_to_output, }, { name: "noEmit", type: "boolean", showInSimplifiedHelpView: true, - category: "Basic", + category: Diagnostics.Basic_Options, description: Diagnostics.Do_not_emit_outputs, }, { name: "importHelpers", type: "boolean", - category: "Basic", + category: Diagnostics.Basic_Options, description: Diagnostics.Import_emit_helpers_from_tslib }, { name: "skipLibCheck", type: "boolean", - category: "Basic", + category: Diagnostics.Basic_Options, description: Diagnostics.Skip_type_checking_of_declaration_files, }, { name: "isolatedModules", type: "boolean", - category: "Basic", + category: Diagnostics.Basic_Options, description: Diagnostics.Unconditionally_emit_imports_for_unresolved_files }, @@ -250,86 +250,86 @@ namespace ts { name: "noImplicitAny", type: "boolean", showInSimplifiedHelpView: true, - category: "StrictChecks", + category: Diagnostics.Strict_Checks, description: Diagnostics.Raise_error_on_expressions_and_declarations_with_an_implied_any_type, }, { name: "strictNullChecks", type: "boolean", showInSimplifiedHelpView: true, - category: "StrictChecks", + category: Diagnostics.Strict_Checks, description: Diagnostics.Enable_strict_null_checks }, { name: "noImplicitThis", type: "boolean", showInSimplifiedHelpView: true, - category: "StrictChecks", + category: Diagnostics.Strict_Checks, description: Diagnostics.Raise_error_on_this_expressions_with_an_implied_any_type, }, { name: "noUnusedLocals", type: "boolean", showInSimplifiedHelpView: true, - category: "StrictChecks", + category: Diagnostics.Strict_Checks, description: Diagnostics.Report_errors_on_unused_locals, }, { name: "noUnusedParameters", type: "boolean", showInSimplifiedHelpView: true, - category: "StrictChecks", + category: Diagnostics.Strict_Checks, description: Diagnostics.Report_errors_on_unused_parameters, }, { name: "alwaysStrict", type: "boolean", showInSimplifiedHelpView: true, - category: "StrictChecks", + category: Diagnostics.Strict_Checks, description: Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file }, { name: "noImplicitReturns", type: "boolean", showInSimplifiedHelpView: true, - category: "StrictChecks", + category: Diagnostics.Strict_Checks, description: Diagnostics.Report_error_when_not_all_code_paths_in_function_return_a_value }, { name: "noFallthroughCasesInSwitch", type: "boolean", showInSimplifiedHelpView: true, - category: "StrictChecks", + category: Diagnostics.Strict_Checks, description: Diagnostics.Report_errors_for_fallthrough_cases_in_switch_statement }, { name: "allowUnusedLabels", type: "boolean", - category: "StrictChecks", + category: Diagnostics.Strict_Checks, description: Diagnostics.Do_not_report_errors_on_unused_labels }, { name: "allowUnreachableCode", type: "boolean", - category: "StrictChecks", + category: Diagnostics.Strict_Checks, description: Diagnostics.Do_not_report_errors_on_unreachable_code }, { name: "suppressExcessPropertyErrors", type: "boolean", - category: "StrictChecks", + category: Diagnostics.Strict_Checks, description: Diagnostics.Suppress_excess_property_checks_for_object_literals, }, { name: "suppressImplicitAnyIndexErrors", type: "boolean", - category: "StrictChecks", + category: Diagnostics.Strict_Checks, description: Diagnostics.Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures, }, { name: "forceConsistentCasingInFileNames", type: "boolean", - category: "StrictChecks", + category: Diagnostics.Strict_Checks, description: Diagnostics.Disallow_inconsistently_cased_references_to_the_same_file }, @@ -341,14 +341,14 @@ namespace ts { "classic": ModuleResolutionKind.Classic, }), paramType: Diagnostics.STRATEGY, - category: "ModuleResolution", + category: Diagnostics.Module_Resolution_Options, description: Diagnostics.Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6, }, { name: "baseUrl", type: "string", isFilePath: true, - category: "ModuleResolution", + category: Diagnostics.Module_Resolution_Options, description: Diagnostics.Base_directory_to_resolve_non_absolute_module_names }, { @@ -357,7 +357,7 @@ namespace ts { name: "paths", type: "object", isTSConfigOnly: true, - category: "ModuleResolution", + category: Diagnostics.Module_Resolution_Options, description: Diagnostics.List_of_path_mapping_entries_for_module_names_to_locations_relative_to_the_baseUrl }, @@ -372,7 +372,7 @@ namespace ts { type: "string", isFilePath: true }, - category: "ModuleResolution", + category: Diagnostics.Module_Resolution_Options, description: Diagnostics.List_of_root_folders_whose_combined_content_represent_the_structure_of_the_project_at_runtime }, { @@ -383,7 +383,7 @@ namespace ts { type: "string", isFilePath: true }, - category: "ModuleResolution", + category: Diagnostics.Module_Resolution_Options, description: Diagnostics.List_of_folders_to_include_type_definitions_from }, { @@ -394,19 +394,19 @@ namespace ts { type: "string" }, showInSimplifiedHelpView: true, - category: "ModuleResolution", + category: Diagnostics.Module_Resolution_Options, description: Diagnostics.Type_declaration_files_to_be_included_in_compilation }, { name: "allowSyntheticDefaultImports", type: "boolean", - category: "ModuleResolution", + 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: "maxNodeModuleJsDepth", type: "number", - category: "ModuleResolution", + category: Diagnostics.Module_Resolution_Options, description: Diagnostics.The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files }, @@ -416,7 +416,7 @@ namespace ts { type: "string", isFilePath: true, paramType: Diagnostics.LOCATION, - category: "SourceMaps", + category: Diagnostics.SourceMap_Options, description: Diagnostics.Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations, }, { @@ -424,19 +424,19 @@ namespace ts { type: "string", isFilePath: true, paramType: Diagnostics.LOCATION, - category: "SourceMaps", + category: Diagnostics.SourceMap_Options, description: Diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations, }, { name: "inlineSourceMap", type: "boolean", - category: "SourceMaps", + category: Diagnostics.SourceMap_Options, description: Diagnostics.Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file }, { name: "inlineSources", type: "boolean", - category: "SourceMaps", + category: Diagnostics.SourceMap_Options, description:Diagnostics.Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set }, @@ -444,7 +444,7 @@ namespace ts { { name: "jsxFactory", type: "string", - category: "JSX", + category: Diagnostics.JSX_Options, description: Diagnostics.Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h }, @@ -452,13 +452,13 @@ namespace ts { { name: "experimentalDecorators", type: "boolean", - category: "Experimental", + category: Diagnostics.Experimental_Options, description: Diagnostics.Enables_experimental_support_for_ES7_decorators }, { name: "emitDecoratorMetadata", type: "boolean", - category: "Experimental", + category: Diagnostics.Experimental_Options, description: Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators }, @@ -466,31 +466,31 @@ namespace ts { { name: "diagnostics", type: "boolean", - category: "Advanced", + category: Diagnostics.Advanced_Options, description: Diagnostics.Show_diagnostic_information }, { name: "extendedDiagnostics", type: "boolean", - category: "Advanced", + category: Diagnostics.Advanced_Options, description: Diagnostics.Show_extended_diagnostic_information }, { name: "traceResolution", type: "boolean", - category: "Advanced", + category: Diagnostics.Advanced_Options, description: Diagnostics.Enable_tracing_of_the_name_resolution_process }, { name: "listFiles", type: "boolean", - category: "Advanced", + category: Diagnostics.Advanced_Options, description: Diagnostics.Print_names_of_files_part_of_the_compilation }, { name: "listEmittedFiles", type: "boolean", - category: "Advanced", + category: Diagnostics.Advanced_Options, description: Diagnostics.Print_names_of_generated_files_part_of_the_compilation }, @@ -499,40 +499,40 @@ namespace ts { type: "string", isFilePath: false, // This is intentionally broken to support compatability with existing tsconfig files // for correct behaviour, please use outFile - category: "Advanced", + category: Diagnostics.Advanced_Options, paramType: Diagnostics.FILE, description: Diagnostics.Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file, }, { name: "reactNamespace", type: "string", - category: "Advanced", + category: Diagnostics.Advanced_Options, description: Diagnostics.Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react_JSX_emit }, { name: "skipDefaultLibCheck", type: "boolean", - category: "Advanced", + category: Diagnostics.Advanced_Options, description: Diagnostics.Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files }, { name: "charset", type: "string", - category: "Advanced", + category: Diagnostics.Advanced_Options, description: Diagnostics.The_character_set_of_the_input_files }, compileOnSaveCommandLineOption, { name: "emitBOM", type: "boolean", - category: "Advanced", + category: Diagnostics.Advanced_Options, description:Diagnostics.Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files }, { name: "locale", type: "string", - category: "Advanced", + category: Diagnostics.Advanced_Options, description: Diagnostics.The_locale_to_use_to_show_error_messages_e_g_en_us }, { @@ -542,61 +542,61 @@ namespace ts { "lf": NewLineKind.LineFeed }), paramType: Diagnostics.NEWLINE, - category: "Advanced", + category: Diagnostics.Advanced_Options, description: Diagnostics.Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix, }, { name: "noErrorTruncation", type: "boolean", - category: "Advanced", + category: Diagnostics.Advanced_Options, description: Diagnostics.Do_not_truncation_error_messages }, { name: "noLib", type: "boolean", - category: "Advanced", + category: Diagnostics.Advanced_Options, description: Diagnostics.Do_not_include_the_default_library_file_lib_d_ts }, { name: "noResolve", type: "boolean", - category: "Advanced", + category: Diagnostics.Advanced_Options, description:Diagnostics.Do_not_add_triple_slash_references_or_module_import_targets_to_the_list_of_compiled_files }, { name: "stripInternal", type: "boolean", - category: "Advanced", + category: Diagnostics.Advanced_Options, description: Diagnostics.Do_not_emit_declarations_for_code_that_has_an_internal_annotation, }, { name: "disableSizeLimit", type: "boolean", - category: "Advanced", + category: Diagnostics.Advanced_Options, description: Diagnostics.Disable_size_limitation_on_JavaScript_project }, { name: "noImplicitUseStrict", type: "boolean", - category: "Advanced", + category: Diagnostics.Advanced_Options, description: Diagnostics.Do_not_emit_use_strict_directives_in_module_output }, { name: "noEmitHelpers", type: "boolean", - category: "Advanced", + category: Diagnostics.Advanced_Options, description: Diagnostics.Do_not_generate_custom_helper_functions_like_extends_in_compiled_output }, { name: "noEmitOnError", type: "boolean", - category: "Advanced", + category: Diagnostics.Advanced_Options, description: Diagnostics.Do_not_emit_outputs_if_any_errors_were_reported, }, { name: "preserveConstEnums", type: "boolean", - category: "Advanced", + category: Diagnostics.Advanced_Options, description: Diagnostics.Do_not_erase_const_enum_declarations_in_generated_code }, ]; @@ -907,7 +907,7 @@ namespace ts { if (hasProperty(options, name)) { // tsconfig only options cannot be specified via command line, // so we can assume that only types that can appear here string | number | boolean - if (optionsNameMap.has(name) && optionsNameMap.get(name).category === "CommandLine") { + if (optionsNameMap.has(name) && optionsNameMap.get(name).category === Diagnostics.CommandLine_Options) { continue; } const value = options[name]; @@ -957,10 +957,11 @@ namespace ts { function writeConfigurations() { const categorizedOptions = reduceLeft( - filter(optionDeclarations, o => o.category !== "CommandLine" && o.category !== "Advanced"), + filter(optionDeclarations, o => o.category !== Diagnostics.CommandLine_Options && o.category !== Diagnostics.Advanced_Options), (memo, value) => { if (value.category) { - (memo[value.category] || (memo[value.category] = [])).push(value); + const name = getLocaleSpecificMessage(value.category); + (memo[name] || (memo[name] = [])).push(value); } return memo; }, >{}); @@ -977,7 +978,7 @@ namespace ts { result += `${tab}${tab}// ${category}${newLine}`; result += `${newLine}`; for (const option of categorizedOptions[category]) { - result += `${tab}${tab}// ${option.description && option.description.message || option.name}${newLine}`; + result += `${tab}${tab}// ${option.description && getLocaleSpecificMessage(option.description) || option.name}${newLine}`; if (option.name in configurations.compilerOptions) { result += `${tab}${tab}"${option.name}": ${JSON.stringify(configurations.compilerOptions[option.name])}${++seenKnownKeys === knownKesyCount ? "" : ","}${newLine}`; } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index b487b47b10..f5ee14a8cb 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3085,6 +3085,39 @@ "category": "Message", "code": 6170 }, + "CommandLine Options": { + "category": "Message", + "code": 6171 + }, + "Basic Options": { + "category": "Message", + "code": 6172 + }, + "Strict Checks": { + "category": "Message", + "code": 6173 + }, + "Module Resolution Options": { + "category": "Message", + "code": 6174 + }, + "SourceMap Options": { + "category": "Message", + "code": 6175 + }, + "JSX Options": { + "category": "Message", + "code": 6176 + }, + "Experimental Options": { + "category": "Message", + "code": 6177 + }, + "Advanced Options": { + "category": "Message", + "code": 6178 + }, + "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 69c8d7a5c9..589c196d13 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3386,7 +3386,7 @@ isTSConfigOnly?: boolean; // True if option can only be specified via tsconfig.json file isCommandLineOnly?: boolean; showInSimplifiedHelpView?:boolean; - category?: "CommandLine" | "Basic" | "StrictChecks" | "ModuleResolution" | "JSX" | "SourceMaps" | "Experimental" | "Advanced"; + category?: DiagnosticMessage; } /* @internal */ From 4de44ee1a241da87ccf2a797e5eb682c1ddbf57f Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 8 Feb 2017 19:32:27 -0800 Subject: [PATCH 010/164] Mark some more options as advanced --- src/compiler/commandLineParser.ts | 100 +++++++++++++++--------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 46327668f2..7b32a23a7d 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -204,14 +204,6 @@ namespace ts { category: Diagnostics.Basic_Options, description: Diagnostics.Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir, }, - { - name: "declarationDir", - type: "string", - isFilePath: true, - paramType: Diagnostics.DIRECTORY, - category: Diagnostics.Basic_Options, - description: Diagnostics.Output_directory_for_generated_declaration_files - }, { name: "removeComments", type: "boolean", @@ -232,12 +224,6 @@ namespace ts { category: Diagnostics.Basic_Options, description: Diagnostics.Import_emit_helpers_from_tslib }, - { - name: "skipLibCheck", - type: "boolean", - category: Diagnostics.Basic_Options, - description: Diagnostics.Skip_type_checking_of_declaration_files, - }, { name: "isolatedModules", type: "boolean", @@ -302,36 +288,6 @@ namespace ts { category: Diagnostics.Strict_Checks, description: Diagnostics.Report_errors_for_fallthrough_cases_in_switch_statement }, - { - name: "allowUnusedLabels", - type: "boolean", - category: Diagnostics.Strict_Checks, - description: Diagnostics.Do_not_report_errors_on_unused_labels - }, - { - name: "allowUnreachableCode", - type: "boolean", - category: Diagnostics.Strict_Checks, - description: Diagnostics.Do_not_report_errors_on_unreachable_code - }, - { - name: "suppressExcessPropertyErrors", - type: "boolean", - category: Diagnostics.Strict_Checks, - description: Diagnostics.Suppress_excess_property_checks_for_object_literals, - }, - { - name: "suppressImplicitAnyIndexErrors", - type: "boolean", - category: Diagnostics.Strict_Checks, - description: Diagnostics.Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures, - }, - { - name: "forceConsistentCasingInFileNames", - type: "boolean", - category: Diagnostics.Strict_Checks, - description: Diagnostics.Disallow_inconsistently_cased_references_to_the_same_file - }, // Module Resolution { @@ -403,12 +359,6 @@ namespace ts { 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: "maxNodeModuleJsDepth", - type: "number", - category: Diagnostics.Module_Resolution_Options, - description: Diagnostics.The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files - }, // Source Maps { @@ -599,6 +549,56 @@ namespace ts { category: Diagnostics.Advanced_Options, description: Diagnostics.Do_not_erase_const_enum_declarations_in_generated_code }, + { + name: "declarationDir", + type: "string", + isFilePath: true, + paramType: Diagnostics.DIRECTORY, + category: Diagnostics.Advanced_Options, + description: Diagnostics.Output_directory_for_generated_declaration_files + }, + { + name: "skipLibCheck", + type: "boolean", + category: Diagnostics.Advanced_Options, + description: Diagnostics.Skip_type_checking_of_declaration_files, + }, + { + name: "allowUnusedLabels", + type: "boolean", + category: Diagnostics.Advanced_Options, + description: Diagnostics.Do_not_report_errors_on_unused_labels + }, + { + name: "allowUnreachableCode", + type: "boolean", + category: Diagnostics.Advanced_Options, + description: Diagnostics.Do_not_report_errors_on_unreachable_code + }, + { + name: "suppressExcessPropertyErrors", + type: "boolean", + category: Diagnostics.Advanced_Options, + description: Diagnostics.Suppress_excess_property_checks_for_object_literals, + }, + { + name: "suppressImplicitAnyIndexErrors", + type: "boolean", + category: Diagnostics.Advanced_Options, + description: Diagnostics.Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures, + }, + { + name: "forceConsistentCasingInFileNames", + type: "boolean", + category: Diagnostics.Advanced_Options, + description: Diagnostics.Disallow_inconsistently_cased_references_to_the_same_file + }, + { + name: "maxNodeModuleJsDepth", + type: "number", + category: Diagnostics.Advanced_Options, + description: Diagnostics.The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files + }, ]; /* @internal */ From abae1bd13680e1fd13deb2f827563770181d071b Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 13 Feb 2017 22:13:48 -0800 Subject: [PATCH 011/164] Accept baseline recursivelly --- Jakefile.js | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/Jakefile.js b/Jakefile.js index f422a99572..89e693fe19 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -966,21 +966,31 @@ task("baseline-accept", function () { function acceptBaseline(sourceFolder, targetFolder) { console.log('Accept baselines from ' + sourceFolder + ' to ' + targetFolder); - var files = fs.readdirSync(sourceFolder); var deleteEnding = '.delete'; - for (var i in files) { - var filename = files[i]; - var fullLocalPath = path.join(sourceFolder, filename); - if (fs.statSync(fullLocalPath).isFile()) { - if (filename.substr(filename.length - deleteEnding.length) === deleteEnding) { - filename = filename.substr(0, filename.length - deleteEnding.length); - fs.unlinkSync(path.join(targetFolder, filename)); - } else { - var target = path.join(targetFolder, filename); - if (fs.existsSync(target)) { - fs.unlinkSync(target); + + acceptBaselineFolder(sourceFolder, targetFolder); + + function acceptBaselineFolder(sourceFolder, targetFolder) { + var files = fs.readdirSync(sourceFolder); + + for (var i in files) { + var filename = files[i]; + var fullLocalPath = path.join(sourceFolder, filename); + var stat = fs.statSync(fullLocalPath); + if (stat.isFile()) { + if (filename.substr(filename.length - deleteEnding.length) === deleteEnding) { + filename = filename.substr(0, filename.length - deleteEnding.length); + fs.unlinkSync(path.join(targetFolder, filename)); + } else { + var target = path.join(targetFolder, filename); + if (fs.existsSync(target)) { + fs.unlinkSync(target); + } + fs.renameSync(path.join(sourceFolder, filename), target); } - fs.renameSync(path.join(sourceFolder, filename), target); + } + else if (stat.isDirectory()) { + acceptBaselineFolder(fullLocalPath, path.join(targetFolder, filename)); } } } From 66135309354f018550b515321ed5dce3cc85e8cb Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 13 Feb 2017 22:14:05 -0800 Subject: [PATCH 012/164] Accept baselines --- src/harness/unittests/initializeTSConfig.ts | 2 +- .../tsconfig.json | 130 ++++++++++++++++- .../tsconfig.json | 129 ++++++++++++++++- .../tsconfig.json | 129 ++++++++++++++++- .../tsconfig.json | 130 ++++++++++++++++- .../tsconfig.json | 134 ++++++++++++++++-- .../tsconfig.json | 130 ++++++++++++++++- .../tsconfig.json | 134 ++++++++++++++++-- .../tsconfig.json | 134 ++++++++++++++++-- 9 files changed, 1007 insertions(+), 45 deletions(-) diff --git a/src/harness/unittests/initializeTSConfig.ts b/src/harness/unittests/initializeTSConfig.ts index cb995212a9..b71396411e 100644 --- a/src/harness/unittests/initializeTSConfig.ts +++ b/src/harness/unittests/initializeTSConfig.ts @@ -12,7 +12,7 @@ namespace ts { it(`Correct output for ${outputFileName}`, () => { Harness.Baseline.runBaseline(outputFileName, () => { if (initResult) { - return JSON.stringify(initResult, undefined, 4); + return initResult; } else { // This can happen if compiler recieve invalid compiler-options diff --git a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json index ea891967cb..9234ce6ad8 100644 --- a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json @@ -1,8 +1,130 @@ { "compilerOptions": { - "module": "commonjs", + // Basic Options + + // Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT' "target": "es5", - "noImplicitAny": false, - "sourceMap": false + + // Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015' + "module": "commonjs" + + // Specify library files to be included in the compilation: + // "lib": [], + + // Allow javascript files to be compiled. + // "allowJs": true, + + // Specify JSX code generation: 'preserve', 'react-native', or 'react' + // "jsx": "preserve", + + // Generates corresponding '.d.ts' file. + // "declaration": true, + + // Generates corresponding '.map' file. + // "sourceMap": true, + + // Concatenate and emit output to single file. + // "outFile": "./", + + // Redirect output structure to the directory. + // "outDir": "./", + + // Specify the root directory of input files. Use to control the output directory structure with --outDir. + // "rootDir": "./", + + // Do not emit comments to output. + // "removeComments": true, + + // Do not emit outputs. + // "noEmit": true, + + // Import emit helpers from 'tslib'. + // "importHelpers": true, + + // Unconditionally emit imports for unresolved files. + // "isolatedModules": true, + + + // Strict Checks + + // Raise error on expressions and declarations with an implied 'any' type. + // "noImplicitAny": true, + + // Enable strict null checks. + // "strictNullChecks": true, + + // Raise error on 'this' expressions with an implied 'any' type. + // "noImplicitThis": true, + + // Report errors on unused locals. + // "noUnusedLocals": true, + + // Report errors on unused parameters. + // "noUnusedParameters": true, + + // Parse in strict mode and emit "use strict" for each source file + // "alwaysStrict": true, + + // Report error when not all code paths in function return a value. + // "noImplicitReturns": true, + + // Report errors for fallthrough cases in switch statement. + // "noFallthroughCasesInSwitch": true, + + + // Module Resolution Options + + // Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). + // "moduleResolution": "node", + + // Base directory to resolve non-absolute module names. + // "baseUrl": "./", + + // List of path mapping entries for module names to locations relative to the 'baseUrl'. + // "paths": {}, + + // List of root folders whose combined content represent the structure of the project at runtime. + // "rootDirs": [], + + // List of folders to include type definitions from. + // "typeRoots": [], + + // Type declaration files to be included in compilation. + // "types": [], + + // Allow default imports from modules with no default export. This does not affect code emit, just typechecking. + // "allowSyntheticDefaultImports": true, + + + // SourceMap Options + + // Specify the location where debugger should locate TypeScript files instead of source locations. + // "sourceRoot": "./", + + // Specify the location where debugger should locate map files instead of generated locations. + // "mapRoot": "./", + + // Emit a single file with source maps instead of having a separate file. + // "inlineSourceMap": true, + + // Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. + // "inlineSources": true, + + + // JSX Options + + // Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'. + // "jsxFactory": "", + + + // Experimental Options + + // Enables experimental support for ES7 decorators. + // "experimentalDecorators": true, + + // Enables experimental support for emitting type metadata for decorators. + // "emitDecoratorMetadata": true, + + } -} \ No newline at end of file +} diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json index abe135b4f1..7481eb6e86 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json @@ -1,9 +1,130 @@ { "compilerOptions": { - "module": "commonjs", + // Basic Options + + // Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT' "target": "es5", - "noImplicitAny": false, - "sourceMap": false, + + // Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015' + "module": "commonjs", + + // Specify library files to be included in the compilation: + // "lib": [], + + // Allow javascript files to be compiled. + // "allowJs": true, + + // Specify JSX code generation: 'preserve', 'react-native', or 'react' + // "jsx": "preserve", + + // Generates corresponding '.d.ts' file. + // "declaration": true, + + // Generates corresponding '.map' file. + // "sourceMap": true, + + // Concatenate and emit output to single file. + // "outFile": "./", + + // Redirect output structure to the directory. + // "outDir": "./", + + // Specify the root directory of input files. Use to control the output directory structure with --outDir. + // "rootDir": "./", + + // Do not emit comments to output. + // "removeComments": true, + + // Do not emit outputs. + // "noEmit": true, + + // Import emit helpers from 'tslib'. + // "importHelpers": true, + + // Unconditionally emit imports for unresolved files. + // "isolatedModules": true, + + + // Strict Checks + + // Raise error on expressions and declarations with an implied 'any' type. + // "noImplicitAny": true, + + // Enable strict null checks. + // "strictNullChecks": true, + + // Raise error on 'this' expressions with an implied 'any' type. + // "noImplicitThis": true, + + // Report errors on unused locals. "noUnusedLocals": true + + // Report errors on unused parameters. + // "noUnusedParameters": true, + + // Parse in strict mode and emit "use strict" for each source file + // "alwaysStrict": true, + + // Report error when not all code paths in function return a value. + // "noImplicitReturns": true, + + // Report errors for fallthrough cases in switch statement. + // "noFallthroughCasesInSwitch": true, + + + // Module Resolution Options + + // Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). + // "moduleResolution": "node", + + // Base directory to resolve non-absolute module names. + // "baseUrl": "./", + + // List of path mapping entries for module names to locations relative to the 'baseUrl'. + // "paths": {}, + + // List of root folders whose combined content represent the structure of the project at runtime. + // "rootDirs": [], + + // List of folders to include type definitions from. + // "typeRoots": [], + + // Type declaration files to be included in compilation. + // "types": [], + + // Allow default imports from modules with no default export. This does not affect code emit, just typechecking. + // "allowSyntheticDefaultImports": true, + + + // SourceMap Options + + // Specify the location where debugger should locate TypeScript files instead of source locations. + // "sourceRoot": "./", + + // Specify the location where debugger should locate map files instead of generated locations. + // "mapRoot": "./", + + // Emit a single file with source maps instead of having a separate file. + // "inlineSourceMap": true, + + // Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. + // "inlineSources": true, + + + // JSX Options + + // Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'. + // "jsxFactory": "", + + + // Experimental Options + + // Enables experimental support for ES7 decorators. + // "experimentalDecorators": true, + + // Enables experimental support for emitting type metadata for decorators. + // "emitDecoratorMetadata": true, + + } -} \ No newline at end of file +} diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json index e28b66c8c2..37ddc8169b 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json @@ -1,9 +1,130 @@ { "compilerOptions": { - "module": "commonjs", + // Basic Options + + // Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT' "target": "es5", - "noImplicitAny": false, - "sourceMap": false, + + // Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015' + "module": "commonjs", + + // Specify library files to be included in the compilation: + // "lib": [], + + // Allow javascript files to be compiled. + // "allowJs": true, + + // Specify JSX code generation: 'preserve', 'react-native', or 'react' "jsx": "react" + + // Generates corresponding '.d.ts' file. + // "declaration": true, + + // Generates corresponding '.map' file. + // "sourceMap": true, + + // Concatenate and emit output to single file. + // "outFile": "./", + + // Redirect output structure to the directory. + // "outDir": "./", + + // Specify the root directory of input files. Use to control the output directory structure with --outDir. + // "rootDir": "./", + + // Do not emit comments to output. + // "removeComments": true, + + // Do not emit outputs. + // "noEmit": true, + + // Import emit helpers from 'tslib'. + // "importHelpers": true, + + // Unconditionally emit imports for unresolved files. + // "isolatedModules": true, + + + // Strict Checks + + // Raise error on expressions and declarations with an implied 'any' type. + // "noImplicitAny": true, + + // Enable strict null checks. + // "strictNullChecks": true, + + // Raise error on 'this' expressions with an implied 'any' type. + // "noImplicitThis": true, + + // Report errors on unused locals. + // "noUnusedLocals": true, + + // Report errors on unused parameters. + // "noUnusedParameters": true, + + // Parse in strict mode and emit "use strict" for each source file + // "alwaysStrict": true, + + // Report error when not all code paths in function return a value. + // "noImplicitReturns": true, + + // Report errors for fallthrough cases in switch statement. + // "noFallthroughCasesInSwitch": true, + + + // Module Resolution Options + + // Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). + // "moduleResolution": "node", + + // Base directory to resolve non-absolute module names. + // "baseUrl": "./", + + // List of path mapping entries for module names to locations relative to the 'baseUrl'. + // "paths": {}, + + // List of root folders whose combined content represent the structure of the project at runtime. + // "rootDirs": [], + + // List of folders to include type definitions from. + // "typeRoots": [], + + // Type declaration files to be included in compilation. + // "types": [], + + // Allow default imports from modules with no default export. This does not affect code emit, just typechecking. + // "allowSyntheticDefaultImports": true, + + + // SourceMap Options + + // Specify the location where debugger should locate TypeScript files instead of source locations. + // "sourceRoot": "./", + + // Specify the location where debugger should locate map files instead of generated locations. + // "mapRoot": "./", + + // Emit a single file with source maps instead of having a separate file. + // "inlineSourceMap": true, + + // Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. + // "inlineSources": true, + + + // JSX Options + + // Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'. + // "jsxFactory": "", + + + // Experimental Options + + // Enables experimental support for ES7 decorators. + // "experimentalDecorators": true, + + // Enables experimental support for emitting type metadata for decorators. + // "emitDecoratorMetadata": true, + + } -} \ No newline at end of file +} diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json index 5273b3cb7c..24fb7b4431 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json @@ -1,13 +1,135 @@ { "compilerOptions": { - "module": "commonjs", + // Basic Options + + // Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT' "target": "es5", - "noImplicitAny": false, - "sourceMap": false + + // Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015' + "module": "commonjs" + + // Specify library files to be included in the compilation: + // "lib": [], + + // Allow javascript files to be compiled. + // "allowJs": true, + + // Specify JSX code generation: 'preserve', 'react-native', or 'react' + // "jsx": "preserve", + + // Generates corresponding '.d.ts' file. + // "declaration": true, + + // Generates corresponding '.map' file. + // "sourceMap": true, + + // Concatenate and emit output to single file. + // "outFile": "./", + + // Redirect output structure to the directory. + // "outDir": "./", + + // Specify the root directory of input files. Use to control the output directory structure with --outDir. + // "rootDir": "./", + + // Do not emit comments to output. + // "removeComments": true, + + // Do not emit outputs. + // "noEmit": true, + + // Import emit helpers from 'tslib'. + // "importHelpers": true, + + // Unconditionally emit imports for unresolved files. + // "isolatedModules": true, + + + // Strict Checks + + // Raise error on expressions and declarations with an implied 'any' type. + // "noImplicitAny": true, + + // Enable strict null checks. + // "strictNullChecks": true, + + // Raise error on 'this' expressions with an implied 'any' type. + // "noImplicitThis": true, + + // Report errors on unused locals. + // "noUnusedLocals": true, + + // Report errors on unused parameters. + // "noUnusedParameters": true, + + // Parse in strict mode and emit "use strict" for each source file + // "alwaysStrict": true, + + // Report error when not all code paths in function return a value. + // "noImplicitReturns": true, + + // Report errors for fallthrough cases in switch statement. + // "noFallthroughCasesInSwitch": true, + + + // Module Resolution Options + + // Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). + // "moduleResolution": "node", + + // Base directory to resolve non-absolute module names. + // "baseUrl": "./", + + // List of path mapping entries for module names to locations relative to the 'baseUrl'. + // "paths": {}, + + // List of root folders whose combined content represent the structure of the project at runtime. + // "rootDirs": [], + + // List of folders to include type definitions from. + // "typeRoots": [], + + // Type declaration files to be included in compilation. + // "types": [], + + // Allow default imports from modules with no default export. This does not affect code emit, just typechecking. + // "allowSyntheticDefaultImports": true, + + + // SourceMap Options + + // Specify the location where debugger should locate TypeScript files instead of source locations. + // "sourceRoot": "./", + + // Specify the location where debugger should locate map files instead of generated locations. + // "mapRoot": "./", + + // Emit a single file with source maps instead of having a separate file. + // "inlineSourceMap": true, + + // Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. + // "inlineSources": true, + + + // JSX Options + + // Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'. + // "jsxFactory": "", + + + // Experimental Options + + // Enables experimental support for ES7 decorators. + // "experimentalDecorators": true, + + // Enables experimental support for emitting type metadata for decorators. + // "emitDecoratorMetadata": true, + + }, "files": [ "file0.st", "file1.ts", "file2.ts" ] -} \ No newline at end of file +} diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json index fa9cb6cad8..0621c2991e 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json @@ -1,12 +1,130 @@ { "compilerOptions": { - "module": "commonjs", + // Basic Options + + // Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT' "target": "es5", - "noImplicitAny": false, - "sourceMap": false, - "lib": [ - "es5", - "es2015.promise" - ] + + // Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015' + "module": "commonjs", + + // Specify library files to be included in the compilation: + "lib": ["es5","es2015.promise"] + + // Allow javascript files to be compiled. + // "allowJs": true, + + // Specify JSX code generation: 'preserve', 'react-native', or 'react' + // "jsx": "preserve", + + // Generates corresponding '.d.ts' file. + // "declaration": true, + + // Generates corresponding '.map' file. + // "sourceMap": true, + + // Concatenate and emit output to single file. + // "outFile": "./", + + // Redirect output structure to the directory. + // "outDir": "./", + + // Specify the root directory of input files. Use to control the output directory structure with --outDir. + // "rootDir": "./", + + // Do not emit comments to output. + // "removeComments": true, + + // Do not emit outputs. + // "noEmit": true, + + // Import emit helpers from 'tslib'. + // "importHelpers": true, + + // Unconditionally emit imports for unresolved files. + // "isolatedModules": true, + + + // Strict Checks + + // Raise error on expressions and declarations with an implied 'any' type. + // "noImplicitAny": true, + + // Enable strict null checks. + // "strictNullChecks": true, + + // Raise error on 'this' expressions with an implied 'any' type. + // "noImplicitThis": true, + + // Report errors on unused locals. + // "noUnusedLocals": true, + + // Report errors on unused parameters. + // "noUnusedParameters": true, + + // Parse in strict mode and emit "use strict" for each source file + // "alwaysStrict": true, + + // Report error when not all code paths in function return a value. + // "noImplicitReturns": true, + + // Report errors for fallthrough cases in switch statement. + // "noFallthroughCasesInSwitch": true, + + + // Module Resolution Options + + // Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). + // "moduleResolution": "node", + + // Base directory to resolve non-absolute module names. + // "baseUrl": "./", + + // List of path mapping entries for module names to locations relative to the 'baseUrl'. + // "paths": {}, + + // List of root folders whose combined content represent the structure of the project at runtime. + // "rootDirs": [], + + // List of folders to include type definitions from. + // "typeRoots": [], + + // Type declaration files to be included in compilation. + // "types": [], + + // Allow default imports from modules with no default export. This does not affect code emit, just typechecking. + // "allowSyntheticDefaultImports": true, + + + // SourceMap Options + + // Specify the location where debugger should locate TypeScript files instead of source locations. + // "sourceRoot": "./", + + // Specify the location where debugger should locate map files instead of generated locations. + // "mapRoot": "./", + + // Emit a single file with source maps instead of having a separate file. + // "inlineSourceMap": true, + + // Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. + // "inlineSources": true, + + + // JSX Options + + // Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'. + // "jsxFactory": "", + + + // Experimental Options + + // Enables experimental support for ES7 decorators. + // "experimentalDecorators": true, + + // Enables experimental support for emitting type metadata for decorators. + // "emitDecoratorMetadata": true, + + } -} \ No newline at end of file +} diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json index ea891967cb..9234ce6ad8 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json @@ -1,8 +1,130 @@ { "compilerOptions": { - "module": "commonjs", + // Basic Options + + // Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT' "target": "es5", - "noImplicitAny": false, - "sourceMap": false + + // Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015' + "module": "commonjs" + + // Specify library files to be included in the compilation: + // "lib": [], + + // Allow javascript files to be compiled. + // "allowJs": true, + + // Specify JSX code generation: 'preserve', 'react-native', or 'react' + // "jsx": "preserve", + + // Generates corresponding '.d.ts' file. + // "declaration": true, + + // Generates corresponding '.map' file. + // "sourceMap": true, + + // Concatenate and emit output to single file. + // "outFile": "./", + + // Redirect output structure to the directory. + // "outDir": "./", + + // Specify the root directory of input files. Use to control the output directory structure with --outDir. + // "rootDir": "./", + + // Do not emit comments to output. + // "removeComments": true, + + // Do not emit outputs. + // "noEmit": true, + + // Import emit helpers from 'tslib'. + // "importHelpers": true, + + // Unconditionally emit imports for unresolved files. + // "isolatedModules": true, + + + // Strict Checks + + // Raise error on expressions and declarations with an implied 'any' type. + // "noImplicitAny": true, + + // Enable strict null checks. + // "strictNullChecks": true, + + // Raise error on 'this' expressions with an implied 'any' type. + // "noImplicitThis": true, + + // Report errors on unused locals. + // "noUnusedLocals": true, + + // Report errors on unused parameters. + // "noUnusedParameters": true, + + // Parse in strict mode and emit "use strict" for each source file + // "alwaysStrict": true, + + // Report error when not all code paths in function return a value. + // "noImplicitReturns": true, + + // Report errors for fallthrough cases in switch statement. + // "noFallthroughCasesInSwitch": true, + + + // Module Resolution Options + + // Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). + // "moduleResolution": "node", + + // Base directory to resolve non-absolute module names. + // "baseUrl": "./", + + // List of path mapping entries for module names to locations relative to the 'baseUrl'. + // "paths": {}, + + // List of root folders whose combined content represent the structure of the project at runtime. + // "rootDirs": [], + + // List of folders to include type definitions from. + // "typeRoots": [], + + // Type declaration files to be included in compilation. + // "types": [], + + // Allow default imports from modules with no default export. This does not affect code emit, just typechecking. + // "allowSyntheticDefaultImports": true, + + + // SourceMap Options + + // Specify the location where debugger should locate TypeScript files instead of source locations. + // "sourceRoot": "./", + + // Specify the location where debugger should locate map files instead of generated locations. + // "mapRoot": "./", + + // Emit a single file with source maps instead of having a separate file. + // "inlineSourceMap": true, + + // Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. + // "inlineSources": true, + + + // JSX Options + + // Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'. + // "jsxFactory": "", + + + // Experimental Options + + // Enables experimental support for ES7 decorators. + // "experimentalDecorators": true, + + // Enables experimental support for emitting type metadata for decorators. + // "emitDecoratorMetadata": true, + + } -} \ No newline at end of file +} diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json index 3ff8208d9d..499c3d57de 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json @@ -1,12 +1,130 @@ { "compilerOptions": { - "module": "commonjs", + // Basic Options + + // Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT' "target": "es5", - "noImplicitAny": false, - "sourceMap": false, - "lib": [ - "es5", - "es2015.core" - ] + + // Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015' + "module": "commonjs", + + // Specify library files to be included in the compilation: + "lib": ["es5","es2015.core"] + + // Allow javascript files to be compiled. + // "allowJs": true, + + // Specify JSX code generation: 'preserve', 'react-native', or 'react' + // "jsx": "preserve", + + // Generates corresponding '.d.ts' file. + // "declaration": true, + + // Generates corresponding '.map' file. + // "sourceMap": true, + + // Concatenate and emit output to single file. + // "outFile": "./", + + // Redirect output structure to the directory. + // "outDir": "./", + + // Specify the root directory of input files. Use to control the output directory structure with --outDir. + // "rootDir": "./", + + // Do not emit comments to output. + // "removeComments": true, + + // Do not emit outputs. + // "noEmit": true, + + // Import emit helpers from 'tslib'. + // "importHelpers": true, + + // Unconditionally emit imports for unresolved files. + // "isolatedModules": true, + + + // Strict Checks + + // Raise error on expressions and declarations with an implied 'any' type. + // "noImplicitAny": true, + + // Enable strict null checks. + // "strictNullChecks": true, + + // Raise error on 'this' expressions with an implied 'any' type. + // "noImplicitThis": true, + + // Report errors on unused locals. + // "noUnusedLocals": true, + + // Report errors on unused parameters. + // "noUnusedParameters": true, + + // Parse in strict mode and emit "use strict" for each source file + // "alwaysStrict": true, + + // Report error when not all code paths in function return a value. + // "noImplicitReturns": true, + + // Report errors for fallthrough cases in switch statement. + // "noFallthroughCasesInSwitch": true, + + + // Module Resolution Options + + // Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). + // "moduleResolution": "node", + + // Base directory to resolve non-absolute module names. + // "baseUrl": "./", + + // List of path mapping entries for module names to locations relative to the 'baseUrl'. + // "paths": {}, + + // List of root folders whose combined content represent the structure of the project at runtime. + // "rootDirs": [], + + // List of folders to include type definitions from. + // "typeRoots": [], + + // Type declaration files to be included in compilation. + // "types": [], + + // Allow default imports from modules with no default export. This does not affect code emit, just typechecking. + // "allowSyntheticDefaultImports": true, + + + // SourceMap Options + + // Specify the location where debugger should locate TypeScript files instead of source locations. + // "sourceRoot": "./", + + // Specify the location where debugger should locate map files instead of generated locations. + // "mapRoot": "./", + + // Emit a single file with source maps instead of having a separate file. + // "inlineSourceMap": true, + + // Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. + // "inlineSources": true, + + + // JSX Options + + // Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'. + // "jsxFactory": "", + + + // Experimental Options + + // Enables experimental support for ES7 decorators. + // "experimentalDecorators": true, + + // Enables experimental support for emitting type metadata for decorators. + // "emitDecoratorMetadata": true, + + } -} \ No newline at end of file +} diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json index b1740ac4c1..7eebba70ab 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json @@ -1,12 +1,130 @@ { "compilerOptions": { - "module": "commonjs", + // Basic Options + + // Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT' "target": "es5", - "noImplicitAny": false, - "sourceMap": false, - "types": [ - "jquery", - "mocha" - ] + + // Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015' + "module": "commonjs", + + // Specify library files to be included in the compilation: + // "lib": [], + + // Allow javascript files to be compiled. + // "allowJs": true, + + // Specify JSX code generation: 'preserve', 'react-native', or 'react' + // "jsx": "preserve", + + // Generates corresponding '.d.ts' file. + // "declaration": true, + + // Generates corresponding '.map' file. + // "sourceMap": true, + + // Concatenate and emit output to single file. + // "outFile": "./", + + // Redirect output structure to the directory. + // "outDir": "./", + + // Specify the root directory of input files. Use to control the output directory structure with --outDir. + // "rootDir": "./", + + // Do not emit comments to output. + // "removeComments": true, + + // Do not emit outputs. + // "noEmit": true, + + // Import emit helpers from 'tslib'. + // "importHelpers": true, + + // Unconditionally emit imports for unresolved files. + // "isolatedModules": true, + + + // Strict Checks + + // Raise error on expressions and declarations with an implied 'any' type. + // "noImplicitAny": true, + + // Enable strict null checks. + // "strictNullChecks": true, + + // Raise error on 'this' expressions with an implied 'any' type. + // "noImplicitThis": true, + + // Report errors on unused locals. + // "noUnusedLocals": true, + + // Report errors on unused parameters. + // "noUnusedParameters": true, + + // Parse in strict mode and emit "use strict" for each source file + // "alwaysStrict": true, + + // Report error when not all code paths in function return a value. + // "noImplicitReturns": true, + + // Report errors for fallthrough cases in switch statement. + // "noFallthroughCasesInSwitch": true, + + + // Module Resolution Options + + // Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). + // "moduleResolution": "node", + + // Base directory to resolve non-absolute module names. + // "baseUrl": "./", + + // List of path mapping entries for module names to locations relative to the 'baseUrl'. + // "paths": {}, + + // List of root folders whose combined content represent the structure of the project at runtime. + // "rootDirs": [], + + // List of folders to include type definitions from. + // "typeRoots": [], + + // Type declaration files to be included in compilation. + "types": ["jquery","mocha"] + + // Allow default imports from modules with no default export. This does not affect code emit, just typechecking. + // "allowSyntheticDefaultImports": true, + + + // SourceMap Options + + // Specify the location where debugger should locate TypeScript files instead of source locations. + // "sourceRoot": "./", + + // Specify the location where debugger should locate map files instead of generated locations. + // "mapRoot": "./", + + // Emit a single file with source maps instead of having a separate file. + // "inlineSourceMap": true, + + // Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. + // "inlineSources": true, + + + // JSX Options + + // Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'. + // "jsxFactory": "", + + + // Experimental Options + + // Enables experimental support for ES7 decorators. + // "experimentalDecorators": true, + + // Enables experimental support for emitting type metadata for decorators. + // "emitDecoratorMetadata": true, + + } -} \ No newline at end of file +} From 2752bfb704a576108b6601b38738dd37ba7f2f62 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 13 Feb 2017 22:21:34 -0800 Subject: [PATCH 013/164] Fix lint failures --- src/compiler/commandLineParser.ts | 12 ++++++------ src/compiler/types.ts | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 7b32a23a7d..c10045fce3 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -387,7 +387,7 @@ namespace ts { name: "inlineSources", type: "boolean", category: Diagnostics.SourceMap_Options, - description:Diagnostics.Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set + description: Diagnostics.Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set }, // JSX @@ -477,7 +477,7 @@ namespace ts { name: "emitBOM", type: "boolean", category: Diagnostics.Advanced_Options, - description:Diagnostics.Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files + description: Diagnostics.Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files }, { name: "locale", @@ -511,7 +511,7 @@ namespace ts { name: "noResolve", type: "boolean", category: Diagnostics.Advanced_Options, - description:Diagnostics.Do_not_add_triple_slash_references_or_module_import_targets_to_the_list_of_compiled_files + description: Diagnostics.Do_not_add_triple_slash_references_or_module_import_targets_to_the_list_of_compiled_files }, { name: "stripInternal", @@ -979,8 +979,8 @@ namespace ts { result += `${newLine}`; for (const option of categorizedOptions[category]) { result += `${tab}${tab}// ${option.description && getLocaleSpecificMessage(option.description) || option.name}${newLine}`; - if (option.name in configurations.compilerOptions) { - result += `${tab}${tab}"${option.name}": ${JSON.stringify(configurations.compilerOptions[option.name])}${++seenKnownKeys === knownKesyCount ? "" : ","}${newLine}`; + if (configurations.compilerOptions[option.name]) { + result += `${tab}${tab}"${option.name}": ${JSON.stringify(configurations.compilerOptions[option.name])}${(seenKnownKeys += 1) === knownKesyCount ? "" : ","}${newLine}`; } else { result += `${tab}${tab}// "${option.name}": ${JSON.stringify(getDefaultValueForOption(option))},${newLine}`; @@ -1606,4 +1606,4 @@ namespace ts { function caseInsensitiveKeyMapper(key: string) { return key.toLowerCase(); } -} +} \ No newline at end of file diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 589c196d13..7dee8bca9c 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3385,7 +3385,7 @@ paramType?: DiagnosticMessage; // The name to be used for a non-boolean option's parameter isTSConfigOnly?: boolean; // True if option can only be specified via tsconfig.json file isCommandLineOnly?: boolean; - showInSimplifiedHelpView?:boolean; + showInSimplifiedHelpView?: boolean; category?: DiagnosticMessage; } From 096c15b0dedeae3cc4cebf28748bb5f70b5e848c Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Fri, 17 Feb 2017 12:58:17 -0800 Subject: [PATCH 014/164] Defer get JSX.Element type allow null to be returned in SFC --- src/compiler/checker.ts | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 12b55aa818..669a2e0f7c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -278,6 +278,8 @@ namespace ts { let deferredGlobalAsyncIterableIteratorType: GenericType; let deferredGlobalTemplateStringsArrayType: ObjectType; let deferredJsxElementClassType: Type; + let deferredJsxElementType: Type; + let deferredJsxStatelessElementType: Type; let deferredNodes: Node[]; let deferredUnusedIdentifierNodes: Node[]; @@ -398,7 +400,6 @@ namespace ts { }); const typeofType = createTypeofType(); - let jsxElementType: Type; let _jsxNamespace: string; let _jsxFactoryEntity: EntityName; @@ -12306,12 +12307,12 @@ namespace ts { type.flags & TypeFlags.UnionOrIntersection && !forEach((type).types, t => !isValidSpreadType(t))); } - function checkJsxSelfClosingElement(node: JsxSelfClosingElement) { + function checkJsxSelfClosingElement(node: JsxSelfClosingElement): Type { checkJsxOpeningLikeElement(node); - return jsxElementType || anyType; + return getJsxGlobalElementType() || anyType; } - function checkJsxElement(node: JsxElement) { + function checkJsxElement(node: JsxElement): Type { // Check attributes checkJsxOpeningLikeElement(node.openingElement); @@ -12338,7 +12339,7 @@ namespace ts { } } - return jsxElementType || anyType; + return getJsxGlobalElementType() || anyType; } /** @@ -12579,13 +12580,14 @@ namespace ts { function defaultTryGetJsxStatelessFunctionAttributesType(openingLikeElement: JsxOpeningLikeElement, elementType: Type, elemInstanceType: Type, elementClassType?: Type): Type { Debug.assert(!(elementType.flags & TypeFlags.Union)); if (!elementClassType || !isTypeAssignableTo(elemInstanceType, elementClassType)) { - if (jsxElementType) { + const jsxStatelessElementType = getJsxGlobalStatelessElementType(); + if (jsxStatelessElementType) { // We don't call getResolvedSignature here because we have already resolve the type of JSX Element. const callSignature = getResolvedJsxStatelessFunctionSignature(openingLikeElement, elementType, /*candidatesOutArray*/ undefined); if (callSignature !== unknownSignature) { const callReturnType = callSignature && getReturnTypeOfSignature(callSignature); let paramType = callReturnType && (callSignature.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(callSignature.parameters[0])); - if (callReturnType && isTypeAssignableTo(callReturnType, jsxElementType)) { + if (callReturnType && isTypeAssignableTo(callReturnType, jsxStatelessElementType)) { // Intersect in JSX.IntrinsicAttributes if it exists const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes); if (intrinsicAttributes !== unknownType) { @@ -12613,7 +12615,8 @@ namespace ts { Debug.assert(!(elementType.flags & TypeFlags.Union)); if (!elementClassType || !isTypeAssignableTo(elemInstanceType, elementClassType)) { // Is this is a stateless function component? See if its single signature's return type is assignable to the JSX Element Type - if (jsxElementType) { + const jsxStatelessElementType = getJsxGlobalStatelessElementType(); + if (jsxStatelessElementType) { // We don't call getResolvedSignature because here we have already resolve the type of JSX Element. const candidatesOutArray: Signature[] = []; getResolvedJsxStatelessFunctionSignature(openingLikeElement, elementType, candidatesOutArray); @@ -12622,7 +12625,7 @@ namespace ts { for (const candidate of candidatesOutArray) { const callReturnType = getReturnTypeOfSignature(candidate); const paramType = callReturnType && (candidate.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(candidate.parameters[0])); - if (callReturnType && isTypeAssignableTo(callReturnType, jsxElementType)) { + if (callReturnType && isTypeAssignableTo(callReturnType, jsxStatelessElementType)) { let shouldBeCandidate = true; for (const attribute of openingLikeElement.attributes.properties) { if (isJsxAttribute(attribute) && @@ -12871,6 +12874,23 @@ namespace ts { return deferredJsxElementClassType; } + function getJsxGlobalElementType(): Type { + if (!deferredJsxElementType) { + deferredJsxElementType = getExportedTypeFromNamespace(JsxNames.JSX, JsxNames.Element); + } + return deferredJsxElementType; + } + + function getJsxGlobalStatelessElementType(): Type { + if (!deferredJsxStatelessElementType) { + const jsxElementType = getJsxGlobalElementType(); + if (jsxElementType){ + deferredJsxStatelessElementType = getUnionType([jsxElementType, nullType]); + } + } + return deferredJsxStatelessElementType; + } + /** * Returns all the properties of the Jsx.IntrinsicElements interface */ @@ -12885,7 +12905,7 @@ namespace ts { error(errorNode, Diagnostics.Cannot_use_JSX_unless_the_jsx_flag_is_provided); } - if (jsxElementType === undefined) { + if (getJsxGlobalElementType() === undefined) { if (compilerOptions.noImplicitAny) { error(errorNode, Diagnostics.JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist); } @@ -21917,7 +21937,6 @@ namespace ts { globalNumberType = getGlobalType("Number", /*arity*/ 0, /*reportErrors*/ true); globalBooleanType = getGlobalType("Boolean", /*arity*/ 0, /*reportErrors*/ true); globalRegExpType = getGlobalType("RegExp", /*arity*/ 0, /*reportErrors*/ true); - jsxElementType = getExportedTypeFromNamespace("JSX", JsxNames.Element); anyArrayType = createArrayType(anyType); autoArrayType = createArrayType(autoType); From fc6eee1a6c694300cf1509a041d21078f53c5632 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Fri, 17 Feb 2017 13:13:26 -0800 Subject: [PATCH 015/164] Add tests and baselines --- tests/baselines/reference/tsxSfcReturnNull.js | 24 +++++++++++++++ .../reference/tsxSfcReturnNull.symbols | 25 ++++++++++++++++ .../reference/tsxSfcReturnNull.types | 30 +++++++++++++++++++ .../tsxSfcReturnNullStrictNullChecks.js | 24 +++++++++++++++ .../tsxSfcReturnNullStrictNullChecks.symbols | 25 ++++++++++++++++ .../tsxSfcReturnNullStrictNullChecks.types | 30 +++++++++++++++++++ ...ReturnUndefinedStrictNullChecks.errors.txt | 20 +++++++++++++ .../tsxSfcReturnUndefinedStrictNullChecks.js | 25 ++++++++++++++++ .../conformance/jsx/tsxSfcReturnNull.tsx | 16 ++++++++++ .../jsx/tsxSfcReturnNullStrictNullChecks.tsx | 17 +++++++++++ .../tsxSfcReturnUndefinedStrictNullChecks.tsx | 17 +++++++++++ 11 files changed, 253 insertions(+) create mode 100644 tests/baselines/reference/tsxSfcReturnNull.js create mode 100644 tests/baselines/reference/tsxSfcReturnNull.symbols create mode 100644 tests/baselines/reference/tsxSfcReturnNull.types create mode 100644 tests/baselines/reference/tsxSfcReturnNullStrictNullChecks.js create mode 100644 tests/baselines/reference/tsxSfcReturnNullStrictNullChecks.symbols create mode 100644 tests/baselines/reference/tsxSfcReturnNullStrictNullChecks.types create mode 100644 tests/baselines/reference/tsxSfcReturnUndefinedStrictNullChecks.errors.txt create mode 100644 tests/baselines/reference/tsxSfcReturnUndefinedStrictNullChecks.js create mode 100644 tests/cases/conformance/jsx/tsxSfcReturnNull.tsx create mode 100644 tests/cases/conformance/jsx/tsxSfcReturnNullStrictNullChecks.tsx create mode 100644 tests/cases/conformance/jsx/tsxSfcReturnUndefinedStrictNullChecks.tsx diff --git a/tests/baselines/reference/tsxSfcReturnNull.js b/tests/baselines/reference/tsxSfcReturnNull.js new file mode 100644 index 0000000000..8a332a7057 --- /dev/null +++ b/tests/baselines/reference/tsxSfcReturnNull.js @@ -0,0 +1,24 @@ +//// [file.tsx] + +import React = require('react'); + +const Foo = (props: any) => null; + +function Greet(x: {name?: string}) { + return null; +} + +const foo = ; +const G = ; + +//// [file.jsx] +define(["require", "exports", "react"], function (require, exports, React) { + "use strict"; + exports.__esModule = true; + var Foo = function (props) { return null; }; + function Greet(x) { + return null; + } + var foo = ; + var G = ; +}); diff --git a/tests/baselines/reference/tsxSfcReturnNull.symbols b/tests/baselines/reference/tsxSfcReturnNull.symbols new file mode 100644 index 0000000000..483b7db6c5 --- /dev/null +++ b/tests/baselines/reference/tsxSfcReturnNull.symbols @@ -0,0 +1,25 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +const Foo = (props: any) => null; +>Foo : Symbol(Foo, Decl(file.tsx, 3, 5)) +>props : Symbol(props, Decl(file.tsx, 3, 13)) + +function Greet(x: {name?: string}) { +>Greet : Symbol(Greet, Decl(file.tsx, 3, 33)) +>x : Symbol(x, Decl(file.tsx, 5, 15)) +>name : Symbol(name, Decl(file.tsx, 5, 19)) + + return null; +} + +const foo = ; +>foo : Symbol(foo, Decl(file.tsx, 9, 5)) +>Foo : Symbol(Foo, Decl(file.tsx, 3, 5)) + +const G = ; +>G : Symbol(G, Decl(file.tsx, 10, 5)) +>Greet : Symbol(Greet, Decl(file.tsx, 3, 33)) + diff --git a/tests/baselines/reference/tsxSfcReturnNull.types b/tests/baselines/reference/tsxSfcReturnNull.types new file mode 100644 index 0000000000..edc346b03e --- /dev/null +++ b/tests/baselines/reference/tsxSfcReturnNull.types @@ -0,0 +1,30 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : typeof React + +const Foo = (props: any) => null; +>Foo : (props: any) => any +>(props: any) => null : (props: any) => any +>props : any +>null : null + +function Greet(x: {name?: string}) { +>Greet : (x: { name?: string; }) => any +>x : { name?: string; } +>name : string + + return null; +>null : null +} + +const foo = ; +>foo : JSX.Element +> : JSX.Element +>Foo : (props: any) => any + +const G = ; +>G : JSX.Element +> : JSX.Element +>Greet : (x: { name?: string; }) => any + diff --git a/tests/baselines/reference/tsxSfcReturnNullStrictNullChecks.js b/tests/baselines/reference/tsxSfcReturnNullStrictNullChecks.js new file mode 100644 index 0000000000..8a332a7057 --- /dev/null +++ b/tests/baselines/reference/tsxSfcReturnNullStrictNullChecks.js @@ -0,0 +1,24 @@ +//// [file.tsx] + +import React = require('react'); + +const Foo = (props: any) => null; + +function Greet(x: {name?: string}) { + return null; +} + +const foo = ; +const G = ; + +//// [file.jsx] +define(["require", "exports", "react"], function (require, exports, React) { + "use strict"; + exports.__esModule = true; + var Foo = function (props) { return null; }; + function Greet(x) { + return null; + } + var foo = ; + var G = ; +}); diff --git a/tests/baselines/reference/tsxSfcReturnNullStrictNullChecks.symbols b/tests/baselines/reference/tsxSfcReturnNullStrictNullChecks.symbols new file mode 100644 index 0000000000..483b7db6c5 --- /dev/null +++ b/tests/baselines/reference/tsxSfcReturnNullStrictNullChecks.symbols @@ -0,0 +1,25 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +const Foo = (props: any) => null; +>Foo : Symbol(Foo, Decl(file.tsx, 3, 5)) +>props : Symbol(props, Decl(file.tsx, 3, 13)) + +function Greet(x: {name?: string}) { +>Greet : Symbol(Greet, Decl(file.tsx, 3, 33)) +>x : Symbol(x, Decl(file.tsx, 5, 15)) +>name : Symbol(name, Decl(file.tsx, 5, 19)) + + return null; +} + +const foo = ; +>foo : Symbol(foo, Decl(file.tsx, 9, 5)) +>Foo : Symbol(Foo, Decl(file.tsx, 3, 5)) + +const G = ; +>G : Symbol(G, Decl(file.tsx, 10, 5)) +>Greet : Symbol(Greet, Decl(file.tsx, 3, 33)) + diff --git a/tests/baselines/reference/tsxSfcReturnNullStrictNullChecks.types b/tests/baselines/reference/tsxSfcReturnNullStrictNullChecks.types new file mode 100644 index 0000000000..5268592b8d --- /dev/null +++ b/tests/baselines/reference/tsxSfcReturnNullStrictNullChecks.types @@ -0,0 +1,30 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : typeof React + +const Foo = (props: any) => null; +>Foo : (props: any) => null +>(props: any) => null : (props: any) => null +>props : any +>null : null + +function Greet(x: {name?: string}) { +>Greet : (x: { name?: string | undefined; }) => null +>x : { name?: string | undefined; } +>name : string | undefined + + return null; +>null : null +} + +const foo = ; +>foo : JSX.Element +> : JSX.Element +>Foo : (props: any) => null + +const G = ; +>G : JSX.Element +> : JSX.Element +>Greet : (x: { name?: string | undefined; }) => null + diff --git a/tests/baselines/reference/tsxSfcReturnUndefinedStrictNullChecks.errors.txt b/tests/baselines/reference/tsxSfcReturnUndefinedStrictNullChecks.errors.txt new file mode 100644 index 0000000000..127eb4b0d4 --- /dev/null +++ b/tests/baselines/reference/tsxSfcReturnUndefinedStrictNullChecks.errors.txt @@ -0,0 +1,20 @@ +tests/cases/conformance/jsx/file.tsx(10,13): error TS2605: JSX element type 'undefined' is not a constructor function for JSX elements. +tests/cases/conformance/jsx/file.tsx(11,11): error TS2605: JSX element type 'undefined' is not a constructor function for JSX elements. + + +==== tests/cases/conformance/jsx/file.tsx (2 errors) ==== + + import React = require('react'); + + const Foo = (props: any) => undefined; + function Greet(x: {name?: string}) { + return undefined; + } + + // Error + const foo = ; + ~~~~~~~ +!!! error TS2605: JSX element type 'undefined' is not a constructor function for JSX elements. + const G = ; + ~~~~~~~~~ +!!! error TS2605: JSX element type 'undefined' is not a constructor function for JSX elements. \ No newline at end of file diff --git a/tests/baselines/reference/tsxSfcReturnUndefinedStrictNullChecks.js b/tests/baselines/reference/tsxSfcReturnUndefinedStrictNullChecks.js new file mode 100644 index 0000000000..0fcaa2f168 --- /dev/null +++ b/tests/baselines/reference/tsxSfcReturnUndefinedStrictNullChecks.js @@ -0,0 +1,25 @@ +//// [file.tsx] + +import React = require('react'); + +const Foo = (props: any) => undefined; +function Greet(x: {name?: string}) { + return undefined; +} + +// Error +const foo = ; +const G = ; + +//// [file.jsx] +define(["require", "exports", "react"], function (require, exports, React) { + "use strict"; + exports.__esModule = true; + var Foo = function (props) { return undefined; }; + function Greet(x) { + return undefined; + } + // Error + var foo = ; + var G = ; +}); diff --git a/tests/cases/conformance/jsx/tsxSfcReturnNull.tsx b/tests/cases/conformance/jsx/tsxSfcReturnNull.tsx new file mode 100644 index 0000000000..436b361eaf --- /dev/null +++ b/tests/cases/conformance/jsx/tsxSfcReturnNull.tsx @@ -0,0 +1,16 @@ +// @filename: file.tsx +// @jsx: preserve +// @module: amd +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +const Foo = (props: any) => null; + +function Greet(x: {name?: string}) { + return null; +} + +const foo = ; +const G = ; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxSfcReturnNullStrictNullChecks.tsx b/tests/cases/conformance/jsx/tsxSfcReturnNullStrictNullChecks.tsx new file mode 100644 index 0000000000..cbc7218698 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxSfcReturnNullStrictNullChecks.tsx @@ -0,0 +1,17 @@ +// @filename: file.tsx +// @jsx: preserve +// @module: amd +// @noLib: true +// @strictNullChecks: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +const Foo = (props: any) => null; + +function Greet(x: {name?: string}) { + return null; +} + +const foo = ; +const G = ; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxSfcReturnUndefinedStrictNullChecks.tsx b/tests/cases/conformance/jsx/tsxSfcReturnUndefinedStrictNullChecks.tsx new file mode 100644 index 0000000000..cb0c6444e7 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxSfcReturnUndefinedStrictNullChecks.tsx @@ -0,0 +1,17 @@ +// @filename: file.tsx +// @jsx: preserve +// @module: amd +// @noLib: true +// @strictNullChecks: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +const Foo = (props: any) => undefined; +function Greet(x: {name?: string}) { + return undefined; +} + +// Error +const foo = ; +const G = ; \ No newline at end of file From 9ca08a4efafec79abf16043de3cd4b92fda6ad54 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Fri, 17 Feb 2017 13:50:05 -0800 Subject: [PATCH 016/164] Fix linting --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 669a2e0f7c..bc39712f2f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12884,7 +12884,7 @@ namespace ts { function getJsxGlobalStatelessElementType(): Type { if (!deferredJsxStatelessElementType) { const jsxElementType = getJsxGlobalElementType(); - if (jsxElementType){ + if (jsxElementType) { deferredJsxStatelessElementType = getUnionType([jsxElementType, nullType]); } } From 3f198e6751892a531d20524300bba34544c02bf2 Mon Sep 17 00:00:00 2001 From: Jason Ramsay Date: Fri, 17 Feb 2017 13:54:07 -0800 Subject: [PATCH 017/164] Adding cancellation token checks for lower priority tasks --- .../unittests/tsserverProjectSystem.ts | 82 +++++++ src/services/navigationBar.ts | 232 +++++++++--------- src/services/outliningElementsCollector.ts | 4 +- src/services/services.ts | 6 +- 4 files changed, 207 insertions(+), 117 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 92ec0b4ee0..01e484fd4b 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -3460,6 +3460,88 @@ namespace ts.projectSystem { return JSON.parse(server.extractMessage(host.getOutput()[n])); } }); + it("Lower priority tasks are cancellable", () => { + const f1 = { + path: "/a/app.ts", + content: `{ let x = 1; } var foo = "foo"; var bar = "bar"; var fooBar = "fooBar";` + }; + const config = { + path: "/a/tsconfig.json", + content: JSON.stringify({ + compilerOptions: {} + }) + }; + + let requestToCancel = -1; + let isCancellationRequestedCount = 0; + let cancelAfterRequest = 3; + let operationCanceledExceptionThrown = false; + const cancellationToken: server.ServerCancellationToken = (function () { + let currentId: number; + return { + setRequest(requestId) { + currentId = requestId; + }, + resetRequest(requestId) { + assert.equal(requestId, currentId, "unexpected request id in cancellation") + currentId = undefined; + }, + isCancellationRequested() { + isCancellationRequestedCount++; + return requestToCancel === currentId && isCancellationRequestedCount >= cancelAfterRequest; + } + } + })(); + const host = createServerHost([f1, config]); + const session = createSession(host, /*typingsInstaller*/ undefined, () => { }, cancellationToken); + { + session.executeCommandSeq({ + command: "open", + arguments: { file: f1.path } + }); + + // send navbar request (normal priority) + session.executeCommandSeq({ + command: "navbar", + arguments: { file: f1.path } + }); + + // ensure the nav bar request can be canceled + verifyExecuteCommandSeqIsCancellable({ + command: "navbar", + arguments: { file: f1.path } + }); + + // send outlining spans request (normal priority) + session.executeCommandSeq({ + command: "outliningSpans", + arguments: { file: f1.path } + }); + + // ensure the outlining spans request can be canceled + verifyExecuteCommandSeqIsCancellable({ + command: "outliningSpans", + arguments: { file: f1.path } + }); + } + + function verifyExecuteCommandSeqIsCancellable(request: Partial) { + // Set the next request to be cancellable + // The cancellation token will cancel the request the third time + // isCancellationRequested() is called. + requestToCancel = session.getNextSeq(); + isCancellationRequestedCount = 0; + operationCanceledExceptionThrown = false; + + try { + session.executeCommandSeq(request); + } catch (e) { + assert(e instanceof OperationCanceledException); + operationCanceledExceptionThrown = true; + } + assert(operationCanceledExceptionThrown); + } + }); }); describe("maxNodeModuleJsDepth for inferred projects", () => { diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 25059d1f57..37b6bedbd5 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -14,16 +14,16 @@ namespace ts.NavigationBar { indent: number; // # of parents } - export function getNavigationBarItems(sourceFile: SourceFile): NavigationBarItem[] { + export function getNavigationBarItems(sourceFile: SourceFile, cancellationToken: CancellationToken): NavigationBarItem[] { curSourceFile = sourceFile; - const result = map(topLevelItems(rootNavigationBarNode(sourceFile)), convertToTopLevelItem); + const result = map(topLevelItems(rootNavigationBarNode(sourceFile, cancellationToken)), convertToTopLevelItem); curSourceFile = undefined; return result; } - export function getNavigationTree(sourceFile: SourceFile): NavigationTree { + export function getNavigationTree(sourceFile: SourceFile, cancellationToken: CancellationToken): NavigationTree { curSourceFile = sourceFile; - const result = convertToTree(rootNavigationBarNode(sourceFile)); + const result = convertToTree(rootNavigationBarNode(sourceFile, cancellationToken)); curSourceFile = undefined; return result; } @@ -55,12 +55,12 @@ namespace ts.NavigationBar { const parentsStack: NavigationBarNode[] = []; let parent: NavigationBarNode; - function rootNavigationBarNode(sourceFile: SourceFile): NavigationBarNode { + function rootNavigationBarNode(sourceFile: SourceFile, cancellationToken: CancellationToken): NavigationBarNode { Debug.assert(!parentsStack.length); const root: NavigationBarNode = { node: sourceFile, additionalNodes: undefined, parent: undefined, children: undefined, indent: 0 }; parent = root; for (const statement of sourceFile.statements) { - addChildrenRecursively(statement); + addChildrenRecursively(statement, cancellationToken); } endNode(); Debug.assert(!parent && !parentsStack.length); @@ -103,138 +103,144 @@ namespace ts.NavigationBar { parent = parentsStack.pop(); } - function addNodeWithRecursiveChild(node: Node, child: Node): void { + function addNodeWithRecursiveChild(node: Node, child: Node, addChildrenRecursively: (node: Node) => void): void { startNode(node); addChildrenRecursively(child); endNode(); } /** Look for navigation bar items in node's subtree, adding them to the current `parent`. */ - function addChildrenRecursively(node: Node): void { - if (!node || isToken(node)) { - return; - } + function addChildrenRecursively(node: Node, cancellationToken: CancellationToken): void { + function addChildrenRecursively(node: Node): void { + cancellationToken.throwIfCancellationRequested(); - switch (node.kind) { - case SyntaxKind.Constructor: - // Get parameter properties, and treat them as being on the *same* level as the constructor, not under it. - const ctr = node; - addNodeWithRecursiveChild(ctr, ctr.body); + if (!node || isToken(node)) { + return; + } - // Parameter properties are children of the class, not the constructor. - for (const param of ctr.parameters) { - if (isParameterPropertyDeclaration(param)) { - addLeafNode(param); + switch (node.kind) { + case SyntaxKind.Constructor: + // Get parameter properties, and treat them as being on the *same* level as the constructor, not under it. + const ctr = node; + addNodeWithRecursiveChild(ctr, ctr.body, addChildrenRecursively); + + // Parameter properties are children of the class, not the constructor. + for (const param of ctr.parameters) { + if (isParameterPropertyDeclaration(param)) { + addLeafNode(param); + } } - } - break; + break; - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.MethodSignature: - if (!hasDynamicName((node))) { - addNodeWithRecursiveChild(node, (node).body); - } - break; + case SyntaxKind.MethodDeclaration: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + case SyntaxKind.MethodSignature: + if (!hasDynamicName((node))) { + addNodeWithRecursiveChild(node, (node).body, addChildrenRecursively); + } + break; - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - if (!hasDynamicName((node))) { - addLeafNode(node); - } - break; + case SyntaxKind.PropertyDeclaration: + case SyntaxKind.PropertySignature: + if (!hasDynamicName((node))) { + addLeafNode(node); + } + break; - case SyntaxKind.ImportClause: - const importClause = node; - // Handle default import case e.g.: - // import d from "mod"; - if (importClause.name) { - addLeafNode(importClause); - } + case SyntaxKind.ImportClause: + const importClause = node; + // Handle default import case e.g.: + // import d from "mod"; + if (importClause.name) { + addLeafNode(importClause); + } - // Handle named bindings in imports e.g.: - // import * as NS from "mod"; - // import {a, b as B} from "mod"; - const {namedBindings} = importClause; - if (namedBindings) { - if (namedBindings.kind === SyntaxKind.NamespaceImport) { - addLeafNode(namedBindings); + // Handle named bindings in imports e.g.: + // import * as NS from "mod"; + // import {a, b as B} from "mod"; + const {namedBindings} = importClause; + if (namedBindings) { + if (namedBindings.kind === SyntaxKind.NamespaceImport) { + addLeafNode(namedBindings); + } + else { + for (const element of (namedBindings).elements) { + addLeafNode(element); + } + } + } + break; + + case SyntaxKind.BindingElement: + case SyntaxKind.VariableDeclaration: + const decl = node; + const name = decl.name; + if (isBindingPattern(name)) { + addChildrenRecursively(name); + } + else if (decl.initializer && isFunctionOrClassExpression(decl.initializer)) { + // For `const x = function() {}`, just use the function node, not the const. + addChildrenRecursively(decl.initializer); } else { - for (const element of (namedBindings).elements) { - addLeafNode(element); + addNodeWithRecursiveChild(decl, decl.initializer, addChildrenRecursively); + } + break; + + case SyntaxKind.ArrowFunction: + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.FunctionExpression: + addNodeWithRecursiveChild(node, (node).body, addChildrenRecursively); + break; + + case SyntaxKind.EnumDeclaration: + startNode(node); + for (const member of (node).members) { + if (!isComputedProperty(member)) { + addLeafNode(member); } } - } - break; + endNode(); + break; - case SyntaxKind.BindingElement: - case SyntaxKind.VariableDeclaration: - const decl = node; - const name = decl.name; - if (isBindingPattern(name)) { - addChildrenRecursively(name); - } - else if (decl.initializer && isFunctionOrClassExpression(decl.initializer)) { - // For `const x = function() {}`, just use the function node, not the const. - addChildrenRecursively(decl.initializer); - } - else { - addNodeWithRecursiveChild(decl, decl.initializer); - } - break; - - case SyntaxKind.ArrowFunction: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - addNodeWithRecursiveChild(node, (node).body); - break; - - case SyntaxKind.EnumDeclaration: - startNode(node); - for (const member of (node).members) { - if (!isComputedProperty(member)) { - addLeafNode(member); + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: + case SyntaxKind.InterfaceDeclaration: + startNode(node); + for (const member of (node).members) { + addChildrenRecursively(member); } - } - endNode(); - break; + endNode(); + break; - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - case SyntaxKind.InterfaceDeclaration: - startNode(node); - for (const member of (node).members) { - addChildrenRecursively(member); - } - endNode(); - break; + case SyntaxKind.ModuleDeclaration: + addNodeWithRecursiveChild(node, getInteriorModule(node).body, addChildrenRecursively); + break; - case SyntaxKind.ModuleDeclaration: - addNodeWithRecursiveChild(node, getInteriorModule(node).body); - break; + case SyntaxKind.ExportSpecifier: + case SyntaxKind.ImportEqualsDeclaration: + case SyntaxKind.IndexSignature: + case SyntaxKind.CallSignature: + case SyntaxKind.ConstructSignature: + case SyntaxKind.TypeAliasDeclaration: + addLeafNode(node); + break; - case SyntaxKind.ExportSpecifier: - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.IndexSignature: - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.TypeAliasDeclaration: - addLeafNode(node); - break; - - default: - forEach(node.jsDoc, jsDoc => { - forEach(jsDoc.tags, tag => { - if (tag.kind === SyntaxKind.JSDocTypedefTag) { - addLeafNode(tag); - } + default: + forEach(node.jsDoc, jsDoc => { + forEach(jsDoc.tags, tag => { + if (tag.kind === SyntaxKind.JSDocTypedefTag) { + addLeafNode(tag); + } + }); }); - }); - forEachChild(node, addChildrenRecursively); + forEachChild(node, addChildrenRecursively); + } } + + addChildrenRecursively(node); } /** Merge declarations of the same kind. */ diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts index 2ad20a7ed0..96a7c9a3c4 100644 --- a/src/services/outliningElementsCollector.ts +++ b/src/services/outliningElementsCollector.ts @@ -1,6 +1,6 @@ /* @internal */ namespace ts.OutliningElementsCollector { - export function collectElements(sourceFile: SourceFile): OutliningSpan[] { + export function collectElements(sourceFile: SourceFile, cancellationToken: CancellationToken): OutliningSpan[] { const elements: OutliningSpan[] = []; const collapseText = "..."; @@ -38,6 +38,7 @@ namespace ts.OutliningElementsCollector { let singleLineCommentCount = 0; for (const currentComment of comments) { + cancellationToken.throwIfCancellationRequested(); // For single line comments, combine consecutive ones (2 or more) into // a single span from the start of the first till the end of the last @@ -84,6 +85,7 @@ namespace ts.OutliningElementsCollector { let depth = 0; const maxDepth = 20; function walk(n: Node): void { + cancellationToken.throwIfCancellationRequested(); if (depth > maxDepth) { return; } diff --git a/src/services/services.ts b/src/services/services.ts index c1b719d347..cef307eb8f 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1541,11 +1541,11 @@ namespace ts { } function getNavigationBarItems(fileName: string): NavigationBarItem[] { - return NavigationBar.getNavigationBarItems(syntaxTreeCache.getCurrentSourceFile(fileName)); + return NavigationBar.getNavigationBarItems(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken); } function getNavigationTree(fileName: string): NavigationTree { - return NavigationBar.getNavigationTree(syntaxTreeCache.getCurrentSourceFile(fileName)); + return NavigationBar.getNavigationTree(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken); } function isTsOrTsxFile(fileName: string): boolean { @@ -1584,7 +1584,7 @@ namespace ts { function getOutliningSpans(fileName: string): OutliningSpan[] { // doesn't use compiler - no need to synchronize with host const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - return OutliningElementsCollector.collectElements(sourceFile); + return OutliningElementsCollector.collectElements(sourceFile, cancellationToken); } function getBraceMatchingAtPosition(fileName: string, position: number) { From 51966076d4ee5f76752053ec89aa3c79cd1381f7 Mon Sep 17 00:00:00 2001 From: Herrington Darkholme Date: Tue, 21 Feb 2017 11:52:12 +0800 Subject: [PATCH 018/164] fix #14187, forIn should allow non primitive object as right hand side --- src/compiler/checker.ts | 4 ++-- .../reference/nonPrimitiveIndexingWithForIn.js | 13 +++++++++++++ .../nonPrimitiveIndexingWithForIn.symbols | 14 ++++++++++++++ .../reference/nonPrimitiveIndexingWithForIn.types | 15 +++++++++++++++ ...itiveIndexingWithForInNoImplicitAny.errors.txt | 12 ++++++++++++ .../nonPrimitiveIndexingWithForInNoImplicitAny.js | 13 +++++++++++++ .../nonPrimitiveIndexingWithForInSupressError.js | 13 +++++++++++++ ...PrimitiveIndexingWithForInSupressError.symbols | 14 ++++++++++++++ ...onPrimitiveIndexingWithForInSupressError.types | 15 +++++++++++++++ .../nonPrimitive/nonPrimitiveIndexingWithForIn.ts | 5 +++++ .../nonPrimitiveIndexingWithForInNoImplicitAny.ts | 6 ++++++ .../nonPrimitiveIndexingWithForInSupressError.ts | 7 +++++++ 12 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/nonPrimitiveIndexingWithForIn.js create mode 100644 tests/baselines/reference/nonPrimitiveIndexingWithForIn.symbols create mode 100644 tests/baselines/reference/nonPrimitiveIndexingWithForIn.types create mode 100644 tests/baselines/reference/nonPrimitiveIndexingWithForInNoImplicitAny.errors.txt create mode 100644 tests/baselines/reference/nonPrimitiveIndexingWithForInNoImplicitAny.js create mode 100644 tests/baselines/reference/nonPrimitiveIndexingWithForInSupressError.js create mode 100644 tests/baselines/reference/nonPrimitiveIndexingWithForInSupressError.symbols create mode 100644 tests/baselines/reference/nonPrimitiveIndexingWithForInSupressError.types create mode 100644 tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForIn.ts create mode 100644 tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInNoImplicitAny.ts create mode 100644 tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInSupressError.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 12b55aa818..1178276fc9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1,4 +1,4 @@ -/// +/// /// /* @internal */ @@ -18606,7 +18606,7 @@ namespace ts { // unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved // in this case error about missing name is already reported - do not report extra one - if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeVariable)) { + if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeVariable | TypeFlags.NonPrimitive)) { error(node.expression, Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter); } diff --git a/tests/baselines/reference/nonPrimitiveIndexingWithForIn.js b/tests/baselines/reference/nonPrimitiveIndexingWithForIn.js new file mode 100644 index 0000000000..c5f4319c74 --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveIndexingWithForIn.js @@ -0,0 +1,13 @@ +//// [nonPrimitiveIndexingWithForIn.ts] +var a: object; + +for (var key in a) { + var value = a[key]; +} + + +//// [nonPrimitiveIndexingWithForIn.js] +var a; +for (var key in a) { + var value = a[key]; +} diff --git a/tests/baselines/reference/nonPrimitiveIndexingWithForIn.symbols b/tests/baselines/reference/nonPrimitiveIndexingWithForIn.symbols new file mode 100644 index 0000000000..3cb4126954 --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveIndexingWithForIn.symbols @@ -0,0 +1,14 @@ +=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForIn.ts === +var a: object; +>a : Symbol(a, Decl(nonPrimitiveIndexingWithForIn.ts, 0, 3)) + +for (var key in a) { +>key : Symbol(key, Decl(nonPrimitiveIndexingWithForIn.ts, 2, 8)) +>a : Symbol(a, Decl(nonPrimitiveIndexingWithForIn.ts, 0, 3)) + + var value = a[key]; +>value : Symbol(value, Decl(nonPrimitiveIndexingWithForIn.ts, 3, 7)) +>a : Symbol(a, Decl(nonPrimitiveIndexingWithForIn.ts, 0, 3)) +>key : Symbol(key, Decl(nonPrimitiveIndexingWithForIn.ts, 2, 8)) +} + diff --git a/tests/baselines/reference/nonPrimitiveIndexingWithForIn.types b/tests/baselines/reference/nonPrimitiveIndexingWithForIn.types new file mode 100644 index 0000000000..44e2b3f4d5 --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveIndexingWithForIn.types @@ -0,0 +1,15 @@ +=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForIn.ts === +var a: object; +>a : object + +for (var key in a) { +>key : string +>a : object + + var value = a[key]; +>value : any +>a[key] : any +>a : object +>key : string +} + diff --git a/tests/baselines/reference/nonPrimitiveIndexingWithForInNoImplicitAny.errors.txt b/tests/baselines/reference/nonPrimitiveIndexingWithForInNoImplicitAny.errors.txt new file mode 100644 index 0000000000..f7f2ee3db1 --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveIndexingWithForInNoImplicitAny.errors.txt @@ -0,0 +1,12 @@ +tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInNoImplicitAny.ts(4,17): error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature. + + +==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInNoImplicitAny.ts (1 errors) ==== + var a: object; + + for (var key in a) { + var value = a[key]; // error + ~~~~~~ +!!! error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature. + } + \ No newline at end of file diff --git a/tests/baselines/reference/nonPrimitiveIndexingWithForInNoImplicitAny.js b/tests/baselines/reference/nonPrimitiveIndexingWithForInNoImplicitAny.js new file mode 100644 index 0000000000..e105e5ba9b --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveIndexingWithForInNoImplicitAny.js @@ -0,0 +1,13 @@ +//// [nonPrimitiveIndexingWithForInNoImplicitAny.ts] +var a: object; + +for (var key in a) { + var value = a[key]; // error +} + + +//// [nonPrimitiveIndexingWithForInNoImplicitAny.js] +var a; +for (var key in a) { + var value = a[key]; // error +} diff --git a/tests/baselines/reference/nonPrimitiveIndexingWithForInSupressError.js b/tests/baselines/reference/nonPrimitiveIndexingWithForInSupressError.js new file mode 100644 index 0000000000..ce575b2a4d --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveIndexingWithForInSupressError.js @@ -0,0 +1,13 @@ +//// [nonPrimitiveIndexingWithForInSupressError.ts] +var a: object; + +for (var key in a) { + var value = a[key]; +} + + +//// [nonPrimitiveIndexingWithForInSupressError.js] +var a; +for (var key in a) { + var value = a[key]; +} diff --git a/tests/baselines/reference/nonPrimitiveIndexingWithForInSupressError.symbols b/tests/baselines/reference/nonPrimitiveIndexingWithForInSupressError.symbols new file mode 100644 index 0000000000..4e52e66b1c --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveIndexingWithForInSupressError.symbols @@ -0,0 +1,14 @@ +=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInSupressError.ts === +var a: object; +>a : Symbol(a, Decl(nonPrimitiveIndexingWithForInSupressError.ts, 0, 3)) + +for (var key in a) { +>key : Symbol(key, Decl(nonPrimitiveIndexingWithForInSupressError.ts, 2, 8)) +>a : Symbol(a, Decl(nonPrimitiveIndexingWithForInSupressError.ts, 0, 3)) + + var value = a[key]; +>value : Symbol(value, Decl(nonPrimitiveIndexingWithForInSupressError.ts, 3, 7)) +>a : Symbol(a, Decl(nonPrimitiveIndexingWithForInSupressError.ts, 0, 3)) +>key : Symbol(key, Decl(nonPrimitiveIndexingWithForInSupressError.ts, 2, 8)) +} + diff --git a/tests/baselines/reference/nonPrimitiveIndexingWithForInSupressError.types b/tests/baselines/reference/nonPrimitiveIndexingWithForInSupressError.types new file mode 100644 index 0000000000..3fafa40b59 --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveIndexingWithForInSupressError.types @@ -0,0 +1,15 @@ +=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInSupressError.ts === +var a: object; +>a : object + +for (var key in a) { +>key : string +>a : object + + var value = a[key]; +>value : any +>a[key] : any +>a : object +>key : string +} + diff --git a/tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForIn.ts b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForIn.ts new file mode 100644 index 0000000000..2ec8cf83cb --- /dev/null +++ b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForIn.ts @@ -0,0 +1,5 @@ +var a: object; + +for (var key in a) { + var value = a[key]; +} diff --git a/tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInNoImplicitAny.ts b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInNoImplicitAny.ts new file mode 100644 index 0000000000..1050cdea49 --- /dev/null +++ b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInNoImplicitAny.ts @@ -0,0 +1,6 @@ +// @noImplicitAny: true +var a: object; + +for (var key in a) { + var value = a[key]; // error +} diff --git a/tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInSupressError.ts b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInSupressError.ts new file mode 100644 index 0000000000..3f63faee60 --- /dev/null +++ b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInSupressError.ts @@ -0,0 +1,7 @@ +// @noImplicitAny: true +// @suppressImplicitAnyIndexErrors: true +var a: object; + +for (var key in a) { + var value = a[key]; +} From f55167e5658f92061b767e4cee839833a022d327 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Wed, 22 Feb 2017 10:23:47 -0800 Subject: [PATCH 019/164] Collect type from return statment in generator function --- src/compiler/checker.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 12b55aa818..56306fb772 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14963,10 +14963,12 @@ namespace ts { } } else { - let types: Type[]; + let yieldTypes: Type[]; + let returnTypes: Type[]; if (functionFlags & FunctionFlags.Generator) { // Generator or AsyncGenerator function - types = checkAndAggregateYieldOperandTypes(func, contextualMapper); - if (types.length === 0) { + yieldTypes = checkAndAggregateYieldOperandTypes(func, contextualMapper); + returnTypes = checkAndAggregateReturnExpressionTypes(func, contextualMapper); + if (yieldTypes.length === 0 && (!returnTypes || returnTypes.length === 0)) { const iterableIteratorAny = functionFlags & FunctionFlags.Async ? createAsyncIterableIteratorType(anyType) // AsyncGenerator function : createIterableIteratorType(anyType); // Generator function @@ -14978,14 +14980,14 @@ namespace ts { } } else { - types = checkAndAggregateReturnExpressionTypes(func, contextualMapper); - if (!types) { + returnTypes = checkAndAggregateReturnExpressionTypes(func, contextualMapper); + if (!returnTypes) { // For an async function, the return type will not be never, but rather a Promise for never. return functionFlags & FunctionFlags.Async ? createPromiseReturnType(func, neverType) // Async function : neverType; // Normal function } - if (types.length === 0) { + if (returnTypes.length === 0) { // For an async function, the return type will not be void, but rather a Promise for void. return functionFlags & FunctionFlags.Async ? createPromiseReturnType(func, voidType) // Async function @@ -14993,7 +14995,7 @@ namespace ts { } } // Return a union of the return expression types. - type = getUnionType(types, /*subtypeReduction*/ true); + type = getUnionType(yieldTypes ? yieldTypes.concat(returnTypes) : returnTypes, /*subtypeReduction*/ true); if (functionFlags & FunctionFlags.Generator) { // AsyncGenerator function or Generator function type = functionFlags & FunctionFlags.Async From 43cb2f56460de3d3883a2e8a39eb934de2d6c566 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Wed, 22 Feb 2017 10:24:00 -0800 Subject: [PATCH 020/164] Add tests --- .../yieldExpressions/generatorTypeCheck62.ts | 40 +++++++++++++++++ .../yieldExpressions/generatorTypeCheck63.ts | 43 +++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck62.ts create mode 100644 tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts diff --git a/tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck62.ts b/tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck62.ts new file mode 100644 index 0000000000..2f30fe9d90 --- /dev/null +++ b/tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck62.ts @@ -0,0 +1,40 @@ +// @module: commonjs +// @target: es6 +// @noImplicitAny: true + +export interface StrategicState { + lastStrategyApplied?: string; +} + +export function strategy(stratName: string, gen: (a: T) => IterableIterator): (a: T) => IterableIterator { + return function*(state) { + for (const next of gen(state)) { + if (next) { + next.lastStrategyApplied = stratName; + } + yield next; + } + } +} + +export interface Strategy { + (a: T): IterableIterator; +} + +export interface State extends StrategicState { + foo: number; +} + +export const Nothing1: Strategy = strategy("Nothing", function*(state: State) { + return state; +}); + +export const Nothing2: Strategy = strategy("Nothing", function*(state: State) { + yield state; +}); + +export const Nothing3: Strategy = strategy("Nothing", function* (state: State) { + yield ; + return state; +}); + \ No newline at end of file diff --git a/tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts b/tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts new file mode 100644 index 0000000000..58411e409b --- /dev/null +++ b/tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts @@ -0,0 +1,43 @@ +// @module: commonjs +// @target: es6 +// @noImplicitAny: true + +export interface StrategicState { + lastStrategyApplied?: string; +} + +export function strategy(stratName: string, gen: (a: T) => IterableIterator): (a: T) => IterableIterator { + return function*(state) { + for (const next of gen(state)) { + if (next) { + next.lastStrategyApplied = stratName; + } + yield next; + } + } +} + +export interface Strategy { + (a: T): IterableIterator; +} + +export interface State extends StrategicState { + foo: number; +} + +export const Nothing: Strategy = strategy("Nothing", function* (state: State) { + yield 1; + return state; +}); + +export const Nothing1: Strategy = strategy("Nothing", function* (state: State) { +}); + +export const Nothing2: Strategy = strategy("Nothing", function* (state: State) { + return 1; +}); + +export const Nothing3: Strategy = strategy("Nothing", function* (state: State) { + yield state; + return 1; +}); \ No newline at end of file From 5cc9414839351f673488a4d30181d312a7437d62 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Wed, 22 Feb 2017 10:24:24 -0800 Subject: [PATCH 021/164] Update baselines --- ....asyncGenerators.classMethods.es2015.types | 2 +- ...ter.asyncGenerators.classMethods.es5.types | 2 +- ....asyncGenerators.classMethods.esnext.types | 2 +- ...nerators.functionDeclarations.es2015.types | 2 +- ...cGenerators.functionDeclarations.es5.types | 2 +- ...nerators.functionDeclarations.esnext.types | 2 +- ...enerators.functionExpressions.es2015.types | 4 +- ...ncGenerators.functionExpressions.es5.types | 4 +- ...enerators.functionExpressions.esnext.types | 4 +- ...nerators.objectLiteralMethods.es2015.types | 6 +- ...cGenerators.objectLiteralMethods.es5.types | 6 +- ...nerators.objectLiteralMethods.esnext.types | 6 +- .../reference/generatorTypeCheck14.types | 2 +- .../reference/generatorTypeCheck15.types | 2 +- .../reference/generatorTypeCheck34.types | 2 +- .../reference/generatorTypeCheck62.js | 63 +++++++++ .../reference/generatorTypeCheck62.symbols | 106 +++++++++++++++ .../reference/generatorTypeCheck62.types | 122 ++++++++++++++++++ .../reference/generatorTypeCheck63.errors.txt | 63 +++++++++ .../reference/generatorTypeCheck63.js | 69 ++++++++++ 20 files changed, 447 insertions(+), 24 deletions(-) create mode 100644 tests/baselines/reference/generatorTypeCheck62.js create mode 100644 tests/baselines/reference/generatorTypeCheck62.symbols create mode 100644 tests/baselines/reference/generatorTypeCheck62.types create mode 100644 tests/baselines/reference/generatorTypeCheck63.errors.txt create mode 100644 tests/baselines/reference/generatorTypeCheck63.js diff --git a/tests/baselines/reference/emitter.asyncGenerators.classMethods.es2015.types b/tests/baselines/reference/emitter.asyncGenerators.classMethods.es2015.types index 524f7c9b71..c375fb6f45 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.classMethods.es2015.types +++ b/tests/baselines/reference/emitter.asyncGenerators.classMethods.es2015.types @@ -80,7 +80,7 @@ class C7 { >C7 : C7 async * f() { ->f : () => AsyncIterableIterator +>f : () => AsyncIterableIterator<1> return 1; >1 : 1 diff --git a/tests/baselines/reference/emitter.asyncGenerators.classMethods.es5.types b/tests/baselines/reference/emitter.asyncGenerators.classMethods.es5.types index c20e0d3501..e4be9f80d4 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.classMethods.es5.types +++ b/tests/baselines/reference/emitter.asyncGenerators.classMethods.es5.types @@ -80,7 +80,7 @@ class C7 { >C7 : C7 async * f() { ->f : () => AsyncIterableIterator +>f : () => AsyncIterableIterator<1> return 1; >1 : 1 diff --git a/tests/baselines/reference/emitter.asyncGenerators.classMethods.esnext.types b/tests/baselines/reference/emitter.asyncGenerators.classMethods.esnext.types index b5230006f1..1232130a38 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.classMethods.esnext.types +++ b/tests/baselines/reference/emitter.asyncGenerators.classMethods.esnext.types @@ -80,7 +80,7 @@ class C7 { >C7 : C7 async * f() { ->f : () => AsyncIterableIterator +>f : () => AsyncIterableIterator<1> return 1; >1 : 1 diff --git a/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es2015.types b/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es2015.types index 5d57519d14..0e43463990 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es2015.types +++ b/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es2015.types @@ -53,7 +53,7 @@ async function * f6() { } === tests/cases/conformance/emitter/es2015/asyncGenerators/F7.ts === async function * f7() { ->f7 : () => AsyncIterableIterator +>f7 : () => AsyncIterableIterator<1> return 1; >1 : 1 diff --git a/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es5.types b/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es5.types index 2c3063eca5..9ebd2659ef 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es5.types +++ b/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es5.types @@ -53,7 +53,7 @@ async function * f6() { } === tests/cases/conformance/emitter/es5/asyncGenerators/F7.ts === async function * f7() { ->f7 : () => AsyncIterableIterator +>f7 : () => AsyncIterableIterator<1> return 1; >1 : 1 diff --git a/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.esnext.types b/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.esnext.types index 5eb09901ac..4e61c90322 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.esnext.types +++ b/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.esnext.types @@ -53,7 +53,7 @@ async function * f6() { } === tests/cases/conformance/emitter/esnext/asyncGenerators/F7.ts === async function * f7() { ->f7 : () => AsyncIterableIterator +>f7 : () => AsyncIterableIterator<1> return 1; >1 : 1 diff --git a/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es2015.types b/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es2015.types index ab41ffd9c7..83d65ce524 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es2015.types +++ b/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es2015.types @@ -59,8 +59,8 @@ const f6 = async function * () { } === tests/cases/conformance/emitter/es2015/asyncGenerators/F7.ts === const f7 = async function * () { ->f7 : () => AsyncIterableIterator ->async function * () { return 1;} : () => AsyncIterableIterator +>f7 : () => AsyncIterableIterator<1> +>async function * () { return 1;} : () => AsyncIterableIterator<1> return 1; >1 : 1 diff --git a/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es5.types b/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es5.types index 424f09cf53..7d736b2327 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es5.types +++ b/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es5.types @@ -59,8 +59,8 @@ const f6 = async function * () { } === tests/cases/conformance/emitter/es5/asyncGenerators/F7.ts === const f7 = async function * () { ->f7 : () => AsyncIterableIterator ->async function * () { return 1;} : () => AsyncIterableIterator +>f7 : () => AsyncIterableIterator<1> +>async function * () { return 1;} : () => AsyncIterableIterator<1> return 1; >1 : 1 diff --git a/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.esnext.types b/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.esnext.types index e4559e3ece..6c40f9cebb 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.esnext.types +++ b/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.esnext.types @@ -59,8 +59,8 @@ const f6 = async function * () { } === tests/cases/conformance/emitter/esnext/asyncGenerators/F7.ts === const f7 = async function * () { ->f7 : () => AsyncIterableIterator ->async function * () { return 1;} : () => AsyncIterableIterator +>f7 : () => AsyncIterableIterator<1> +>async function * () { return 1;} : () => AsyncIterableIterator<1> return 1; >1 : 1 diff --git a/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es2015.types b/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es2015.types index 0e89d9a1ca..59c5bcfa16 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es2015.types +++ b/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es2015.types @@ -83,11 +83,11 @@ const o6 = { } === tests/cases/conformance/emitter/es2015/asyncGenerators/O7.ts === const o7 = { ->o7 : { f(): AsyncIterableIterator; } ->{ async * f() { return 1; }} : { f(): AsyncIterableIterator; } +>o7 : { f(): AsyncIterableIterator<1>; } +>{ async * f() { return 1; }} : { f(): AsyncIterableIterator<1>; } async * f() { ->f : () => AsyncIterableIterator +>f : () => AsyncIterableIterator<1> return 1; >1 : 1 diff --git a/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es5.types b/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es5.types index 4c8ae47b6a..3e7ead2f73 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es5.types +++ b/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es5.types @@ -83,11 +83,11 @@ const o6 = { } === tests/cases/conformance/emitter/es5/asyncGenerators/O7.ts === const o7 = { ->o7 : { f(): AsyncIterableIterator; } ->{ async * f() { return 1; }} : { f(): AsyncIterableIterator; } +>o7 : { f(): AsyncIterableIterator<1>; } +>{ async * f() { return 1; }} : { f(): AsyncIterableIterator<1>; } async * f() { ->f : () => AsyncIterableIterator +>f : () => AsyncIterableIterator<1> return 1; >1 : 1 diff --git a/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.esnext.types b/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.esnext.types index 511cd7ec9e..9e5aad8af2 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.esnext.types +++ b/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.esnext.types @@ -83,11 +83,11 @@ const o6 = { } === tests/cases/conformance/emitter/esnext/asyncGenerators/O7.ts === const o7 = { ->o7 : { f(): AsyncIterableIterator; } ->{ async * f() { return 1; }} : { f(): AsyncIterableIterator; } +>o7 : { f(): AsyncIterableIterator<1>; } +>{ async * f() { return 1; }} : { f(): AsyncIterableIterator<1>; } async * f() { ->f : () => AsyncIterableIterator +>f : () => AsyncIterableIterator<1> return 1; >1 : 1 diff --git a/tests/baselines/reference/generatorTypeCheck14.types b/tests/baselines/reference/generatorTypeCheck14.types index 48565fe2be..28401e6856 100644 --- a/tests/baselines/reference/generatorTypeCheck14.types +++ b/tests/baselines/reference/generatorTypeCheck14.types @@ -1,6 +1,6 @@ === tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck14.ts === function* g() { ->g : () => IterableIterator<0> +>g : () => IterableIterator<0 | ""> yield 0; >yield 0 : any diff --git a/tests/baselines/reference/generatorTypeCheck15.types b/tests/baselines/reference/generatorTypeCheck15.types index eb14208009..3851d8e56a 100644 --- a/tests/baselines/reference/generatorTypeCheck15.types +++ b/tests/baselines/reference/generatorTypeCheck15.types @@ -1,6 +1,6 @@ === tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck15.ts === function* g() { ->g : () => IterableIterator +>g : () => IterableIterator<""> return ""; >"" : "" diff --git a/tests/baselines/reference/generatorTypeCheck34.types b/tests/baselines/reference/generatorTypeCheck34.types index 2ca1117721..239c5ff149 100644 --- a/tests/baselines/reference/generatorTypeCheck34.types +++ b/tests/baselines/reference/generatorTypeCheck34.types @@ -7,7 +7,7 @@ function* g() { >0 : 0 function* g2() { ->g2 : () => IterableIterator +>g2 : () => IterableIterator<""> return ""; >"" : "" diff --git a/tests/baselines/reference/generatorTypeCheck62.js b/tests/baselines/reference/generatorTypeCheck62.js new file mode 100644 index 0000000000..3086472221 --- /dev/null +++ b/tests/baselines/reference/generatorTypeCheck62.js @@ -0,0 +1,63 @@ +//// [generatorTypeCheck62.ts] + +export interface StrategicState { + lastStrategyApplied?: string; +} + +export function strategy(stratName: string, gen: (a: T) => IterableIterator): (a: T) => IterableIterator { + return function*(state) { + for (const next of gen(state)) { + if (next) { + next.lastStrategyApplied = stratName; + } + yield next; + } + } +} + +export interface Strategy { + (a: T): IterableIterator; +} + +export interface State extends StrategicState { + foo: number; +} + +export const Nothing1: Strategy = strategy("Nothing", function*(state: State) { + return state; +}); + +export const Nothing2: Strategy = strategy("Nothing", function*(state: State) { + yield state; +}); + +export const Nothing3: Strategy = strategy("Nothing", function* (state: State) { + yield ; + return state; +}); + + +//// [generatorTypeCheck62.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function strategy(stratName, gen) { + return function* (state) { + for (const next of gen(state)) { + if (next) { + next.lastStrategyApplied = stratName; + } + yield next; + } + }; +} +exports.strategy = strategy; +exports.Nothing1 = strategy("Nothing", function* (state) { + return state; +}); +exports.Nothing2 = strategy("Nothing", function* (state) { + yield state; +}); +exports.Nothing3 = strategy("Nothing", function* (state) { + yield; + return state; +}); diff --git a/tests/baselines/reference/generatorTypeCheck62.symbols b/tests/baselines/reference/generatorTypeCheck62.symbols new file mode 100644 index 0000000000..580ab20884 --- /dev/null +++ b/tests/baselines/reference/generatorTypeCheck62.symbols @@ -0,0 +1,106 @@ +=== tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck62.ts === + +export interface StrategicState { +>StrategicState : Symbol(StrategicState, Decl(generatorTypeCheck62.ts, 0, 0)) + + lastStrategyApplied?: string; +>lastStrategyApplied : Symbol(StrategicState.lastStrategyApplied, Decl(generatorTypeCheck62.ts, 1, 33)) +} + +export function strategy(stratName: string, gen: (a: T) => IterableIterator): (a: T) => IterableIterator { +>strategy : Symbol(strategy, Decl(generatorTypeCheck62.ts, 3, 1)) +>T : Symbol(T, Decl(generatorTypeCheck62.ts, 5, 25)) +>StrategicState : Symbol(StrategicState, Decl(generatorTypeCheck62.ts, 0, 0)) +>stratName : Symbol(stratName, Decl(generatorTypeCheck62.ts, 5, 51)) +>gen : Symbol(gen, Decl(generatorTypeCheck62.ts, 5, 69)) +>a : Symbol(a, Decl(generatorTypeCheck62.ts, 5, 76)) +>T : Symbol(T, Decl(generatorTypeCheck62.ts, 5, 25)) +>IterableIterator : Symbol(IterableIterator, Decl(lib.es2015.iterable.d.ts, --, --)) +>T : Symbol(T, Decl(generatorTypeCheck62.ts, 5, 25)) +>a : Symbol(a, Decl(generatorTypeCheck62.ts, 5, 120)) +>T : Symbol(T, Decl(generatorTypeCheck62.ts, 5, 25)) +>IterableIterator : Symbol(IterableIterator, Decl(lib.es2015.iterable.d.ts, --, --)) +>T : Symbol(T, Decl(generatorTypeCheck62.ts, 5, 25)) + + return function*(state) { +>state : Symbol(state, Decl(generatorTypeCheck62.ts, 6, 21)) + + for (const next of gen(state)) { +>next : Symbol(next, Decl(generatorTypeCheck62.ts, 7, 18)) +>gen : Symbol(gen, Decl(generatorTypeCheck62.ts, 5, 69)) +>state : Symbol(state, Decl(generatorTypeCheck62.ts, 6, 21)) + + if (next) { +>next : Symbol(next, Decl(generatorTypeCheck62.ts, 7, 18)) + + next.lastStrategyApplied = stratName; +>next.lastStrategyApplied : Symbol(StrategicState.lastStrategyApplied, Decl(generatorTypeCheck62.ts, 1, 33)) +>next : Symbol(next, Decl(generatorTypeCheck62.ts, 7, 18)) +>lastStrategyApplied : Symbol(StrategicState.lastStrategyApplied, Decl(generatorTypeCheck62.ts, 1, 33)) +>stratName : Symbol(stratName, Decl(generatorTypeCheck62.ts, 5, 51)) + } + yield next; +>next : Symbol(next, Decl(generatorTypeCheck62.ts, 7, 18)) + } + } +} + +export interface Strategy { +>Strategy : Symbol(Strategy, Decl(generatorTypeCheck62.ts, 14, 1)) +>T : Symbol(T, Decl(generatorTypeCheck62.ts, 16, 26)) + + (a: T): IterableIterator; +>a : Symbol(a, Decl(generatorTypeCheck62.ts, 17, 5)) +>T : Symbol(T, Decl(generatorTypeCheck62.ts, 16, 26)) +>IterableIterator : Symbol(IterableIterator, Decl(lib.es2015.iterable.d.ts, --, --)) +>T : Symbol(T, Decl(generatorTypeCheck62.ts, 16, 26)) +} + +export interface State extends StrategicState { +>State : Symbol(State, Decl(generatorTypeCheck62.ts, 18, 1)) +>StrategicState : Symbol(StrategicState, Decl(generatorTypeCheck62.ts, 0, 0)) + + foo: number; +>foo : Symbol(State.foo, Decl(generatorTypeCheck62.ts, 20, 47)) +} + +export const Nothing1: Strategy = strategy("Nothing", function*(state: State) { +>Nothing1 : Symbol(Nothing1, Decl(generatorTypeCheck62.ts, 24, 12)) +>Strategy : Symbol(Strategy, Decl(generatorTypeCheck62.ts, 14, 1)) +>State : Symbol(State, Decl(generatorTypeCheck62.ts, 18, 1)) +>strategy : Symbol(strategy, Decl(generatorTypeCheck62.ts, 3, 1)) +>state : Symbol(state, Decl(generatorTypeCheck62.ts, 24, 71)) +>State : Symbol(State, Decl(generatorTypeCheck62.ts, 18, 1)) + + return state; +>state : Symbol(state, Decl(generatorTypeCheck62.ts, 24, 71)) + +}); + +export const Nothing2: Strategy = strategy("Nothing", function*(state: State) { +>Nothing2 : Symbol(Nothing2, Decl(generatorTypeCheck62.ts, 28, 12)) +>Strategy : Symbol(Strategy, Decl(generatorTypeCheck62.ts, 14, 1)) +>State : Symbol(State, Decl(generatorTypeCheck62.ts, 18, 1)) +>strategy : Symbol(strategy, Decl(generatorTypeCheck62.ts, 3, 1)) +>state : Symbol(state, Decl(generatorTypeCheck62.ts, 28, 71)) +>State : Symbol(State, Decl(generatorTypeCheck62.ts, 18, 1)) + + yield state; +>state : Symbol(state, Decl(generatorTypeCheck62.ts, 28, 71)) + +}); + +export const Nothing3: Strategy = strategy("Nothing", function* (state: State) { +>Nothing3 : Symbol(Nothing3, Decl(generatorTypeCheck62.ts, 32, 12)) +>Strategy : Symbol(Strategy, Decl(generatorTypeCheck62.ts, 14, 1)) +>State : Symbol(State, Decl(generatorTypeCheck62.ts, 18, 1)) +>strategy : Symbol(strategy, Decl(generatorTypeCheck62.ts, 3, 1)) +>state : Symbol(state, Decl(generatorTypeCheck62.ts, 32, 72)) +>State : Symbol(State, Decl(generatorTypeCheck62.ts, 18, 1)) + + yield ; + return state; +>state : Symbol(state, Decl(generatorTypeCheck62.ts, 32, 72)) + +}); + diff --git a/tests/baselines/reference/generatorTypeCheck62.types b/tests/baselines/reference/generatorTypeCheck62.types new file mode 100644 index 0000000000..289d33dc7d --- /dev/null +++ b/tests/baselines/reference/generatorTypeCheck62.types @@ -0,0 +1,122 @@ +=== tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck62.ts === + +export interface StrategicState { +>StrategicState : StrategicState + + lastStrategyApplied?: string; +>lastStrategyApplied : string +} + +export function strategy(stratName: string, gen: (a: T) => IterableIterator): (a: T) => IterableIterator { +>strategy : (stratName: string, gen: (a: T) => IterableIterator) => (a: T) => IterableIterator +>T : T +>StrategicState : StrategicState +>stratName : string +>gen : (a: T) => IterableIterator +>a : T +>T : T +>IterableIterator : IterableIterator +>T : T +>a : T +>T : T +>IterableIterator : IterableIterator +>T : T + + return function*(state) { +>function*(state) { for (const next of gen(state)) { if (next) { next.lastStrategyApplied = stratName; } yield next; } } : (state: T) => IterableIterator +>state : T + + for (const next of gen(state)) { +>next : T +>gen(state) : IterableIterator +>gen : (a: T) => IterableIterator +>state : T + + if (next) { +>next : T + + next.lastStrategyApplied = stratName; +>next.lastStrategyApplied = stratName : string +>next.lastStrategyApplied : string +>next : T +>lastStrategyApplied : string +>stratName : string + } + yield next; +>yield next : any +>next : T + } + } +} + +export interface Strategy { +>Strategy : Strategy +>T : T + + (a: T): IterableIterator; +>a : T +>T : T +>IterableIterator : IterableIterator +>T : T +} + +export interface State extends StrategicState { +>State : State +>StrategicState : StrategicState + + foo: number; +>foo : number +} + +export const Nothing1: Strategy = strategy("Nothing", function*(state: State) { +>Nothing1 : Strategy +>Strategy : Strategy +>State : State +>strategy("Nothing", function*(state: State) { return state;}) : (a: State) => IterableIterator +>strategy : (stratName: string, gen: (a: T) => IterableIterator) => (a: T) => IterableIterator +>"Nothing" : "Nothing" +>function*(state: State) { return state;} : (state: State) => IterableIterator +>state : State +>State : State + + return state; +>state : State + +}); + +export const Nothing2: Strategy = strategy("Nothing", function*(state: State) { +>Nothing2 : Strategy +>Strategy : Strategy +>State : State +>strategy("Nothing", function*(state: State) { yield state;}) : (a: State) => IterableIterator +>strategy : (stratName: string, gen: (a: T) => IterableIterator) => (a: T) => IterableIterator +>"Nothing" : "Nothing" +>function*(state: State) { yield state;} : (state: State) => IterableIterator +>state : State +>State : State + + yield state; +>yield state : any +>state : State + +}); + +export const Nothing3: Strategy = strategy("Nothing", function* (state: State) { +>Nothing3 : Strategy +>Strategy : Strategy +>State : State +>strategy("Nothing", function* (state: State) { yield ; return state;}) : (a: State) => IterableIterator +>strategy : (stratName: string, gen: (a: T) => IterableIterator) => (a: T) => IterableIterator +>"Nothing" : "Nothing" +>function* (state: State) { yield ; return state;} : (state: State) => IterableIterator +>state : State +>State : State + + yield ; +>yield : any + + return state; +>state : State + +}); + diff --git a/tests/baselines/reference/generatorTypeCheck63.errors.txt b/tests/baselines/reference/generatorTypeCheck63.errors.txt new file mode 100644 index 0000000000..46e722a0dd --- /dev/null +++ b/tests/baselines/reference/generatorTypeCheck63.errors.txt @@ -0,0 +1,63 @@ +tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(25,14): error TS2322: Type '(a: State | 1) => IterableIterator' is not assignable to type 'Strategy'. + Type 'IterableIterator' is not assignable to type 'IterableIterator'. + Type 'State | 1' is not assignable to type 'State'. + Type '1' is not assignable to type 'State'. +tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(30,70): error TS7025: Generator implicitly has type 'IterableIterator' because it does not yield any values. Consider supplying a return type. +tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(33,42): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. + Type argument candidate 'State' is not a valid type argument because it is not a supertype of candidate '1'. +tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(37,14): error TS2322: Type '(a: State | 1) => IterableIterator' is not assignable to type 'Strategy'. + + +==== tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts (4 errors) ==== + + export interface StrategicState { + lastStrategyApplied?: string; + } + + export function strategy(stratName: string, gen: (a: T) => IterableIterator): (a: T) => IterableIterator { + return function*(state) { + for (const next of gen(state)) { + if (next) { + next.lastStrategyApplied = stratName; + } + yield next; + } + } + } + + export interface Strategy { + (a: T): IterableIterator; + } + + export interface State extends StrategicState { + foo: number; + } + + export const Nothing: Strategy = strategy("Nothing", function* (state: State) { + ~~~~~~~ +!!! error TS2322: Type '(a: State | 1) => IterableIterator' is not assignable to type 'Strategy'. +!!! error TS2322: Type 'IterableIterator' is not assignable to type 'IterableIterator'. +!!! error TS2322: Type 'State | 1' is not assignable to type 'State'. +!!! error TS2322: Type '1' is not assignable to type 'State'. + yield 1; + return state; + }); + + export const Nothing1: Strategy = strategy("Nothing", function* (state: State) { + ~ +!!! error TS7025: Generator implicitly has type 'IterableIterator' because it does not yield any values. Consider supplying a return type. + }); + + export const Nothing2: Strategy = strategy("Nothing", function* (state: State) { + ~~~~~~~~ +!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. +!!! error TS2453: Type argument candidate 'State' is not a valid type argument because it is not a supertype of candidate '1'. + return 1; + }); + + export const Nothing3: Strategy = strategy("Nothing", function* (state: State) { + ~~~~~~~~ +!!! error TS2322: Type '(a: State | 1) => IterableIterator' is not assignable to type 'Strategy'. + yield state; + return 1; + }); \ No newline at end of file diff --git a/tests/baselines/reference/generatorTypeCheck63.js b/tests/baselines/reference/generatorTypeCheck63.js new file mode 100644 index 0000000000..92cf2f867f --- /dev/null +++ b/tests/baselines/reference/generatorTypeCheck63.js @@ -0,0 +1,69 @@ +//// [generatorTypeCheck63.ts] + +export interface StrategicState { + lastStrategyApplied?: string; +} + +export function strategy(stratName: string, gen: (a: T) => IterableIterator): (a: T) => IterableIterator { + return function*(state) { + for (const next of gen(state)) { + if (next) { + next.lastStrategyApplied = stratName; + } + yield next; + } + } +} + +export interface Strategy { + (a: T): IterableIterator; +} + +export interface State extends StrategicState { + foo: number; +} + +export const Nothing: Strategy = strategy("Nothing", function* (state: State) { + yield 1; + return state; +}); + +export const Nothing1: Strategy = strategy("Nothing", function* (state: State) { +}); + +export const Nothing2: Strategy = strategy("Nothing", function* (state: State) { + return 1; +}); + +export const Nothing3: Strategy = strategy("Nothing", function* (state: State) { + yield state; + return 1; +}); + +//// [generatorTypeCheck63.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function strategy(stratName, gen) { + return function* (state) { + for (const next of gen(state)) { + if (next) { + next.lastStrategyApplied = stratName; + } + yield next; + } + }; +} +exports.strategy = strategy; +exports.Nothing = strategy("Nothing", function* (state) { + yield 1; + return state; +}); +exports.Nothing1 = strategy("Nothing", function* (state) { +}); +exports.Nothing2 = strategy("Nothing", function* (state) { + return 1; +}); +exports.Nothing3 = strategy("Nothing", function* (state) { + yield state; + return 1; +}); From a37053f780583e979386a8ff7802e51e64e5bf67 Mon Sep 17 00:00:00 2001 From: Jason Ramsay Date: Wed, 22 Feb 2017 09:54:45 -0800 Subject: [PATCH 022/164] Addressing CR comments - Adding a throttle - Refactor - Navbar reset onCancel --- src/compiler/program.ts | 52 +++++----- src/compiler/types.ts | 2 + .../unittests/tsserverProjectSystem.ts | 94 ++++++++++--------- src/services/navigationBar.ts | 17 ++-- src/services/outliningElementsCollector.ts | 2 +- src/services/services.ts | 48 +++++++++- src/services/shims.ts | 23 ----- src/services/types.ts | 1 + 8 files changed, 137 insertions(+), 102 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 62f3c06644..083c812464 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -72,6 +72,20 @@ namespace ts { return getNormalizedPathFromPathComponents(commonPathComponents); } + /* @internal */ + export function runWithCancellationToken(func: () => T, onCancel?: () => void): T { + try { + return func(); + } + catch (e) { + if (e instanceof OperationCanceledException && onCancel) { + // We were canceled while performing the operation. + onCancel(); + } + throw e; + } + } + interface OutputFingerprint { hash: string; byteOrderMark: boolean; @@ -873,29 +887,19 @@ namespace ts { return sourceFile.parseDiagnostics; } - function runWithCancellationToken(func: () => T): T { - try { - return func(); - } - catch (e) { - if (e instanceof OperationCanceledException) { - // We were canceled while performing the operation. Because our type checker - // might be a bad state, we need to throw it away. - // - // Note: we are overly aggressive here. We do not actually *have* to throw away - // the "noDiagnosticsTypeChecker". However, for simplicity, i'd like to keep - // the lifetimes of these two TypeCheckers the same. Also, we generally only - // cancel when the user has made a change anyways. And, in that case, we (the - // program instance) will get thrown away anyways. So trying to keep one of - // these type checkers alive doesn't serve much purpose. - noDiagnosticsTypeChecker = undefined; - diagnosticsProducingTypeChecker = undefined; - } - - throw e; - } + function onCancel() { + // Because our type checker might be a bad state, we need to throw it away. + // Note: we are overly aggressive here. We do not actually *have* to throw away + // the "noDiagnosticsTypeChecker". However, for simplicity, i'd like to keep + // the lifetimes of these two TypeCheckers the same. Also, we generally only + // cancel when the user has made a change anyways. And, in that case, we (the + // program instance) will get thrown away anyways. So trying to keep one of + // these type checkers alive doesn't serve much purpose. + noDiagnosticsTypeChecker = undefined; + diagnosticsProducingTypeChecker = undefined; } + function getSemanticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] { return runWithCancellationToken(() => { const typeChecker = getDiagnosticsProducingTypeChecker(); @@ -910,7 +914,7 @@ namespace ts { const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName); return bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile); - }); + }, onCancel); } function getJavaScriptSyntacticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] { @@ -1089,7 +1093,7 @@ namespace ts { function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): Diagnostic { return createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2); } - }); + }, onCancel); } function getDeclarationDiagnosticsWorker(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] { @@ -1097,7 +1101,7 @@ namespace ts { const resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken); // Don't actually write any files since we're just getting diagnostics. return ts.getDeclarationDiagnostics(getEmitHost(noop), resolver, sourceFile); - }); + }, onCancel); } function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 7fc77b4870..17adbd2ea3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2262,6 +2262,8 @@ /** @throws OperationCanceledException if isCancellationRequested is true */ throwIfCancellationRequested(): void; + + throttleWaitMilliseconds?: number; } export interface Program extends ScriptReferenceHost { diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 01e484fd4b..ee4273c3d2 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -547,6 +547,45 @@ namespace ts.projectSystem { readonly getEnvironmentVariable = notImplemented; } + export class TestServerCancellationToken implements server.ServerCancellationToken { + private currentId = -1; + private requestToCancel = -1; + private isCancellationRequestedCount = 0; + + constructor(private cancelAfterRequest = 0) { + } + + get throttleWaitMilliseconds() { + // For testing purposes disable the throttle + return 0; + } + + setRequest(requestId: number) { + this.currentId = requestId; + } + + setRequestToCancel(requestId: number) { + this.resetToken(); + this.requestToCancel = requestId; + } + + resetRequest(requestId: number) { + assert.equal(requestId, this.currentId, "unexpected request id in cancellation") + this.currentId = undefined; + } + + isCancellationRequested() { + this.isCancellationRequestedCount++; + return this.requestToCancel === this.currentId && this.isCancellationRequestedCount >= this.cancelAfterRequest; + } + + resetToken() { + this.currentId = -1; + this.isCancellationRequestedCount = 0; + this.requestToCancel = -1; + } + } + export function makeSessionRequest(command: string, args: T) { const newRequest: protocol.Request = { seq: 0, @@ -3324,22 +3363,7 @@ namespace ts.projectSystem { }) }; - let requestToCancel = -1; - const cancellationToken: server.ServerCancellationToken = (function(){ - let currentId: number; - return { - setRequest(requestId) { - currentId = requestId; - }, - resetRequest(requestId) { - assert.equal(requestId, currentId, "unexpected request id in cancellation") - currentId = undefined; - }, - isCancellationRequested() { - return requestToCancel === currentId; - } - } - })(); + const cancellationToken = new TestServerCancellationToken(); const host = createServerHost([f1, config]); const session = createSession(host, /*typingsInstaller*/ undefined, () => {}, cancellationToken); { @@ -3374,13 +3398,13 @@ namespace ts.projectSystem { host.clearOutput(); // cancel previously issued Geterr - requestToCancel = getErrId; + cancellationToken.setRequestToCancel(getErrId); host.runQueuedTimeoutCallbacks(); assert.equal(host.getOutput().length, 1, "expect 1 message"); verifyRequestCompleted(getErrId, 0); - requestToCancel = -1; + cancellationToken.resetToken(); } { const getErrId = session.getNextSeq(); @@ -3397,12 +3421,12 @@ namespace ts.projectSystem { assert.equal(e1.event, "syntaxDiag"); host.clearOutput(); - requestToCancel = getErrId; + cancellationToken.setRequestToCancel(getErrId); host.runQueuedImmediateCallbacks(); assert.equal(host.getOutput().length, 1, "expect 1 message"); verifyRequestCompleted(getErrId, 0); - requestToCancel = -1; + cancellationToken.resetToken(); } { const getErrId = session.getNextSeq(); @@ -3425,7 +3449,7 @@ namespace ts.projectSystem { assert.equal(e2.event, "semanticDiag"); verifyRequestCompleted(getErrId, 1); - requestToCancel = -1; + cancellationToken.resetToken(); } { const getErr1 = session.getNextSeq(); @@ -3472,26 +3496,8 @@ namespace ts.projectSystem { }) }; - let requestToCancel = -1; - let isCancellationRequestedCount = 0; - let cancelAfterRequest = 3; let operationCanceledExceptionThrown = false; - const cancellationToken: server.ServerCancellationToken = (function () { - let currentId: number; - return { - setRequest(requestId) { - currentId = requestId; - }, - resetRequest(requestId) { - assert.equal(requestId, currentId, "unexpected request id in cancellation") - currentId = undefined; - }, - isCancellationRequested() { - isCancellationRequestedCount++; - return requestToCancel === currentId && isCancellationRequestedCount >= cancelAfterRequest; - } - } - })(); + const cancellationToken = new TestServerCancellationToken(/*cancelAfterRequest*/ 3); const host = createServerHost([f1, config]); const session = createSession(host, /*typingsInstaller*/ undefined, () => { }, cancellationToken); { @@ -3529,17 +3535,17 @@ namespace ts.projectSystem { // Set the next request to be cancellable // The cancellation token will cancel the request the third time // isCancellationRequested() is called. - requestToCancel = session.getNextSeq(); - isCancellationRequestedCount = 0; + cancellationToken.setRequestToCancel(session.getNextSeq()); operationCanceledExceptionThrown = false; try { session.executeCommandSeq(request); - } catch (e) { + } + catch (e) { assert(e instanceof OperationCanceledException); operationCanceledExceptionThrown = true; } - assert(operationCanceledExceptionThrown); + assert(operationCanceledExceptionThrown, "Operation Canceled Exception not thrown for request: " + JSON.stringify(request)); } }); }); diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 37b6bedbd5..2910a3528d 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -14,21 +14,24 @@ namespace ts.NavigationBar { indent: number; // # of parents } - export function getNavigationBarItems(sourceFile: SourceFile, cancellationToken: CancellationToken): NavigationBarItem[] { + export function getNavigationBarItems(sourceFile: SourceFile, cancellationToken: ThrottledCancellationToken): NavigationBarItem[] { + curCancellationToken = cancellationToken; curSourceFile = sourceFile; - const result = map(topLevelItems(rootNavigationBarNode(sourceFile, cancellationToken)), convertToTopLevelItem); + const result = runWithCancellationToken(() => map(topLevelItems(rootNavigationBarNode(sourceFile)), convertToTopLevelItem), () => curSourceFile = undefined); curSourceFile = undefined; return result; } - export function getNavigationTree(sourceFile: SourceFile, cancellationToken: CancellationToken): NavigationTree { + export function getNavigationTree(sourceFile: SourceFile, cancellationToken: ThrottledCancellationToken): NavigationTree { + curCancellationToken = cancellationToken; curSourceFile = sourceFile; - const result = convertToTree(rootNavigationBarNode(sourceFile, cancellationToken)); + const result = runWithCancellationToken(() => convertToTree(rootNavigationBarNode(sourceFile)), () => curSourceFile = undefined); curSourceFile = undefined; return result; } // Keep sourceFile handy so we don't have to search for it every time we need to call `getText`. + let curCancellationToken: ThrottledCancellationToken; let curSourceFile: SourceFile; function nodeText(node: Node): string { return node.getText(curSourceFile); @@ -55,12 +58,12 @@ namespace ts.NavigationBar { const parentsStack: NavigationBarNode[] = []; let parent: NavigationBarNode; - function rootNavigationBarNode(sourceFile: SourceFile, cancellationToken: CancellationToken): NavigationBarNode { + function rootNavigationBarNode(sourceFile: SourceFile): NavigationBarNode { Debug.assert(!parentsStack.length); const root: NavigationBarNode = { node: sourceFile, additionalNodes: undefined, parent: undefined, children: undefined, indent: 0 }; parent = root; for (const statement of sourceFile.statements) { - addChildrenRecursively(statement, cancellationToken); + addChildrenRecursively(statement, curCancellationToken); } endNode(); Debug.assert(!parent && !parentsStack.length); @@ -110,7 +113,7 @@ namespace ts.NavigationBar { } /** Look for navigation bar items in node's subtree, adding them to the current `parent`. */ - function addChildrenRecursively(node: Node, cancellationToken: CancellationToken): void { + function addChildrenRecursively(node: Node, cancellationToken: ThrottledCancellationToken): void { function addChildrenRecursively(node: Node): void { cancellationToken.throwIfCancellationRequested(); diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts index 96a7c9a3c4..1b7618c032 100644 --- a/src/services/outliningElementsCollector.ts +++ b/src/services/outliningElementsCollector.ts @@ -1,6 +1,6 @@ /* @internal */ namespace ts.OutliningElementsCollector { - export function collectElements(sourceFile: SourceFile, cancellationToken: CancellationToken): OutliningSpan[] { + export function collectElements(sourceFile: SourceFile, cancellationToken: ThrottledCancellationToken): OutliningSpan[] { const elements: OutliningSpan[] = []; const collapseText = "..."; diff --git a/src/services/services.ts b/src/services/services.ts index cef307eb8f..6cf50940fb 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -958,7 +958,12 @@ namespace ts { } class CancellationTokenObject implements CancellationToken { + throttleWaitMilliseconds?: number; + constructor(private cancellationToken: HostCancellationToken) { + if (cancellationToken.throttleWaitMilliseconds !== undefined) { + this.throttleWaitMilliseconds = cancellationToken.throttleWaitMilliseconds; + } } public isCancellationRequested() { @@ -972,6 +977,42 @@ namespace ts { } } + /** A cancellation that throttles calls to the host */ + export class ThrottledCancellationToken implements CancellationToken { + // Store when we last tried to cancel. Checking cancellation can be expensive (as we have + // to marshall over to the host layer). So we only bother actually checking once enough + // time has passed. + private lastCancellationCheckTime = 0; + // The minuimum duration to wait in milliseconds before querying host. + // The default of 10 milliseconds will be used unless throttleWaitMilliseconds + // is specified in the host cancellation token. + throttleWaitMilliseconds: number = 10; + + constructor(private hostCancellationToken: HostCancellationToken) { + if (hostCancellationToken.throttleWaitMilliseconds !== undefined) { + this.throttleWaitMilliseconds = hostCancellationToken.throttleWaitMilliseconds; + } + } + + public isCancellationRequested(): boolean { + const time = timestamp(); + const duration = Math.abs(time - this.lastCancellationCheckTime); + if (duration >= this.throttleWaitMilliseconds) { + // Check no more than the min wait in milliseconds + this.lastCancellationCheckTime = time; + return this.hostCancellationToken.isCancellationRequested(); + } + + return false; + } + + public throwIfCancellationRequested(): void { + if (this.isCancellationRequested()) { + throw new OperationCanceledException(); + } + } + } + export function createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory())): LanguageService { @@ -984,6 +1025,7 @@ namespace ts { const useCaseSensitivefileNames = host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(); const cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken()); + const throttledCancellationToken = new ThrottledCancellationToken(cancellationToken); const currentDirectory = host.getCurrentDirectory(); // Check if the localized messages json is set, otherwise query the host for it @@ -1541,11 +1583,11 @@ namespace ts { } function getNavigationBarItems(fileName: string): NavigationBarItem[] { - return NavigationBar.getNavigationBarItems(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken); + return NavigationBar.getNavigationBarItems(syntaxTreeCache.getCurrentSourceFile(fileName), throttledCancellationToken); } function getNavigationTree(fileName: string): NavigationTree { - return NavigationBar.getNavigationTree(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken); + return NavigationBar.getNavigationTree(syntaxTreeCache.getCurrentSourceFile(fileName), throttledCancellationToken); } function isTsOrTsxFile(fileName: string): boolean { @@ -1584,7 +1626,7 @@ namespace ts { function getOutliningSpans(fileName: string): OutliningSpan[] { // doesn't use compiler - no need to synchronize with host const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - return OutliningElementsCollector.collectElements(sourceFile, cancellationToken); + return OutliningElementsCollector.collectElements(sourceFile, throttledCancellationToken); } function getBraceMatchingAtPosition(fileName: string, position: number) { diff --git a/src/services/shims.ts b/src/services/shims.ts index 6fe9aed144..de2fd39b8a 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -469,29 +469,6 @@ namespace ts { } } - /** A cancellation that throttles calls to the host */ - class ThrottledCancellationToken implements HostCancellationToken { - // Store when we last tried to cancel. Checking cancellation can be expensive (as we have - // to marshall over to the host layer). So we only bother actually checking once enough - // time has passed. - private lastCancellationCheckTime = 0; - - constructor(private hostCancellationToken: HostCancellationToken) { - } - - public isCancellationRequested(): boolean { - const time = timestamp(); - const duration = Math.abs(time - this.lastCancellationCheckTime); - if (duration > 10) { - // Check no more than once every 10 ms. - this.lastCancellationCheckTime = time; - return this.hostCancellationToken.isCancellationRequested(); - } - - return false; - } - } - export class CoreServicesShimHostAdapter implements ParseConfigHost, ModuleResolutionHost { public directoryExists: (directoryName: string) => boolean; diff --git a/src/services/types.ts b/src/services/types.ts index a6ca385259..f9c33e15df 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -121,6 +121,7 @@ namespace ts { export interface HostCancellationToken { isCancellationRequested(): boolean; + throttleWaitMilliseconds?: number; } // From 497d8d3a58f40729941d08de64ee082e9b0d8154 Mon Sep 17 00:00:00 2001 From: Jason Ramsay Date: Wed, 22 Feb 2017 15:33:57 -0800 Subject: [PATCH 023/164] Updates from CR comments --- src/compiler/program.ts | 38 ++++++++++++++++++++++------------- src/services/navigationBar.ts | 26 +++++++++++++++--------- 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 083c812464..b94efe1822 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -887,18 +887,28 @@ namespace ts { return sourceFile.parseDiagnostics; } - function onCancel() { - // Because our type checker might be a bad state, we need to throw it away. - // Note: we are overly aggressive here. We do not actually *have* to throw away - // the "noDiagnosticsTypeChecker". However, for simplicity, i'd like to keep - // the lifetimes of these two TypeCheckers the same. Also, we generally only - // cancel when the user has made a change anyways. And, in that case, we (the - // program instance) will get thrown away anyways. So trying to keep one of - // these type checkers alive doesn't serve much purpose. - noDiagnosticsTypeChecker = undefined; - diagnosticsProducingTypeChecker = undefined; - } + function runWithCancellationToken(func: () => T): T { + try { + return func(); + } + catch (e) { + if (e instanceof OperationCanceledException) { + // We were canceled while performing the operation. Because our type checker + // might be a bad state, we need to throw it away. + // + // Note: we are overly aggressive here. We do not actually *have* to throw away + // the "noDiagnosticsTypeChecker". However, for simplicity, i'd like to keep + // the lifetimes of these two TypeCheckers the same. Also, we generally only + // cancel when the user has made a change anyways. And, in that case, we (the + // program instance) will get thrown away anyways. So trying to keep one of + // these type checkers alive doesn't serve much purpose. + noDiagnosticsTypeChecker = undefined; + diagnosticsProducingTypeChecker = undefined; + } + throw e; + } + } function getSemanticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] { return runWithCancellationToken(() => { @@ -914,7 +924,7 @@ namespace ts { const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName); return bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile); - }, onCancel); + }); } function getJavaScriptSyntacticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] { @@ -1093,7 +1103,7 @@ namespace ts { function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): Diagnostic { return createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2); } - }, onCancel); + }); } function getDeclarationDiagnosticsWorker(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] { @@ -1101,7 +1111,7 @@ namespace ts { const resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken); // Don't actually write any files since we're just getting diagnostics. return ts.getDeclarationDiagnostics(getEmitHost(noop), resolver, sourceFile); - }, onCancel); + }); } function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] { diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 2910a3528d..62ead677d8 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -17,21 +17,27 @@ namespace ts.NavigationBar { export function getNavigationBarItems(sourceFile: SourceFile, cancellationToken: ThrottledCancellationToken): NavigationBarItem[] { curCancellationToken = cancellationToken; curSourceFile = sourceFile; - const result = runWithCancellationToken(() => map(topLevelItems(rootNavigationBarNode(sourceFile)), convertToTopLevelItem), () => curSourceFile = undefined); - curSourceFile = undefined; - return result; + try { + return map(topLevelItems(rootNavigationBarNode(sourceFile)), convertToTopLevelItem); + } + finally { + curSourceFile = undefined; + } } export function getNavigationTree(sourceFile: SourceFile, cancellationToken: ThrottledCancellationToken): NavigationTree { curCancellationToken = cancellationToken; curSourceFile = sourceFile; - const result = runWithCancellationToken(() => convertToTree(rootNavigationBarNode(sourceFile)), () => curSourceFile = undefined); - curSourceFile = undefined; - return result; + try { + return convertToTree(rootNavigationBarNode(sourceFile)); + } + finally { + curSourceFile = undefined; + } } // Keep sourceFile handy so we don't have to search for it every time we need to call `getText`. - let curCancellationToken: ThrottledCancellationToken; + let curCancellationToken: CancellationToken; let curSourceFile: SourceFile; function nodeText(node: Node): string { return node.getText(curSourceFile); @@ -63,7 +69,7 @@ namespace ts.NavigationBar { const root: NavigationBarNode = { node: sourceFile, additionalNodes: undefined, parent: undefined, children: undefined, indent: 0 }; parent = root; for (const statement of sourceFile.statements) { - addChildrenRecursively(statement, curCancellationToken); + addChildrenRecursively(statement); } endNode(); Debug.assert(!parent && !parentsStack.length); @@ -113,9 +119,9 @@ namespace ts.NavigationBar { } /** Look for navigation bar items in node's subtree, adding them to the current `parent`. */ - function addChildrenRecursively(node: Node, cancellationToken: ThrottledCancellationToken): void { + function addChildrenRecursively(node: Node): void { function addChildrenRecursively(node: Node): void { - cancellationToken.throwIfCancellationRequested(); + curCancellationToken.throwIfCancellationRequested(); if (!node || isToken(node)) { return; From 84b9ebd0d7c40b9987f2ee8c7b821ac550eb5b2a Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Wed, 22 Feb 2017 15:42:22 -0800 Subject: [PATCH 024/164] Return empty string instead to prevent exception downstream particularly in writeReferencePath --- src/compiler/utilities.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 66bf693d83..528544e46d 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2653,7 +2653,7 @@ namespace ts { if (sourceFiles.length) { const jsFilePath = options.outFile || options.out; const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options); - const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : undefined; + const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : ""; action({ jsFilePath, sourceMapFilePath, declarationFilePath }, createBundle(sourceFiles), emitOnlyDtsFiles); } } From e62108cf9b5dbf678bf596def315ab766b82fa25 Mon Sep 17 00:00:00 2001 From: Jason Ramsay Date: Wed, 22 Feb 2017 17:33:11 -0800 Subject: [PATCH 025/164] Removing throttling until tests prove it is required --- src/compiler/program.ts | 14 - src/compiler/types.ts | 2 - .../unittests/tsserverProjectSystem.ts | 9 +- src/services/navigationBar.ts | 258 +++++++++--------- src/services/outliningElementsCollector.ts | 2 +- src/services/services.ts | 48 +--- src/services/shims.ts | 23 ++ src/services/types.ts | 1 - 8 files changed, 156 insertions(+), 201 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index b94efe1822..62f3c06644 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -72,20 +72,6 @@ namespace ts { return getNormalizedPathFromPathComponents(commonPathComponents); } - /* @internal */ - export function runWithCancellationToken(func: () => T, onCancel?: () => void): T { - try { - return func(); - } - catch (e) { - if (e instanceof OperationCanceledException && onCancel) { - // We were canceled while performing the operation. - onCancel(); - } - throw e; - } - } - interface OutputFingerprint { hash: string; byteOrderMark: boolean; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 17adbd2ea3..7fc77b4870 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2262,8 +2262,6 @@ /** @throws OperationCanceledException if isCancellationRequested is true */ throwIfCancellationRequested(): void; - - throttleWaitMilliseconds?: number; } export interface Program extends ScriptReferenceHost { diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index ee4273c3d2..d9abb0a907 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -555,11 +555,6 @@ namespace ts.projectSystem { constructor(private cancelAfterRequest = 0) { } - get throttleWaitMilliseconds() { - // For testing purposes disable the throttle - return 0; - } - setRequest(requestId: number) { this.currentId = requestId; } @@ -3495,8 +3490,6 @@ namespace ts.projectSystem { compilerOptions: {} }) }; - - let operationCanceledExceptionThrown = false; const cancellationToken = new TestServerCancellationToken(/*cancelAfterRequest*/ 3); const host = createServerHost([f1, config]); const session = createSession(host, /*typingsInstaller*/ undefined, () => { }, cancellationToken); @@ -3536,7 +3529,7 @@ namespace ts.projectSystem { // The cancellation token will cancel the request the third time // isCancellationRequested() is called. cancellationToken.setRequestToCancel(session.getNextSeq()); - operationCanceledExceptionThrown = false; + let operationCanceledExceptionThrown = false; try { session.executeCommandSeq(request); diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 62ead677d8..811762fb73 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -14,7 +14,7 @@ namespace ts.NavigationBar { indent: number; // # of parents } - export function getNavigationBarItems(sourceFile: SourceFile, cancellationToken: ThrottledCancellationToken): NavigationBarItem[] { + export function getNavigationBarItems(sourceFile: SourceFile, cancellationToken: CancellationToken): NavigationBarItem[] { curCancellationToken = cancellationToken; curSourceFile = sourceFile; try { @@ -22,10 +22,11 @@ namespace ts.NavigationBar { } finally { curSourceFile = undefined; + curCancellationToken = undefined; } } - export function getNavigationTree(sourceFile: SourceFile, cancellationToken: ThrottledCancellationToken): NavigationTree { + export function getNavigationTree(sourceFile: SourceFile, cancellationToken: CancellationToken): NavigationTree { curCancellationToken = cancellationToken; curSourceFile = sourceFile; try { @@ -33,6 +34,7 @@ namespace ts.NavigationBar { } finally { curSourceFile = undefined; + curCancellationToken = undefined; } } @@ -112,7 +114,7 @@ namespace ts.NavigationBar { parent = parentsStack.pop(); } - function addNodeWithRecursiveChild(node: Node, child: Node, addChildrenRecursively: (node: Node) => void): void { + function addNodeWithRecursiveChild(node: Node, child: Node): void { startNode(node); addChildrenRecursively(child); endNode(); @@ -120,136 +122,132 @@ namespace ts.NavigationBar { /** Look for navigation bar items in node's subtree, adding them to the current `parent`. */ function addChildrenRecursively(node: Node): void { - function addChildrenRecursively(node: Node): void { - curCancellationToken.throwIfCancellationRequested(); + curCancellationToken.throwIfCancellationRequested(); - if (!node || isToken(node)) { - return; - } - - switch (node.kind) { - case SyntaxKind.Constructor: - // Get parameter properties, and treat them as being on the *same* level as the constructor, not under it. - const ctr = node; - addNodeWithRecursiveChild(ctr, ctr.body, addChildrenRecursively); - - // Parameter properties are children of the class, not the constructor. - for (const param of ctr.parameters) { - if (isParameterPropertyDeclaration(param)) { - addLeafNode(param); - } - } - break; - - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.MethodSignature: - if (!hasDynamicName((node))) { - addNodeWithRecursiveChild(node, (node).body, addChildrenRecursively); - } - break; - - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - if (!hasDynamicName((node))) { - addLeafNode(node); - } - break; - - case SyntaxKind.ImportClause: - const importClause = node; - // Handle default import case e.g.: - // import d from "mod"; - if (importClause.name) { - addLeafNode(importClause); - } - - // Handle named bindings in imports e.g.: - // import * as NS from "mod"; - // import {a, b as B} from "mod"; - const {namedBindings} = importClause; - if (namedBindings) { - if (namedBindings.kind === SyntaxKind.NamespaceImport) { - addLeafNode(namedBindings); - } - else { - for (const element of (namedBindings).elements) { - addLeafNode(element); - } - } - } - break; - - case SyntaxKind.BindingElement: - case SyntaxKind.VariableDeclaration: - const decl = node; - const name = decl.name; - if (isBindingPattern(name)) { - addChildrenRecursively(name); - } - else if (decl.initializer && isFunctionOrClassExpression(decl.initializer)) { - // For `const x = function() {}`, just use the function node, not the const. - addChildrenRecursively(decl.initializer); - } - else { - addNodeWithRecursiveChild(decl, decl.initializer, addChildrenRecursively); - } - break; - - case SyntaxKind.ArrowFunction: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - addNodeWithRecursiveChild(node, (node).body, addChildrenRecursively); - break; - - case SyntaxKind.EnumDeclaration: - startNode(node); - for (const member of (node).members) { - if (!isComputedProperty(member)) { - addLeafNode(member); - } - } - endNode(); - break; - - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - case SyntaxKind.InterfaceDeclaration: - startNode(node); - for (const member of (node).members) { - addChildrenRecursively(member); - } - endNode(); - break; - - case SyntaxKind.ModuleDeclaration: - addNodeWithRecursiveChild(node, getInteriorModule(node).body, addChildrenRecursively); - break; - - case SyntaxKind.ExportSpecifier: - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.IndexSignature: - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.TypeAliasDeclaration: - addLeafNode(node); - break; - - default: - forEach(node.jsDoc, jsDoc => { - forEach(jsDoc.tags, tag => { - if (tag.kind === SyntaxKind.JSDocTypedefTag) { - addLeafNode(tag); - } - }); - }); - - forEachChild(node, addChildrenRecursively); - } + if (!node || isToken(node)) { + return; } - addChildrenRecursively(node); + switch (node.kind) { + case SyntaxKind.Constructor: + // Get parameter properties, and treat them as being on the *same* level as the constructor, not under it. + const ctr = node; + addNodeWithRecursiveChild(ctr, ctr.body); + + // Parameter properties are children of the class, not the constructor. + for (const param of ctr.parameters) { + if (isParameterPropertyDeclaration(param)) { + addLeafNode(param); + } + } + break; + + case SyntaxKind.MethodDeclaration: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + case SyntaxKind.MethodSignature: + if (!hasDynamicName((node))) { + addNodeWithRecursiveChild(node, (node).body); + } + break; + + case SyntaxKind.PropertyDeclaration: + case SyntaxKind.PropertySignature: + if (!hasDynamicName((node))) { + addLeafNode(node); + } + break; + + case SyntaxKind.ImportClause: + const importClause = node; + // Handle default import case e.g.: + // import d from "mod"; + if (importClause.name) { + addLeafNode(importClause); + } + + // Handle named bindings in imports e.g.: + // import * as NS from "mod"; + // import {a, b as B} from "mod"; + const {namedBindings} = importClause; + if (namedBindings) { + if (namedBindings.kind === SyntaxKind.NamespaceImport) { + addLeafNode(namedBindings); + } + else { + for (const element of (namedBindings).elements) { + addLeafNode(element); + } + } + } + break; + + case SyntaxKind.BindingElement: + case SyntaxKind.VariableDeclaration: + const decl = node; + const name = decl.name; + if (isBindingPattern(name)) { + addChildrenRecursively(name); + } + else if (decl.initializer && isFunctionOrClassExpression(decl.initializer)) { + // For `const x = function() {}`, just use the function node, not the const. + addChildrenRecursively(decl.initializer); + } + else { + addNodeWithRecursiveChild(decl, decl.initializer); + } + break; + + case SyntaxKind.ArrowFunction: + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.FunctionExpression: + addNodeWithRecursiveChild(node, (node).body); + break; + + case SyntaxKind.EnumDeclaration: + startNode(node); + for (const member of (node).members) { + if (!isComputedProperty(member)) { + addLeafNode(member); + } + } + endNode(); + break; + + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: + case SyntaxKind.InterfaceDeclaration: + startNode(node); + for (const member of (node).members) { + addChildrenRecursively(member); + } + endNode(); + break; + + case SyntaxKind.ModuleDeclaration: + addNodeWithRecursiveChild(node, getInteriorModule(node).body); + break; + + case SyntaxKind.ExportSpecifier: + case SyntaxKind.ImportEqualsDeclaration: + case SyntaxKind.IndexSignature: + case SyntaxKind.CallSignature: + case SyntaxKind.ConstructSignature: + case SyntaxKind.TypeAliasDeclaration: + addLeafNode(node); + break; + + default: + forEach(node.jsDoc, jsDoc => { + forEach(jsDoc.tags, tag => { + if (tag.kind === SyntaxKind.JSDocTypedefTag) { + addLeafNode(tag); + } + }); + }); + + forEachChild(node, addChildrenRecursively); + } } /** Merge declarations of the same kind. */ diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts index 1b7618c032..96a7c9a3c4 100644 --- a/src/services/outliningElementsCollector.ts +++ b/src/services/outliningElementsCollector.ts @@ -1,6 +1,6 @@ /* @internal */ namespace ts.OutliningElementsCollector { - export function collectElements(sourceFile: SourceFile, cancellationToken: ThrottledCancellationToken): OutliningSpan[] { + export function collectElements(sourceFile: SourceFile, cancellationToken: CancellationToken): OutliningSpan[] { const elements: OutliningSpan[] = []; const collapseText = "..."; diff --git a/src/services/services.ts b/src/services/services.ts index 6cf50940fb..cef307eb8f 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -958,12 +958,7 @@ namespace ts { } class CancellationTokenObject implements CancellationToken { - throttleWaitMilliseconds?: number; - constructor(private cancellationToken: HostCancellationToken) { - if (cancellationToken.throttleWaitMilliseconds !== undefined) { - this.throttleWaitMilliseconds = cancellationToken.throttleWaitMilliseconds; - } } public isCancellationRequested() { @@ -977,42 +972,6 @@ namespace ts { } } - /** A cancellation that throttles calls to the host */ - export class ThrottledCancellationToken implements CancellationToken { - // Store when we last tried to cancel. Checking cancellation can be expensive (as we have - // to marshall over to the host layer). So we only bother actually checking once enough - // time has passed. - private lastCancellationCheckTime = 0; - // The minuimum duration to wait in milliseconds before querying host. - // The default of 10 milliseconds will be used unless throttleWaitMilliseconds - // is specified in the host cancellation token. - throttleWaitMilliseconds: number = 10; - - constructor(private hostCancellationToken: HostCancellationToken) { - if (hostCancellationToken.throttleWaitMilliseconds !== undefined) { - this.throttleWaitMilliseconds = hostCancellationToken.throttleWaitMilliseconds; - } - } - - public isCancellationRequested(): boolean { - const time = timestamp(); - const duration = Math.abs(time - this.lastCancellationCheckTime); - if (duration >= this.throttleWaitMilliseconds) { - // Check no more than the min wait in milliseconds - this.lastCancellationCheckTime = time; - return this.hostCancellationToken.isCancellationRequested(); - } - - return false; - } - - public throwIfCancellationRequested(): void { - if (this.isCancellationRequested()) { - throw new OperationCanceledException(); - } - } - } - export function createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory())): LanguageService { @@ -1025,7 +984,6 @@ namespace ts { const useCaseSensitivefileNames = host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(); const cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken()); - const throttledCancellationToken = new ThrottledCancellationToken(cancellationToken); const currentDirectory = host.getCurrentDirectory(); // Check if the localized messages json is set, otherwise query the host for it @@ -1583,11 +1541,11 @@ namespace ts { } function getNavigationBarItems(fileName: string): NavigationBarItem[] { - return NavigationBar.getNavigationBarItems(syntaxTreeCache.getCurrentSourceFile(fileName), throttledCancellationToken); + return NavigationBar.getNavigationBarItems(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken); } function getNavigationTree(fileName: string): NavigationTree { - return NavigationBar.getNavigationTree(syntaxTreeCache.getCurrentSourceFile(fileName), throttledCancellationToken); + return NavigationBar.getNavigationTree(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken); } function isTsOrTsxFile(fileName: string): boolean { @@ -1626,7 +1584,7 @@ namespace ts { function getOutliningSpans(fileName: string): OutliningSpan[] { // doesn't use compiler - no need to synchronize with host const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - return OutliningElementsCollector.collectElements(sourceFile, throttledCancellationToken); + return OutliningElementsCollector.collectElements(sourceFile, cancellationToken); } function getBraceMatchingAtPosition(fileName: string, position: number) { diff --git a/src/services/shims.ts b/src/services/shims.ts index de2fd39b8a..6fe9aed144 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -469,6 +469,29 @@ namespace ts { } } + /** A cancellation that throttles calls to the host */ + class ThrottledCancellationToken implements HostCancellationToken { + // Store when we last tried to cancel. Checking cancellation can be expensive (as we have + // to marshall over to the host layer). So we only bother actually checking once enough + // time has passed. + private lastCancellationCheckTime = 0; + + constructor(private hostCancellationToken: HostCancellationToken) { + } + + public isCancellationRequested(): boolean { + const time = timestamp(); + const duration = Math.abs(time - this.lastCancellationCheckTime); + if (duration > 10) { + // Check no more than once every 10 ms. + this.lastCancellationCheckTime = time; + return this.hostCancellationToken.isCancellationRequested(); + } + + return false; + } + } + export class CoreServicesShimHostAdapter implements ParseConfigHost, ModuleResolutionHost { public directoryExists: (directoryName: string) => boolean; diff --git a/src/services/types.ts b/src/services/types.ts index f9c33e15df..a6ca385259 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -121,7 +121,6 @@ namespace ts { export interface HostCancellationToken { isCancellationRequested(): boolean; - throttleWaitMilliseconds?: number; } // From 91571f05d31b968d30ef358f505ae2c837c30faf Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 23 Feb 2017 15:58:49 -0800 Subject: [PATCH 026/164] Add support for handeling .js file correctelly in fixAddMissingMember code fix --- src/compiler/diagnosticMessages.json | 5 ++ src/services/codefixes/fixAddMissingMember.ts | 86 ++++++++++++------- 2 files changed, 59 insertions(+), 32 deletions(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index b9572b2b0f..d1c7f82ead 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3351,6 +3351,11 @@ "category": "Message", "code": 90017 }, + "Initialize property '{0}' in the constructor.": { + "category": "Message", + "code": 90018 + }, + "Octal literal types must use ES2015 syntax. Use the syntax '{0}'.": { "category": "Error", "code": 8017 diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index 6ae2ba3f51..fe4176a766 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -23,45 +23,67 @@ namespace ts.codefix { return undefined; } - if (!(token.parent && token.parent.kind === SyntaxKind.PropertyAccessExpression)) { + if (!isPropertyAccessExpression(token.parent) || token.parent.expression.kind !== SyntaxKind.ThisKeyword) { return undefined; } - if ((token.parent as PropertyAccessExpression).expression.kind !== SyntaxKind.ThisKeyword) { - return undefined; + return isInJavaScriptFile(sourceFile) ? getActionsForAddMissingMemberInJavaScriptFile() : getActionsForAddMissingMemberInTypeScriptFile(); + + + function getActionsForAddMissingMemberInTypeScriptFile(): CodeAction[] | undefined { + let typeString = "any"; + + if (token.parent.parent.kind === SyntaxKind.BinaryExpression) { + const binaryExpression = token.parent.parent as BinaryExpression; + + const checker = context.program.getTypeChecker(); + const widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(binaryExpression.right))); + typeString = checker.typeToString(widenedType); + } + + const startPos = classDeclaration.members.pos; + + return [{ + description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_declaration_for_missing_property_0), [token.getText()]), + changes: [{ + fileName: sourceFile.fileName, + textChanges: [{ + span: { start: startPos, length: 0 }, + newText: `${token.getFullText(sourceFile)}: ${typeString};` + }] + }] + }, + { + description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_index_signature_for_missing_property_0), [token.getText()]), + changes: [{ + fileName: sourceFile.fileName, + textChanges: [{ + span: { start: startPos, length: 0 }, + newText: `[name: string]: ${typeString};` + }] + }] + }]; } - let typeString = "any"; + function getActionsForAddMissingMemberInJavaScriptFile(): CodeAction[] | undefined { + const classConstructor = getFirstConstructorWithBody(classDeclaration); + if (!classConstructor) { + return undefined; + } - if (token.parent.parent.kind === SyntaxKind.BinaryExpression) { - const binaryExpression = token.parent.parent as BinaryExpression; + const memberName = token.getText(); + const startPos = classConstructor.body.getEnd() - 1; - const checker = context.program.getTypeChecker(); - const widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(binaryExpression.right))); - typeString = checker.typeToString(widenedType); + return [{ + description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Initialize_property_0_in_the_constructor), [memberName]), + changes: [{ + fileName: sourceFile.fileName, + textChanges: [{ + span: { start: startPos, length: 0 }, + newText: `this.${memberName} = undefined;` + }] + }] + }]; } - - const startPos = classDeclaration.members.pos; - - return [{ - description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_declaration_for_missing_property_0), [token.getText()]), - changes: [{ - fileName: sourceFile.fileName, - textChanges: [{ - span: { start: startPos, length: 0 }, - newText: `${token.getFullText(sourceFile)}: ${typeString};` - }] - }] - }, - { - description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_index_signature_for_missing_property_0), [token.getText()]), - changes: [{ - fileName: sourceFile.fileName, - textChanges: [{ - span: { start: startPos, length: 0 }, - newText: `[name: string]: ${typeString};` - }] - }] - }]; } } \ No newline at end of file From ed7a3d00b985193f9d5469e4dd88137b2d799c53 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Fri, 24 Feb 2017 16:46:21 -0800 Subject: [PATCH 027/164] Issue an error when class is used before class declaration --- src/compiler/checker.ts | 38 +++++++++++++++------------- src/compiler/diagnosticMessages.json | 8 +++--- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 83fea11c99..57905315d7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1056,9 +1056,9 @@ namespace ts { // block-scoped variable and namespace module. However, only when we // try to resolve name in /*1*/ which is used in variable position, // we want to check for block-scoped - if (meaning & SymbolFlags.BlockScopedVariable) { + if (meaning & SymbolFlags.BlockScopedVariable || (meaning & SymbolFlags.Class && (meaning & SymbolFlags.Value) === SymbolFlags.Value)) { const exportOrLocalSymbol = getExportSymbolOfValueSymbolIfExported(result); - if (exportOrLocalSymbol.flags & SymbolFlags.BlockScopedVariable) { + if (exportOrLocalSymbol.flags & SymbolFlags.BlockScopedVariable || exportOrLocalSymbol.flags & SymbolFlags.Class) { checkResolvedBlockScopedVariable(exportOrLocalSymbol, errorLocation); } } @@ -1171,14 +1171,19 @@ namespace ts { } function checkResolvedBlockScopedVariable(result: Symbol, errorLocation: Node): void { - Debug.assert((result.flags & SymbolFlags.BlockScopedVariable) !== 0); + Debug.assert(!!(result.flags & SymbolFlags.BlockScopedVariable || result.flags & SymbolFlags.Class)); // Block-scoped variables cannot be used before their definition - const declaration = forEach(result.declarations, d => isBlockOrCatchScoped(d) ? d : undefined); + const declaration = forEach(result.declarations, d => isBlockOrCatchScoped(d) || isClassLike(d) ? d : undefined); Debug.assert(declaration !== undefined, "Block-scoped variable declaration is undefined"); if (!isInAmbientContext(declaration) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) { - error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, declarationNameToString(declaration.name)); + if (result.flags & SymbolFlags.BlockScopedVariable) { + error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, declarationNameToString(declaration.name)); + } + else { + error(errorLocation, Diagnostics.Class_0_used_before_its_declaration, declarationNameToString(declaration.name)); + } } } @@ -13171,10 +13176,17 @@ namespace ts { } return unknownType; } - if (prop.valueDeclaration && - isInPropertyInitializer(node) && - !isBlockScopedNameDeclaredBeforeUse(prop.valueDeclaration, right)) { - error(right, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, right.text); + if (prop.valueDeclaration) { + if (isInPropertyInitializer(node) && + !isBlockScopedNameDeclaredBeforeUse(prop.valueDeclaration, right)) { + error(right, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, right.text); + } + if (prop.valueDeclaration.kind === SyntaxKind.ClassDeclaration && + node.parent && node.parent.kind !== SyntaxKind.TypeReference && + !isInAmbientContext(prop.valueDeclaration) && + !isBlockScopedNameDeclaredBeforeUse(prop.valueDeclaration, right)) { + error(right, Diagnostics.Class_0_used_before_its_declaration, right.text); + } } markPropertyAsReferenced(prop); @@ -19421,14 +19433,6 @@ namespace ts { error(node.name || node, Diagnostics.A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any); } - if (baseType.symbol && baseType.symbol.valueDeclaration && - !isInAmbientContext(baseType.symbol.valueDeclaration) && - baseType.symbol.valueDeclaration.kind === SyntaxKind.ClassDeclaration) { - if (!isBlockScopedNameDeclaredBeforeUse(baseType.symbol.valueDeclaration, node)) { - error(baseTypeNode, Diagnostics.A_class_must_be_declared_after_its_base_class); - } - } - if (!(staticBaseType.symbol && staticBaseType.symbol.flags & SymbolFlags.Class) && !(baseConstructorType.flags & TypeFlags.TypeVariable)) { // When the static base type is a "class-like" constructor function (but not actually a class), we verify // that all instantiated base constructor signatures return the same type. We can simply compare the type diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index b9572b2b0f..691f8e8d31 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1435,6 +1435,10 @@ "category": "Error", "code": 2448 }, + "Class '{0}' used before its declaration.": { + "category": "Error", + "code": 2449 + }, "Cannot redeclare block-scoped variable '{0}'.": { "category": "Error", "code": 2451 @@ -2019,10 +2023,6 @@ "category": "Error", "code": 2689 }, - "A class must be declared after its base class.": { - "category": "Error", - "code": 2690 - }, "An import path cannot end with a '{0}' extension. Consider importing '{1}' instead.": { "category": "Error", "code": 2691 From d511884cd9810e788259eadb254d28285e5008bb Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Fri, 24 Feb 2017 16:47:10 -0800 Subject: [PATCH 028/164] Update baselines from issueing an error for class used before declaration --- ...dClassWithSameNameAndCommonRoot.errors.txt | 5 +- .../reference/circularImportAlias.errors.txt | 6 +- .../classAbstractInstantiations2.errors.txt | 5 +- .../classExtendsItselfIndirectly.errors.txt | 8 +- .../classExtendsItselfIndirectly2.errors.txt | 8 +- .../reference/classInheritence.errors.txt | 4 +- .../reference/classOrder2.errors.txt | 4 +- .../classSideInheritance2.errors.txt | 4 +- .../complexClassRelationships.errors.txt | 4 +- .../reference/derivedClasses.errors.txt | 4 +- ...xtendBaseClassBeforeItsDeclared.errors.txt | 4 +- ...sConstructorFromNonGenericClass.errors.txt | 10 +- .../indirectSelfReference.errors.txt | 5 +- .../indirectSelfReferenceGeneric.errors.txt | 5 +- .../reference/parserRealSource10.errors.txt | 5 +- ...ivacyClassExtendsClauseDeclFile.errors.txt | 12 +- .../reference/recursiveBaseCheck3.errors.txt | 5 +- ...arationWhenInBaseTypeResolution.errors.txt | 144 +++++++++--------- .../reference/symbolProperty33.errors.txt | 4 +- .../reference/symbolProperty34.errors.txt | 4 +- 20 files changed, 140 insertions(+), 110 deletions(-) diff --git a/tests/baselines/reference/ModuleAndClassWithSameNameAndCommonRoot.errors.txt b/tests/baselines/reference/ModuleAndClassWithSameNameAndCommonRoot.errors.txt index 2a464e8826..0da61368ee 100644 --- a/tests/baselines/reference/ModuleAndClassWithSameNameAndCommonRoot.errors.txt +++ b/tests/baselines/reference/ModuleAndClassWithSameNameAndCommonRoot.errors.txt @@ -1,5 +1,6 @@ tests/cases/conformance/internalModules/DeclarationMerging/module.ts(2,19): error TS2433: A namespace declaration cannot be in a different file from a class or function with which it is merged. tests/cases/conformance/internalModules/DeclarationMerging/simple.ts(1,8): error TS2434: A namespace declaration cannot be located prior to a class or function with which it is merged. +tests/cases/conformance/internalModules/DeclarationMerging/simple.ts(2,31): error TS2449: Class 'A' used before its declaration. ==== tests/cases/conformance/internalModules/DeclarationMerging/module.ts (1 errors) ==== @@ -24,11 +25,13 @@ tests/cases/conformance/internalModules/DeclarationMerging/simple.ts(1,8): error } } -==== tests/cases/conformance/internalModules/DeclarationMerging/simple.ts (1 errors) ==== +==== tests/cases/conformance/internalModules/DeclarationMerging/simple.ts (2 errors) ==== module A { ~ !!! error TS2434: A namespace declaration cannot be located prior to a class or function with which it is merged. export var Instance = new A(); + ~ +!!! error TS2449: Class 'A' used before its declaration. } // duplicate identifier diff --git a/tests/baselines/reference/circularImportAlias.errors.txt b/tests/baselines/reference/circularImportAlias.errors.txt index 82c9205ae5..13ff1d8c7c 100644 --- a/tests/baselines/reference/circularImportAlias.errors.txt +++ b/tests/baselines/reference/circularImportAlias.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/internalModules/importDeclarations/circularImportAlias.ts(5,28): error TS2690: A class must be declared after its base class. +tests/cases/conformance/internalModules/importDeclarations/circularImportAlias.ts(5,30): error TS2449: Class 'C' used before its declaration. ==== tests/cases/conformance/internalModules/importDeclarations/circularImportAlias.ts (1 errors) ==== @@ -7,8 +7,8 @@ tests/cases/conformance/internalModules/importDeclarations/circularImportAlias.t module B { export import a = A; export class D extends a.C { - ~~~ -!!! error TS2690: A class must be declared after its base class. + ~ +!!! error TS2449: Class 'C' used before its declaration. id: number; } } diff --git a/tests/baselines/reference/classAbstractInstantiations2.errors.txt b/tests/baselines/reference/classAbstractInstantiations2.errors.txt index bf4cd851fb..15b63a6d3e 100644 --- a/tests/baselines/reference/classAbstractInstantiations2.errors.txt +++ b/tests/baselines/reference/classAbstractInstantiations2.errors.txt @@ -3,13 +3,14 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst Cannot assign an abstract constructor type to a non-abstract constructor type. tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(17,5): error TS2511: Cannot create an instance of the abstract class 'B'. tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(21,1): error TS2511: Cannot create an instance of the abstract class 'B'. +tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(23,15): error TS2449: Class 'C' used before its declaration. tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(26,7): error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'bar' from class 'B'. tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(46,5): error TS2391: Function implementation is missing or not immediately following the declaration. tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(46,5): error TS2512: Overload signatures must all be abstract or non-abstract. tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(50,5): error TS1244: Abstract methods can only appear within an abstract class. -==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts (8 errors) ==== +==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts (9 errors) ==== class A { // ... } @@ -42,6 +43,8 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst !!! error TS2511: Cannot create an instance of the abstract class 'B'. var x : any = C; + ~ +!!! error TS2449: Class 'C' used before its declaration. new x; // okay -- undefined behavior at runtime class C extends B { } // error -- not declared abstract diff --git a/tests/baselines/reference/classExtendsItselfIndirectly.errors.txt b/tests/baselines/reference/classExtendsItselfIndirectly.errors.txt index c0f35f0388..8f54ef1805 100644 --- a/tests/baselines/reference/classExtendsItselfIndirectly.errors.txt +++ b/tests/baselines/reference/classExtendsItselfIndirectly.errors.txt @@ -1,15 +1,19 @@ tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly.ts(1,7): error TS2506: 'C' is referenced directly or indirectly in its own base expression. +tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly.ts(1,17): error TS2449: Class 'E' used before its declaration. tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly.ts(3,7): error TS2506: 'D' is referenced directly or indirectly in its own base expression. tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly.ts(5,7): error TS2506: 'E' is referenced directly or indirectly in its own base expression. tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly.ts(7,7): error TS2506: 'C2' is referenced directly or indirectly in its own base expression. +tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly.ts(7,21): error TS2449: Class 'E2' used before its declaration. tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly.ts(9,7): error TS2506: 'D2' is referenced directly or indirectly in its own base expression. tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly.ts(11,7): error TS2506: 'E2' is referenced directly or indirectly in its own base expression. -==== tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly.ts (6 errors) ==== +==== tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly.ts (8 errors) ==== class C extends E { foo: string; } // error ~ !!! error TS2506: 'C' is referenced directly or indirectly in its own base expression. + ~ +!!! error TS2449: Class 'E' used before its declaration. class D extends C { bar: string; } ~ @@ -22,6 +26,8 @@ tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/cla class C2 extends E2 { foo: T; } // error ~~ !!! error TS2506: 'C2' is referenced directly or indirectly in its own base expression. + ~~ +!!! error TS2449: Class 'E2' used before its declaration. class D2 extends C2 { bar: T; } ~~ diff --git a/tests/baselines/reference/classExtendsItselfIndirectly2.errors.txt b/tests/baselines/reference/classExtendsItselfIndirectly2.errors.txt index 061770f9b7..48c787b54d 100644 --- a/tests/baselines/reference/classExtendsItselfIndirectly2.errors.txt +++ b/tests/baselines/reference/classExtendsItselfIndirectly2.errors.txt @@ -1,15 +1,19 @@ tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly2.ts(1,7): error TS2506: 'C' is referenced directly or indirectly in its own base expression. +tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly2.ts(1,19): error TS2449: Class 'E' used before its declaration. tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly2.ts(4,18): error TS2506: 'D' is referenced directly or indirectly in its own base expression. tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly2.ts(9,18): error TS2506: 'E' is referenced directly or indirectly in its own base expression. tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly2.ts(13,11): error TS2506: 'C2' is referenced directly or indirectly in its own base expression. +tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly2.ts(13,27): error TS2449: Class 'E2' used before its declaration. tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly2.ts(16,22): error TS2506: 'D2' is referenced directly or indirectly in its own base expression. tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly2.ts(20,22): error TS2506: 'E2' is referenced directly or indirectly in its own base expression. -==== tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly2.ts (6 errors) ==== +==== tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly2.ts (8 errors) ==== class C extends N.E { foo: string; } // error ~ !!! error TS2506: 'C' is referenced directly or indirectly in its own base expression. + ~ +!!! error TS2449: Class 'E' used before its declaration. module M { export class D extends C { bar: string; } @@ -28,6 +32,8 @@ tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/cla class C2 extends Q.E2 { foo: T; } // error ~~ !!! error TS2506: 'C2' is referenced directly or indirectly in its own base expression. + ~~ +!!! error TS2449: Class 'E2' used before its declaration. module P { export class D2 extends C2 { bar: T; } diff --git a/tests/baselines/reference/classInheritence.errors.txt b/tests/baselines/reference/classInheritence.errors.txt index cd95dedbfc..3bad3caf3d 100644 --- a/tests/baselines/reference/classInheritence.errors.txt +++ b/tests/baselines/reference/classInheritence.errors.txt @@ -1,11 +1,11 @@ -tests/cases/compiler/classInheritence.ts(1,17): error TS2690: A class must be declared after its base class. +tests/cases/compiler/classInheritence.ts(1,17): error TS2449: Class 'A' used before its declaration. tests/cases/compiler/classInheritence.ts(2,7): error TS2506: 'A' is referenced directly or indirectly in its own base expression. ==== tests/cases/compiler/classInheritence.ts (2 errors) ==== class B extends A { } ~ -!!! error TS2690: A class must be declared after its base class. +!!! error TS2449: Class 'A' used before its declaration. class A extends A { } ~ !!! error TS2506: 'A' is referenced directly or indirectly in its own base expression. \ No newline at end of file diff --git a/tests/baselines/reference/classOrder2.errors.txt b/tests/baselines/reference/classOrder2.errors.txt index a1b8dc6346..59184e6a5e 100644 --- a/tests/baselines/reference/classOrder2.errors.txt +++ b/tests/baselines/reference/classOrder2.errors.txt @@ -1,11 +1,11 @@ -tests/cases/compiler/classOrder2.ts(2,17): error TS2690: A class must be declared after its base class. +tests/cases/compiler/classOrder2.ts(2,17): error TS2449: Class 'B' used before its declaration. ==== tests/cases/compiler/classOrder2.ts (1 errors) ==== class A extends B { ~ -!!! error TS2690: A class must be declared after its base class. +!!! error TS2449: Class 'B' used before its declaration. foo() { this.bar(); } diff --git a/tests/baselines/reference/classSideInheritance2.errors.txt b/tests/baselines/reference/classSideInheritance2.errors.txt index e286594ec2..7b27ee7c0f 100644 --- a/tests/baselines/reference/classSideInheritance2.errors.txt +++ b/tests/baselines/reference/classSideInheritance2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/classSideInheritance2.ts(7,23): error TS2690: A class must be declared after its base class. +tests/cases/compiler/classSideInheritance2.ts(7,23): error TS2449: Class 'TextBase' used before its declaration. ==== tests/cases/compiler/classSideInheritance2.ts (1 errors) ==== @@ -10,7 +10,7 @@ tests/cases/compiler/classSideInheritance2.ts(7,23): error TS2690: A class must class SubText extends TextBase { ~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. +!!! error TS2449: Class 'TextBase' used before its declaration. constructor(text: IText, span: TextSpan) { super(); diff --git a/tests/baselines/reference/complexClassRelationships.errors.txt b/tests/baselines/reference/complexClassRelationships.errors.txt index 33413e496d..c978a36c03 100644 --- a/tests/baselines/reference/complexClassRelationships.errors.txt +++ b/tests/baselines/reference/complexClassRelationships.errors.txt @@ -1,11 +1,11 @@ -tests/cases/compiler/complexClassRelationships.ts(2,23): error TS2690: A class must be declared after its base class. +tests/cases/compiler/complexClassRelationships.ts(2,23): error TS2449: Class 'Base' used before its declaration. ==== tests/cases/compiler/complexClassRelationships.ts (1 errors) ==== // There should be no errors in this file class Derived extends Base { ~~~~ -!!! error TS2690: A class must be declared after its base class. +!!! error TS2449: Class 'Base' used before its declaration. public static createEmpty(): Derived { var item = new Derived(); return item; diff --git a/tests/baselines/reference/derivedClasses.errors.txt b/tests/baselines/reference/derivedClasses.errors.txt index fdd38d8c06..ff6946df2c 100644 --- a/tests/baselines/reference/derivedClasses.errors.txt +++ b/tests/baselines/reference/derivedClasses.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/derivedClasses.ts(1,19): error TS2690: A class must be declared after its base class. +tests/cases/compiler/derivedClasses.ts(1,19): error TS2449: Class 'Color' used before its declaration. ==== tests/cases/compiler/derivedClasses.ts (1 errors) ==== class Red extends Color { ~~~~~ -!!! error TS2690: A class must be declared after its base class. +!!! error TS2449: Class 'Color' used before its declaration. public shade() { var getHue = () => { return this.hue(); }; return getHue() + " red"; diff --git a/tests/baselines/reference/extendBaseClassBeforeItsDeclared.errors.txt b/tests/baselines/reference/extendBaseClassBeforeItsDeclared.errors.txt index 2678fdf866..64e5c7d3ef 100644 --- a/tests/baselines/reference/extendBaseClassBeforeItsDeclared.errors.txt +++ b/tests/baselines/reference/extendBaseClassBeforeItsDeclared.errors.txt @@ -1,9 +1,9 @@ -tests/cases/compiler/extendBaseClassBeforeItsDeclared.ts(1,23): error TS2690: A class must be declared after its base class. +tests/cases/compiler/extendBaseClassBeforeItsDeclared.ts(1,23): error TS2449: Class 'base' used before its declaration. ==== tests/cases/compiler/extendBaseClassBeforeItsDeclared.ts (1 errors) ==== class derived extends base { } ~~~~ -!!! error TS2690: A class must be declared after its base class. +!!! error TS2449: Class 'base' used before its declaration. class base { constructor (public n: number) { } } \ No newline at end of file diff --git a/tests/baselines/reference/genericClassInheritsConstructorFromNonGenericClass.errors.txt b/tests/baselines/reference/genericClassInheritsConstructorFromNonGenericClass.errors.txt index 1962576abc..d259a2d2e2 100644 --- a/tests/baselines/reference/genericClassInheritsConstructorFromNonGenericClass.errors.txt +++ b/tests/baselines/reference/genericClassInheritsConstructorFromNonGenericClass.errors.txt @@ -1,14 +1,14 @@ -tests/cases/compiler/genericClassInheritsConstructorFromNonGenericClass.ts(1,17): error TS2690: A class must be declared after its base class. -tests/cases/compiler/genericClassInheritsConstructorFromNonGenericClass.ts(2,20): error TS2690: A class must be declared after its base class. +tests/cases/compiler/genericClassInheritsConstructorFromNonGenericClass.ts(1,17): error TS2449: Class 'B' used before its declaration. +tests/cases/compiler/genericClassInheritsConstructorFromNonGenericClass.ts(2,20): error TS2449: Class 'C' used before its declaration. ==== tests/cases/compiler/genericClassInheritsConstructorFromNonGenericClass.ts (2 errors) ==== class A extends B { } - ~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~ +!!! error TS2449: Class 'B' used before its declaration. class B extends C { } ~ -!!! error TS2690: A class must be declared after its base class. +!!! error TS2449: Class 'C' used before its declaration. class C { constructor(p: string) { } } \ No newline at end of file diff --git a/tests/baselines/reference/indirectSelfReference.errors.txt b/tests/baselines/reference/indirectSelfReference.errors.txt index 3f7d3d47f1..0339dd8ed0 100644 --- a/tests/baselines/reference/indirectSelfReference.errors.txt +++ b/tests/baselines/reference/indirectSelfReference.errors.txt @@ -1,11 +1,14 @@ tests/cases/compiler/indirectSelfReference.ts(1,7): error TS2506: 'a' is referenced directly or indirectly in its own base expression. +tests/cases/compiler/indirectSelfReference.ts(1,17): error TS2449: Class 'b' used before its declaration. tests/cases/compiler/indirectSelfReference.ts(2,7): error TS2506: 'b' is referenced directly or indirectly in its own base expression. -==== tests/cases/compiler/indirectSelfReference.ts (2 errors) ==== +==== tests/cases/compiler/indirectSelfReference.ts (3 errors) ==== class a extends b{ } ~ !!! error TS2506: 'a' is referenced directly or indirectly in its own base expression. + ~ +!!! error TS2449: Class 'b' used before its declaration. class b extends a{ } ~ !!! error TS2506: 'b' is referenced directly or indirectly in its own base expression. \ No newline at end of file diff --git a/tests/baselines/reference/indirectSelfReferenceGeneric.errors.txt b/tests/baselines/reference/indirectSelfReferenceGeneric.errors.txt index 5a6aeed5de..d1cdbf1da5 100644 --- a/tests/baselines/reference/indirectSelfReferenceGeneric.errors.txt +++ b/tests/baselines/reference/indirectSelfReferenceGeneric.errors.txt @@ -1,11 +1,14 @@ tests/cases/compiler/indirectSelfReferenceGeneric.ts(1,7): error TS2506: 'a' is referenced directly or indirectly in its own base expression. +tests/cases/compiler/indirectSelfReferenceGeneric.ts(1,20): error TS2449: Class 'b' used before its declaration. tests/cases/compiler/indirectSelfReferenceGeneric.ts(2,7): error TS2506: 'b' is referenced directly or indirectly in its own base expression. -==== tests/cases/compiler/indirectSelfReferenceGeneric.ts (2 errors) ==== +==== tests/cases/compiler/indirectSelfReferenceGeneric.ts (3 errors) ==== class a extends b { } ~ !!! error TS2506: 'a' is referenced directly or indirectly in its own base expression. + ~ +!!! error TS2449: Class 'b' used before its declaration. class b extends a { } ~ !!! error TS2506: 'b' is referenced directly or indirectly in its own base expression. \ No newline at end of file diff --git a/tests/baselines/reference/parserRealSource10.errors.txt b/tests/baselines/reference/parserRealSource10.errors.txt index d6199636e6..ae48cd79b5 100644 --- a/tests/baselines/reference/parserRealSource10.errors.txt +++ b/tests/baselines/reference/parserRealSource10.errors.txt @@ -1,4 +1,5 @@ tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(4,1): error TS6053: File 'tests/cases/conformance/parser/ecmascript5/typescript.ts' not found. +tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(127,33): error TS2449: Class 'TokenInfo' used before its declaration. tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(127,42): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(128,36): error TS2304: Cannot find name 'string'. tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(128,42): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. @@ -342,7 +343,7 @@ tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(356,53): error tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(449,40): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. -==== tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts (342 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts (343 errors) ==== // Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0. // See LICENSE.txt in the project root for complete license information. @@ -472,6 +473,8 @@ tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(449,40): error } export var tokenTable = new TokenInfo[]; + ~~~~~~~~~ +!!! error TS2449: Class 'TokenInfo' used before its declaration. ~~ !!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. export var nodeTypeTable = new string[]; diff --git a/tests/baselines/reference/privacyClassExtendsClauseDeclFile.errors.txt b/tests/baselines/reference/privacyClassExtendsClauseDeclFile.errors.txt index dd44005047..95378c4c69 100644 --- a/tests/baselines/reference/privacyClassExtendsClauseDeclFile.errors.txt +++ b/tests/baselines/reference/privacyClassExtendsClauseDeclFile.errors.txt @@ -1,8 +1,8 @@ tests/cases/compiler/privacyClassExtendsClauseDeclFile_GlobalFile.ts(16,67): error TS4020: 'extends' clause of exported class 'publicClassExtendingPrivateClassInModule' has or is using private name 'privateClassInPublicModule'. tests/cases/compiler/privacyClassExtendsClauseDeclFile_externalModule.ts(17,67): error TS4020: 'extends' clause of exported class 'publicClassExtendingPrivateClassInModule' has or is using private name 'privateClassInPublicModule'. -tests/cases/compiler/privacyClassExtendsClauseDeclFile_externalModule.ts(20,63): error TS2690: A class must be declared after its base class. +tests/cases/compiler/privacyClassExtendsClauseDeclFile_externalModule.ts(20,77): error TS2449: Class 'publicClassInPrivateModule' used before its declaration. tests/cases/compiler/privacyClassExtendsClauseDeclFile_externalModule.ts(22,69): error TS4020: 'extends' clause of exported class 'publicClassExtendingFromPrivateModuleClass' has or is using private name 'privateModule'. -tests/cases/compiler/privacyClassExtendsClauseDeclFile_externalModule.ts(22,69): error TS2690: A class must be declared after its base class. +tests/cases/compiler/privacyClassExtendsClauseDeclFile_externalModule.ts(22,83): error TS2449: Class 'publicClassInPrivateModule' used before its declaration. tests/cases/compiler/privacyClassExtendsClauseDeclFile_externalModule.ts(64,55): error TS4020: 'extends' clause of exported class 'publicClassExtendingPrivateClass' has or is using private name 'privateClass'. tests/cases/compiler/privacyClassExtendsClauseDeclFile_externalModule.ts(69,65): error TS4020: 'extends' clause of exported class 'publicClassExtendingFromPrivateModuleClass' has or is using private name 'privateModule'. @@ -30,14 +30,14 @@ tests/cases/compiler/privacyClassExtendsClauseDeclFile_externalModule.ts(69,65): } class privateClassExtendingFromPrivateModuleClass extends privateModule.publicClassInPrivateModule { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2449: Class 'publicClassInPrivateModule' used before its declaration. } export class publicClassExtendingFromPrivateModuleClass extends privateModule.publicClassInPrivateModule { // Should error ~~~~~~~~~~~~~ !!! error TS4020: 'extends' clause of exported class 'publicClassExtendingFromPrivateModuleClass' has or is using private name 'privateModule'. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2449: Class 'publicClassInPrivateModule' used before its declaration. } } diff --git a/tests/baselines/reference/recursiveBaseCheck3.errors.txt b/tests/baselines/reference/recursiveBaseCheck3.errors.txt index 97f7cadc3d..ba0ea669c5 100644 --- a/tests/baselines/reference/recursiveBaseCheck3.errors.txt +++ b/tests/baselines/reference/recursiveBaseCheck3.errors.txt @@ -1,12 +1,15 @@ tests/cases/compiler/recursiveBaseCheck3.ts(1,7): error TS2506: 'A' is referenced directly or indirectly in its own base expression. +tests/cases/compiler/recursiveBaseCheck3.ts(1,20): error TS2449: Class 'C' used before its declaration. tests/cases/compiler/recursiveBaseCheck3.ts(2,7): error TS2506: 'C' is referenced directly or indirectly in its own base expression. tests/cases/compiler/recursiveBaseCheck3.ts(4,9): error TS2339: Property 'blah' does not exist on type 'C<{}>'. -==== tests/cases/compiler/recursiveBaseCheck3.ts (3 errors) ==== +==== tests/cases/compiler/recursiveBaseCheck3.ts (4 errors) ==== class A extends C { } ~ !!! error TS2506: 'A' is referenced directly or indirectly in its own base expression. + ~ +!!! error TS2449: Class 'C' used before its declaration. class C extends A { } ~ !!! error TS2506: 'C' is referenced directly or indirectly in its own base expression. diff --git a/tests/baselines/reference/resolvingClassDeclarationWhenInBaseTypeResolution.errors.txt b/tests/baselines/reference/resolvingClassDeclarationWhenInBaseTypeResolution.errors.txt index b9e650b644..bfb9a5127f 100644 --- a/tests/baselines/reference/resolvingClassDeclarationWhenInBaseTypeResolution.errors.txt +++ b/tests/baselines/reference/resolvingClassDeclarationWhenInBaseTypeResolution.errors.txt @@ -1,34 +1,34 @@ -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(2,35): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(9,44): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(45,39): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(60,34): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(96,33): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(114,40): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(126,34): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(182,42): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(199,39): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(247,35): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(272,30): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(301,33): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(403,44): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(436,45): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(469,44): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(490,34): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(495,39): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(500,38): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(534,42): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(549,41): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(580,45): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(589,44): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(605,46): error TS2690: A class must be declared after its base class. -tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,42): error TS2690: A class must be declared after its base class. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(2,45): error TS2449: Class 'nitidus' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(9,56): error TS2449: Class 'mixtus' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(45,48): error TS2449: Class 'psilurus' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(60,44): error TS2449: Class 'jugularis' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(96,44): error TS2449: Class 'aurata' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(114,48): error TS2449: Class 'gilbertii' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(126,43): error TS2449: Class 'johorensis' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(182,54): error TS2449: Class 'falconeri' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(199,47): error TS2449: Class 'pygmaea' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(247,46): error TS2449: Class 'ciliolabrum' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(272,35): error TS2449: Class 'coludo' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(301,41): error TS2449: Class 'oreas' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(403,53): error TS2449: Class 'johorensis' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(436,55): error TS2449: Class 'punicus' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(469,52): error TS2449: Class 'stolzmanni' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(490,42): error TS2449: Class 'portoricensis' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(495,50): error TS2449: Class 'pelurus' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(500,49): error TS2449: Class 'lasiurus' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(534,50): error TS2449: Class 'stolzmanni' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(549,53): error TS2449: Class 'daphaenodon' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(580,54): error TS2449: Class 'johorensis' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(589,52): error TS2449: Class 'stolzmanni' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(605,55): error TS2449: Class 'psilurus' used before its declaration. +tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,53): error TS2449: Class 'lasiurus' used before its declaration. ==== tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts (24 errors) ==== module rionegrensis { export class caniventer extends Lanthanum.nitidus { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~~ +!!! error TS2449: Class 'nitidus' used before its declaration. salomonseni() : caniventer { var x : caniventer; () => { var y = this; }; return x; } uchidai() : lavali.xanthognathus { var x : lavali.xanthognathus; () => { var y = this; }; return x; } raffrayana() : lavali.otion { var x : lavali.otion; () => { var y = this; }; return x; } @@ -36,8 +36,8 @@ tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,42 nayaur() : gabriellae.amicus { var x : gabriellae.amicus; () => { var y = this; }; return x; } } export class veraecrucis extends trivirgatus.mixtus { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~ +!!! error TS2449: Class 'mixtus' used before its declaration. naso() : panamensis.setulosus> { var x : panamensis.setulosus>; () => { var y = this; }; return x; } vancouverensis() : imperfecta.ciliolabrum { var x : imperfecta.ciliolabrum; () => { var y = this; }; return x; } africana() : argurus.gilbertii, sagitta.cinereus> { var x : argurus.gilbertii, sagitta.cinereus>; () => { var y = this; }; return x; } @@ -74,8 +74,8 @@ tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,42 porcellus() : ruatanica.americanus { var x : ruatanica.americanus; () => { var y = this; }; return x; } } export class oralis extends caurinus.psilurus { - ~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~~~ +!!! error TS2449: Class 'psilurus' used before its declaration. cepapi() : caurinus.psilurus { var x : caurinus.psilurus; () => { var y = this; }; return x; } porteri() : lavali.thaeleri { var x : lavali.thaeleri; () => { var y = this; }; return x; } bindi() : caurinus.mahaganus> { var x : caurinus.mahaganus>; () => { var y = this; }; return x; } @@ -91,8 +91,8 @@ tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,42 eisentrauti() : rendalli.zuluensis { var x : rendalli.zuluensis; () => { var y = this; }; return x; } } export class sumatrana extends Lanthanum.jugularis { - ~~~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~~~~ +!!! error TS2449: Class 'jugularis' used before its declaration. wolffsohni() : Lanthanum.suillus { var x : Lanthanum.suillus; () => { var y = this; }; return x; } geata() : ruatanica.hector { var x : ruatanica.hector; () => { var y = this; }; return x; } awashensis() : petrophilus.minutilla { var x : petrophilus.minutilla; () => { var y = this; }; return x; } @@ -129,8 +129,8 @@ tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,42 olchonensis() : rendalli.crenulata { var x : rendalli.crenulata; () => { var y = this; }; return x; } } export class durangae extends dogramacii.aurata { - ~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~ +!!! error TS2449: Class 'aurata' used before its declaration. Californium() : panamensis.setulosus { var x : panamensis.setulosus; () => { var y = this; }; return x; } Flerovium() : howi.angulatus { var x : howi.angulatus; () => { var y = this; }; return x; } phrudus() : sagitta.stolzmanni { var x : sagitta.stolzmanni; () => { var y = this; }; return x; } @@ -149,8 +149,8 @@ tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,42 anatolicus() : julianae.steerii { var x : julianae.steerii; () => { var y = this; }; return x; } } export class nitidus extends argurus.gilbertii { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~~~~ +!!! error TS2449: Class 'gilbertii' used before its declaration. granatensis() : quasiater.bobrinskoi { var x : quasiater.bobrinskoi; () => { var y = this; }; return x; } negligens() : minutus.inez { var x : minutus.inez; () => { var y = this; }; return x; } lewisi() : julianae.oralis { var x : julianae.oralis; () => { var y = this; }; return x; } @@ -163,8 +163,8 @@ tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,42 bicornis() : dogramacii.kaiseri { var x : dogramacii.kaiseri; () => { var y = this; }; return x; } } export class megalonyx extends caurinus.johorensis { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~~~~~ +!!! error TS2449: Class 'johorensis' used before its declaration. phillipsii() : macrorhinos.konganensis { var x : macrorhinos.konganensis; () => { var y = this; }; return x; } melanogaster() : rionegrensis.veraecrucis { var x : rionegrensis.veraecrucis; () => { var y = this; }; return x; } elaphus() : nitidus { var x : nitidus; () => { var y = this; }; return x; } @@ -221,8 +221,8 @@ tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,42 biacensis() : howi.coludo { var x : howi.coludo; () => { var y = this; }; return x; } } export class crenulata extends trivirgatus.falconeri { - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~~~~ +!!! error TS2449: Class 'falconeri' used before its declaration. salvanius() : howi.coludo { var x : howi.coludo; () => { var y = this; }; return x; } maritimus() : ruatanica.americanus { var x : ruatanica.americanus; () => { var y = this; }; return x; } edax() : lutreolus.cor>, rionegrensis.caniventer> { var x : lutreolus.cor>, rionegrensis.caniventer>; () => { var y = this; }; return x; } @@ -240,8 +240,8 @@ tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,42 vallinus() : sagitta.sicarius { var x : sagitta.sicarius; () => { var y = this; }; return x; } } export class mixtus extends argurus.pygmaea> { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~~ +!!! error TS2449: Class 'pygmaea' used before its declaration. ochrogaster() : dogramacii.aurata { var x : dogramacii.aurata; () => { var y = this; }; return x; } bryophilus() : macrorhinos.marmosurus>> { var x : macrorhinos.marmosurus>>; () => { var y = this; }; return x; } liechtensteini() : rendalli.zuluensis { var x : rendalli.zuluensis; () => { var y = this; }; return x; } @@ -290,8 +290,8 @@ tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,42 } module ruatanica { export class americanus extends imperfecta.ciliolabrum { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~~~~~~ +!!! error TS2449: Class 'ciliolabrum' used before its declaration. nasoloi() : macrorhinos.konganensis { var x : macrorhinos.konganensis; () => { var y = this; }; return x; } mystacalis() : howi.angulatus { var x : howi.angulatus; () => { var y = this; }; return x; } fardoulisi() : trivirgatus.oconnelli { var x : trivirgatus.oconnelli; () => { var y = this; }; return x; } @@ -317,8 +317,8 @@ tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,42 export class beisa { } export class otion extends howi.coludo { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~ +!!! error TS2449: Class 'coludo' used before its declaration. bonaerensis() : provocax.melanoleuca { var x : provocax.melanoleuca; () => { var y = this; }; return x; } dussumieri() : nigra.gracilis { var x : nigra.gracilis; () => { var y = this; }; return x; } osvaldoreigi() : julianae.albidens { var x : julianae.albidens; () => { var y = this; }; return x; } @@ -348,8 +348,8 @@ tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,42 coyhaiquensis() : caurinus.mahaganus, panglima.abidi>, lutreolus.punicus> { var x : caurinus.mahaganus, panglima.abidi>, lutreolus.punicus>; () => { var y = this; }; return x; } } export class thaeleri extends argurus.oreas { - ~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~ +!!! error TS2449: Class 'oreas' used before its declaration. coromandra() : julianae.galapagoensis { var x : julianae.galapagoensis; () => { var y = this; }; return x; } parvipes() : nigra.dolichurus { var x : nigra.dolichurus; () => { var y = this; }; return x; } sponsorius() : rionegrensis.veraecrucis, julianae.steerii> { var x : rionegrensis.veraecrucis, julianae.steerii>; () => { var y = this; }; return x; } @@ -452,8 +452,8 @@ tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,42 } module panglima { export class amphibius extends caurinus.johorensis, Lanthanum.jugularis> { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~~~~~ +!!! error TS2449: Class 'johorensis' used before its declaration. bottegi(): macrorhinos.marmosurus, gabriellae.echinatus>, sagitta.stolzmanni> { var x: macrorhinos.marmosurus, gabriellae.echinatus>, sagitta.stolzmanni>; () => { var y = this; }; return x; } jerdoni(): macrorhinos.daphaenodon { var x: macrorhinos.daphaenodon; () => { var y = this; }; return x; } camtschatica(): samarensis.pallidus { var x: samarensis.pallidus; () => { var y = this; }; return x; } @@ -487,8 +487,8 @@ tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,42 } module minutus { export class himalayana extends lutreolus.punicus { - ~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~~ +!!! error TS2449: Class 'punicus' used before its declaration. simoni(): argurus.netscheri> { var x: argurus.netscheri>; () => { var y = this; }; return x; } lobata(): samarensis.pallidus { var x: samarensis.pallidus; () => { var y = this; }; return x; } rusticus(): dogramacii.aurata { var x: dogramacii.aurata; () => { var y = this; }; return x; } @@ -522,8 +522,8 @@ tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,42 } module howi { export class angulatus extends sagitta.stolzmanni { - ~~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~~~~~ +!!! error TS2449: Class 'stolzmanni' used before its declaration. pennatus(): howi.marcanoi { var x: howi.marcanoi; () => { var y = this; }; return x; } } } @@ -545,22 +545,22 @@ tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,42 } module sagitta { export class walkeri extends minutus.portoricensis { - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~~~~~~~~ +!!! error TS2449: Class 'portoricensis' used before its declaration. maracajuensis(): samarensis.cahirinus { var x: samarensis.cahirinus; () => { var y = this; }; return x; } } } module minutus { export class inez extends samarensis.pelurus { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~~ +!!! error TS2449: Class 'pelurus' used before its declaration. vexillaris(): samarensis.cahirinus { var x: samarensis.cahirinus; () => { var y = this; }; return x; } } } module macrorhinos { export class konganensis extends imperfecta.lasiurus { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~~~ +!!! error TS2449: Class 'lasiurus' used before its declaration. } } module panamensis { @@ -595,8 +595,8 @@ tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,42 } module samarensis { export class pelurus extends sagitta.stolzmanni { - ~~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~~~~~ +!!! error TS2449: Class 'stolzmanni' used before its declaration. Palladium(): panamensis.linulus { var x: panamensis.linulus; () => { var y = this; }; return x; } castanea(): argurus.netscheri, julianae.oralis> { var x: argurus.netscheri, julianae.oralis>; () => { var y = this; }; return x; } chamek(): argurus.pygmaea { var x: argurus.pygmaea; () => { var y = this; }; return x; } @@ -612,8 +612,8 @@ tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,42 olitor(): rionegrensis.veraecrucis { var x: rionegrensis.veraecrucis; () => { var y = this; }; return x; } } export class fuscus extends macrorhinos.daphaenodon { - ~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~~~~~~ +!!! error TS2449: Class 'daphaenodon' used before its declaration. planifrons(): nigra.gracilis { var x: nigra.gracilis; () => { var y = this; }; return x; } badia(): julianae.sumatrana { var x: julianae.sumatrana; () => { var y = this; }; return x; } prymnolopha(): sagitta.walkeri { var x: sagitta.walkeri; () => { var y = this; }; return x; } @@ -645,8 +645,8 @@ tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,42 } module sagitta { export class leptoceros extends caurinus.johorensis> { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~~~~~ +!!! error TS2449: Class 'johorensis' used before its declaration. victus(): rionegrensis.caniventer { var x: rionegrensis.caniventer; () => { var y = this; }; return x; } hoplomyoides(): panglima.fundatus, nigra.gracilis> { var x: panglima.fundatus, nigra.gracilis>; () => { var y = this; }; return x; } gratiosus(): lavali.lepturus { var x: lavali.lepturus; () => { var y = this; }; return x; } @@ -656,8 +656,8 @@ tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,42 } module daubentonii { export class nigricans extends sagitta.stolzmanni { - ~~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~~~~~ +!!! error TS2449: Class 'stolzmanni' used before its declaration. woosnami(): dogramacii.robustulus { var x: dogramacii.robustulus; () => { var y = this; }; return x; } } } @@ -674,8 +674,8 @@ tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,42 } module chrysaeolus { export class sarasinorum extends caurinus.psilurus { - ~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~~~ +!!! error TS2449: Class 'psilurus' used before its declaration. belzebul(): samarensis.pallidus { var x: samarensis.pallidus; () => { var y = this; }; return x; } hinpoon(): nigra.caucasica { var x: nigra.caucasica; () => { var y = this; }; return x; } kandti(): quasiater.wattsi { var x: quasiater.wattsi; () => { var y = this; }; return x; } @@ -840,8 +840,8 @@ tests/cases/compiler/resolvingClassDeclarationWhenInBaseTypeResolution.ts(769,42 } module gabriellae { export class klossii extends imperfecta.lasiurus { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2690: A class must be declared after its base class. + ~~~~~~~~ +!!! error TS2449: Class 'lasiurus' used before its declaration. } export class amicus { pirrensis(): argurus.luctuosa { var x: argurus.luctuosa; () => { var y = this; }; return x; } diff --git a/tests/baselines/reference/symbolProperty33.errors.txt b/tests/baselines/reference/symbolProperty33.errors.txt index b1dab90db3..a8e95fc5bd 100644 --- a/tests/baselines/reference/symbolProperty33.errors.txt +++ b/tests/baselines/reference/symbolProperty33.errors.txt @@ -1,11 +1,11 @@ -tests/cases/conformance/es6/Symbols/symbolProperty33.ts(1,18): error TS2690: A class must be declared after its base class. +tests/cases/conformance/es6/Symbols/symbolProperty33.ts(1,18): error TS2449: Class 'C2' used before its declaration. tests/cases/conformance/es6/Symbols/symbolProperty33.ts(7,6): error TS1023: An index signature parameter type must be 'string' or 'number'. ==== tests/cases/conformance/es6/Symbols/symbolProperty33.ts (2 errors) ==== class C1 extends C2 { ~~ -!!! error TS2690: A class must be declared after its base class. +!!! error TS2449: Class 'C2' used before its declaration. [Symbol.toStringTag]() { return { x: "" }; } diff --git a/tests/baselines/reference/symbolProperty34.errors.txt b/tests/baselines/reference/symbolProperty34.errors.txt index 98a9875bd5..3ff62c12ad 100644 --- a/tests/baselines/reference/symbolProperty34.errors.txt +++ b/tests/baselines/reference/symbolProperty34.errors.txt @@ -1,11 +1,11 @@ -tests/cases/conformance/es6/Symbols/symbolProperty34.ts(1,18): error TS2690: A class must be declared after its base class. +tests/cases/conformance/es6/Symbols/symbolProperty34.ts(1,18): error TS2449: Class 'C2' used before its declaration. tests/cases/conformance/es6/Symbols/symbolProperty34.ts(7,6): error TS1023: An index signature parameter type must be 'string' or 'number'. ==== tests/cases/conformance/es6/Symbols/symbolProperty34.ts (2 errors) ==== class C1 extends C2 { ~~ -!!! error TS2690: A class must be declared after its base class. +!!! error TS2449: Class 'C2' used before its declaration. [Symbol.toStringTag]() { return { x: "" }; } From 21ef9078adcdbee99c5ebf2041850ea7562cb55c Mon Sep 17 00:00:00 2001 From: Jason Ramsay Date: Thu, 23 Feb 2017 15:52:38 -0800 Subject: [PATCH 029/164] Wrapping LSHost's cancellationtoken with a throttle --- .../unittests/tsserverProjectSystem.ts | 7 +- src/server/editorServices.ts | 3 +- src/server/lsHost.ts | 1 + src/server/session.ts | 5 +- src/services/navigationBar.ts | 73 ++++++++++--------- src/services/services.ts | 30 ++++++++ src/services/shims.ts | 23 ------ 7 files changed, 80 insertions(+), 62 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index d9abb0a907..353d0e2e18 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -176,11 +176,11 @@ namespace ts.projectSystem { } }; - export function createSession(host: server.ServerHost, typingsInstaller?: server.ITypingsInstaller, projectServiceEventHandler?: server.ProjectServiceEventHandler, cancellationToken?: server.ServerCancellationToken) { + export function createSession(host: server.ServerHost, typingsInstaller?: server.ITypingsInstaller, projectServiceEventHandler?: server.ProjectServiceEventHandler, cancellationToken?: server.ServerCancellationToken, throttleWaitMilliseconds?: number) { if (typingsInstaller === undefined) { typingsInstaller = new TestTypingsInstaller("/a/data/", /*throttleLimit*/5, host); } - return new TestSession(host, cancellationToken || server.nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ projectServiceEventHandler !== undefined, projectServiceEventHandler); + return new TestSession(host, cancellationToken || server.nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ projectServiceEventHandler !== undefined, projectServiceEventHandler, throttleWaitMilliseconds); } export interface CreateProjectServiceParameters { @@ -3320,6 +3320,7 @@ namespace ts.projectSystem { }, resetRequest: noop } + const session = createSession(host, /*typingsInstaller*/ undefined, /*projectServiceEventHandler*/ undefined, cancellationToken); expectedRequestId = session.getNextSeq(); @@ -3492,7 +3493,7 @@ namespace ts.projectSystem { }; const cancellationToken = new TestServerCancellationToken(/*cancelAfterRequest*/ 3); const host = createServerHost([f1, config]); - const session = createSession(host, /*typingsInstaller*/ undefined, () => { }, cancellationToken); + const session = createSession(host, /*typingsInstaller*/ undefined, () => { }, cancellationToken, /*throttleWaitMilliseconds*/ 0); { session.executeCommandSeq({ command: "open", diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 36aa3939c8..4067d85fb3 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -270,7 +270,8 @@ namespace ts.server { public readonly cancellationToken: HostCancellationToken, public readonly useSingleInferredProject: boolean, readonly typingsInstaller: ITypingsInstaller = nullTypingsInstaller, - private readonly eventHandler?: ProjectServiceEventHandler) { + private readonly eventHandler?: ProjectServiceEventHandler, + public readonly throttleWaitMilliseconds?: number) { Debug.assert(!!host.createHash, "'ServerHost.createHash' is required for ProjectService"); diff --git a/src/server/lsHost.ts b/src/server/lsHost.ts index eee80d82e7..ec655c545e 100644 --- a/src/server/lsHost.ts +++ b/src/server/lsHost.ts @@ -16,6 +16,7 @@ namespace ts.server { readonly realpath?: (path: string) => string; constructor(private readonly host: ServerHost, private readonly project: Project, private readonly cancellationToken: HostCancellationToken) { + this.cancellationToken = new ThrottledCancellationToken(cancellationToken, project.projectService.throttleWaitMilliseconds); this.getCanonicalFileName = ts.createGetCanonicalFileName(this.host.useCaseSensitiveFileNames); if (host.trace) { diff --git a/src/server/session.ts b/src/server/session.ts index 262ba8da1d..e7b4fc4bd4 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -338,7 +338,8 @@ namespace ts.server { private hrtime: (start?: number[]) => number[], protected logger: Logger, protected readonly canUseEvents: boolean, - eventHandler?: ProjectServiceEventHandler) { + eventHandler?: ProjectServiceEventHandler, + private readonly throttleWaitMilliseconds?: number) { this.eventHander = canUseEvents ? eventHandler || (event => this.defaultEventHandler(event)) @@ -353,7 +354,7 @@ namespace ts.server { isCancellationRequested: () => cancellationToken.isCancellationRequested() } this.errorCheck = new MultistepOperation(multistepOperationHost); - this.projectService = new ProjectService(host, logger, cancellationToken, useSingleInferredProject, typingsInstaller, this.eventHander); + this.projectService = new ProjectService(host, logger, cancellationToken, useSingleInferredProject, typingsInstaller, this.eventHander, this.throttleWaitMilliseconds); this.gcTimer = new GcTimer(host, /*delay*/ 7000, logger); } diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 811762fb73..7a2508fcfd 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -2,6 +2,36 @@ /* @internal */ namespace ts.NavigationBar { + /** + * Matches all whitespace characters in a string. Eg: + * + * "app. + * + * onactivated" + * + * matches because of the newline, whereas + * + * "app.onactivated" + * + * does not match. + */ + const whiteSpaceRegex = /\s+/g; + + // Keep sourceFile handy so we don't have to search for it every time we need to call `getText`. + let curCancellationToken: CancellationToken; + let curSourceFile: SourceFile; + + /** + * For performance, we keep navigation bar parents on a stack rather than passing them through each recursion. + * `parent` is the current parent and is *not* stored in parentsStack. + * `startNode` sets a new parent and `endNode` returns to the previous parent. + */ + let parentsStack: NavigationBarNode[] = []; + let parent: NavigationBarNode; + + // NavigationBarItem requires an array, but will not mutate it, so just give it this for performance. + let emptyChildItemArray: NavigationBarItem[] = []; + /** * Represents a navigation bar item and its children. * The returned NavigationBarItem is more complicated and doesn't include 'parent', so we use these to do work before converting. @@ -21,8 +51,7 @@ namespace ts.NavigationBar { return map(topLevelItems(rootNavigationBarNode(sourceFile)), convertToTopLevelItem); } finally { - curSourceFile = undefined; - curCancellationToken = undefined; + reset(); } } @@ -33,14 +62,18 @@ namespace ts.NavigationBar { return convertToTree(rootNavigationBarNode(sourceFile)); } finally { - curSourceFile = undefined; - curCancellationToken = undefined; + reset(); } } - // Keep sourceFile handy so we don't have to search for it every time we need to call `getText`. - let curCancellationToken: CancellationToken; - let curSourceFile: SourceFile; + function reset() { + curSourceFile = undefined; + curCancellationToken = undefined; + parentsStack = []; + parent = undefined; + emptyChildItemArray = []; + } + function nodeText(node: Node): string { return node.getText(curSourceFile); } @@ -58,14 +91,6 @@ namespace ts.NavigationBar { } } - /* - For performance, we keep navigation bar parents on a stack rather than passing them through each recursion. - `parent` is the current parent and is *not* stored in parentsStack. - `startNode` sets a new parent and `endNode` returns to the previous parent. - */ - const parentsStack: NavigationBarNode[] = []; - let parent: NavigationBarNode; - function rootNavigationBarNode(sourceFile: SourceFile): NavigationBarNode { Debug.assert(!parentsStack.length); const root: NavigationBarNode = { node: sourceFile, additionalNodes: undefined, parent: undefined, children: undefined, indent: 0 }; @@ -500,9 +525,6 @@ namespace ts.NavigationBar { } } - // NavigationBarItem requires an array, but will not mutate it, so just give it this for performance. - const emptyChildItemArray: NavigationBarItem[] = []; - function convertToTree(n: NavigationBarNode): NavigationTree { return { text: getItemName(n.node), @@ -623,19 +645,4 @@ namespace ts.NavigationBar { function isFunctionOrClassExpression(node: Node): boolean { return node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.ArrowFunction || node.kind === SyntaxKind.ClassExpression; } - - /** - * Matches all whitespace characters in a string. Eg: - * - * "app. - * - * onactivated" - * - * matches because of the newline, whereas - * - * "app.onactivated" - * - * does not match. - */ - const whiteSpaceRegex = /\s+/g; } diff --git a/src/services/services.ts b/src/services/services.ts index cef307eb8f..d808ed28b7 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -972,6 +972,36 @@ namespace ts { } } + /* @internal */ + /** A cancellation that throttles calls to the host */ + export class ThrottledCancellationToken implements CancellationToken { + // Store when we last tried to cancel. Checking cancellation can be expensive (as we have + // to marshall over to the host layer). So we only bother actually checking once enough + // time has passed. + private lastCancellationCheckTime = 0; + + constructor(private hostCancellationToken: HostCancellationToken, private readonly throttleWaitMilliseconds = 20) { + } + + public isCancellationRequested(): boolean { + const time = timestamp(); + const duration = Math.abs(time - this.lastCancellationCheckTime); + if (duration >= this.throttleWaitMilliseconds) { + // Check no more than once every throttle wait milliseconds + this.lastCancellationCheckTime = time; + return this.hostCancellationToken.isCancellationRequested(); + } + + return false; + } + + public throwIfCancellationRequested(): void { + if (this.isCancellationRequested()) { + throw new OperationCanceledException(); + } + } + } + export function createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory())): LanguageService { diff --git a/src/services/shims.ts b/src/services/shims.ts index 6fe9aed144..de2fd39b8a 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -469,29 +469,6 @@ namespace ts { } } - /** A cancellation that throttles calls to the host */ - class ThrottledCancellationToken implements HostCancellationToken { - // Store when we last tried to cancel. Checking cancellation can be expensive (as we have - // to marshall over to the host layer). So we only bother actually checking once enough - // time has passed. - private lastCancellationCheckTime = 0; - - constructor(private hostCancellationToken: HostCancellationToken) { - } - - public isCancellationRequested(): boolean { - const time = timestamp(); - const duration = Math.abs(time - this.lastCancellationCheckTime); - if (duration > 10) { - // Check no more than once every 10 ms. - this.lastCancellationCheckTime = time; - return this.hostCancellationToken.isCancellationRequested(); - } - - return false; - } - } - export class CoreServicesShimHostAdapter implements ParseConfigHost, ModuleResolutionHost { public directoryExists: (directoryName: string) => boolean; From 1415cf4ea2dbde9077844537f0ebab549f0f8a98 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Fri, 24 Feb 2017 17:48:06 -0800 Subject: [PATCH 030/164] Update tests and baselines to declare class declaration before use --- .../reference/ES5For-ofTypeCheck10.errors.txt | 13 +++--- .../reference/ES5For-ofTypeCheck10.js | 11 +++-- .../classDoesNotDependOnBaseTypes.js | 24 +++++----- .../classDoesNotDependOnBaseTypes.symbols | 43 +++++++++-------- .../classDoesNotDependOnBaseTypes.types | 33 +++++++------ ...5ExportDefaultClassDeclaration3.errors.txt | 20 ++++++++ .../es5ExportDefaultClassDeclaration3.symbols | 30 ------------ .../es5ExportDefaultClassDeclaration3.types | 33 ------------- .../exportAssignmentOfGenericType1.errors.txt | 17 +++++++ tests/baselines/reference/for-of14.errors.txt | 14 +++--- tests/baselines/reference/for-of14.js | 12 ++--- tests/baselines/reference/for-of15.errors.txt | 14 +++--- tests/baselines/reference/for-of15.js | 12 ++--- tests/baselines/reference/for-of16.errors.txt | 14 +++--- tests/baselines/reference/for-of16.js | 12 ++--- tests/baselines/reference/for-of17.errors.txt | 14 +++--- tests/baselines/reference/for-of17.js | 12 ++--- tests/baselines/reference/for-of18.js | 12 ++--- tests/baselines/reference/for-of18.symbols | 25 +++++----- tests/baselines/reference/for-of18.types | 17 +++---- tests/baselines/reference/for-of19.js | 14 +++--- tests/baselines/reference/for-of19.symbols | 30 ++++++------ tests/baselines/reference/for-of19.types | 18 ++++---- tests/baselines/reference/for-of20.js | 14 +++--- tests/baselines/reference/for-of20.symbols | 30 ++++++------ tests/baselines/reference/for-of20.types | 18 ++++---- tests/baselines/reference/for-of21.js | 14 +++--- tests/baselines/reference/for-of21.symbols | 30 ++++++------ tests/baselines/reference/for-of21.types | 18 ++++---- tests/baselines/reference/for-of22.js | 16 +++---- tests/baselines/reference/for-of22.symbols | 32 ++++++------- tests/baselines/reference/for-of22.types | 20 ++++---- tests/baselines/reference/for-of23.js | 14 +++--- tests/baselines/reference/for-of23.symbols | 30 ++++++------ tests/baselines/reference/for-of23.types | 20 ++++---- tests/baselines/reference/for-of25.js | 12 ++--- tests/baselines/reference/for-of25.symbols | 19 ++++---- tests/baselines/reference/for-of25.types | 17 +++---- tests/baselines/reference/for-of26.js | 12 ++--- tests/baselines/reference/for-of26.symbols | 23 +++++----- tests/baselines/reference/for-of26.types | 17 +++---- tests/baselines/reference/for-of27.js | 8 ++-- tests/baselines/reference/for-of27.symbols | 11 +++-- tests/baselines/reference/for-of27.types | 11 +++-- tests/baselines/reference/for-of28.js | 8 ++-- tests/baselines/reference/for-of28.symbols | 15 +++--- tests/baselines/reference/for-of28.types | 11 +++-- tests/baselines/reference/for-of30.errors.txt | 22 ++++----- tests/baselines/reference/for-of30.js | 8 ++-- tests/baselines/reference/for-of31.errors.txt | 26 +++++------ tests/baselines/reference/for-of31.js | 8 ++-- tests/baselines/reference/for-of33.errors.txt | 14 +++--- tests/baselines/reference/for-of33.js | 8 ++-- tests/baselines/reference/for-of34.errors.txt | 14 +++--- tests/baselines/reference/for-of34.js | 8 ++-- tests/baselines/reference/for-of35.errors.txt | 14 +++--- tests/baselines/reference/for-of35.js | 8 ++-- .../reference/iterableArrayPattern1.js | 7 +-- .../reference/iterableArrayPattern1.symbols | 21 +++++---- .../reference/iterableArrayPattern1.types | 13 +++--- .../iterableArrayPattern10.errors.txt | 15 +++--- .../reference/iterableArrayPattern10.js | 11 +++-- .../reference/iterableArrayPattern11.js | 12 +++-- .../reference/iterableArrayPattern11.symbols | 43 ++++++++--------- .../reference/iterableArrayPattern11.types | 27 +++++------ .../reference/iterableArrayPattern12.js | 11 +++-- .../reference/iterableArrayPattern12.symbols | 43 ++++++++--------- .../reference/iterableArrayPattern12.types | 27 +++++------ .../reference/iterableArrayPattern13.js | 11 +++-- .../reference/iterableArrayPattern13.symbols | 41 +++++++++-------- .../reference/iterableArrayPattern13.types | 23 +++++----- .../iterableArrayPattern14.errors.txt | 13 +++--- .../reference/iterableArrayPattern14.js | 11 +++-- .../iterableArrayPattern15.errors.txt | 13 +++--- .../reference/iterableArrayPattern15.js | 11 +++-- .../iterableArrayPattern16.errors.txt | 5 +- .../iterableArrayPattern17.errors.txt | 21 +++++---- .../reference/iterableArrayPattern17.js | 11 +++-- .../iterableArrayPattern18.errors.txt | 15 +++--- .../reference/iterableArrayPattern18.js | 11 +++-- .../iterableArrayPattern19.errors.txt | 15 +++--- .../reference/iterableArrayPattern19.js | 11 +++-- .../reference/iterableArrayPattern2.js | 7 +-- .../reference/iterableArrayPattern2.symbols | 21 +++++---- .../reference/iterableArrayPattern2.types | 13 +++--- .../iterableArrayPattern20.errors.txt | 13 +++--- .../reference/iterableArrayPattern20.js | 11 +++-- .../reference/iterableArrayPattern3.js | 11 +++-- .../reference/iterableArrayPattern3.symbols | 45 +++++++++--------- .../reference/iterableArrayPattern3.types | 29 ++++++------ .../reference/iterableArrayPattern4.js | 11 +++-- .../reference/iterableArrayPattern4.symbols | 45 +++++++++--------- .../reference/iterableArrayPattern4.types | 31 +++++++------ .../iterableArrayPattern5.errors.txt | 13 +++--- .../reference/iterableArrayPattern5.js | 11 +++-- .../iterableArrayPattern6.errors.txt | 15 +++--- .../reference/iterableArrayPattern6.js | 11 +++-- .../iterableArrayPattern7.errors.txt | 15 +++--- .../reference/iterableArrayPattern7.js | 11 +++-- .../iterableArrayPattern8.errors.txt | 13 +++--- .../reference/iterableArrayPattern8.js | 11 +++-- .../reference/iteratorSpreadInArray.js | 9 ++-- .../reference/iteratorSpreadInArray.symbols | 19 ++++---- .../reference/iteratorSpreadInArray.types | 15 +++--- .../iteratorSpreadInArray10.errors.txt | 12 ++--- .../reference/iteratorSpreadInArray10.js | 8 ++-- .../reference/iteratorSpreadInArray2.js | 9 ++-- .../reference/iteratorSpreadInArray2.symbols | 31 +++++++------ .../reference/iteratorSpreadInArray2.types | 21 +++++---- .../reference/iteratorSpreadInArray3.js | 8 ++-- .../reference/iteratorSpreadInArray3.symbols | 19 ++++---- .../reference/iteratorSpreadInArray3.types | 23 +++++----- .../reference/iteratorSpreadInArray4.js | 8 ++-- .../reference/iteratorSpreadInArray4.symbols | 19 ++++---- .../reference/iteratorSpreadInArray4.types | 19 ++++---- .../iteratorSpreadInArray5.errors.txt | 16 +++---- .../reference/iteratorSpreadInArray5.js | 8 ++-- .../iteratorSpreadInArray6.errors.txt | 18 ++++---- .../reference/iteratorSpreadInArray6.js | 12 ++--- .../reference/iteratorSpreadInArray7.js | 12 ++--- .../reference/iteratorSpreadInArray7.symbols | 29 ++++++------ .../reference/iteratorSpreadInArray7.types | 27 +++++------ .../iteratorSpreadInArray8.errors.txt | 12 ++--- .../reference/iteratorSpreadInArray8.js | 8 ++-- .../iteratorSpreadInArray9.errors.txt | 26 +++++------ .../reference/iteratorSpreadInArray9.js | 8 ++-- .../reference/iteratorSpreadInCall.errors.txt | 12 ++--- .../reference/iteratorSpreadInCall.js | 8 ++-- .../iteratorSpreadInCall10.errors.txt | 13 +++--- .../reference/iteratorSpreadInCall10.js | 9 ++-- .../reference/iteratorSpreadInCall11.js | 9 ++-- .../reference/iteratorSpreadInCall11.symbols | 29 ++++++------ .../reference/iteratorSpreadInCall11.types | 15 +++--- .../reference/iteratorSpreadInCall12.js | 8 ++-- .../reference/iteratorSpreadInCall12.symbols | 39 ++++++++-------- .../reference/iteratorSpreadInCall12.types | 29 ++++++------ .../iteratorSpreadInCall2.errors.txt | 12 ++--- .../reference/iteratorSpreadInCall2.js | 8 ++-- .../reference/iteratorSpreadInCall3.js | 8 ++-- .../reference/iteratorSpreadInCall3.symbols | 23 +++++----- .../reference/iteratorSpreadInCall3.types | 15 +++--- .../iteratorSpreadInCall4.errors.txt | 12 ++--- .../reference/iteratorSpreadInCall4.js | 8 ++-- .../reference/iteratorSpreadInCall5.js | 8 ++-- .../reference/iteratorSpreadInCall5.symbols | 35 +++++++------- .../reference/iteratorSpreadInCall5.types | 21 +++++---- .../iteratorSpreadInCall6.errors.txt | 12 ++--- .../reference/iteratorSpreadInCall6.js | 8 ++-- .../iteratorSpreadInCall7.errors.txt | 14 +++--- .../reference/iteratorSpreadInCall7.js | 8 ++-- .../iteratorSpreadInCall8.errors.txt | 14 +++--- .../reference/iteratorSpreadInCall8.js | 8 ++-- .../iteratorSpreadInCall9.errors.txt | 15 +++--- .../reference/iteratorSpreadInCall9.js | 9 ++-- ...ssInstantiationsWithDefaultConstructors.js | 16 +++---- ...tantiationsWithDefaultConstructors.symbols | 32 ++++++------- ...nstantiationsWithDefaultConstructors.types | 32 ++++++------- .../typeArgumentInferenceOrdering.js | 11 ++--- .../typeArgumentInferenceOrdering.symbols | 46 +++++++++---------- .../typeArgumentInferenceOrdering.types | 36 +++++++-------- ...ssInstantiationsWithDefaultConstructors.ts | 13 +++--- .../compiler/typeArgumentInferenceOrdering.ts | 6 +-- .../destructuring/iterableArrayPattern1.ts | 5 +- .../destructuring/iterableArrayPattern10.ts | 7 +-- .../destructuring/iterableArrayPattern11.ts | 7 +-- .../destructuring/iterableArrayPattern12.ts | 7 +-- .../destructuring/iterableArrayPattern13.ts | 7 +-- .../destructuring/iterableArrayPattern14.ts | 7 +-- .../destructuring/iterableArrayPattern15.ts | 7 +-- .../destructuring/iterableArrayPattern17.ts | 7 +-- .../destructuring/iterableArrayPattern18.ts | 7 +-- .../destructuring/iterableArrayPattern19.ts | 7 +-- .../destructuring/iterableArrayPattern2.ts | 5 +- .../destructuring/iterableArrayPattern20.ts | 7 +-- .../destructuring/iterableArrayPattern3.ts | 7 +-- .../destructuring/iterableArrayPattern4.ts | 7 +-- .../destructuring/iterableArrayPattern5.ts | 7 +-- .../destructuring/iterableArrayPattern6.ts | 7 +-- .../destructuring/iterableArrayPattern7.ts | 7 +-- .../destructuring/iterableArrayPattern8.ts | 7 +-- .../es6/for-ofStatements/for-of14.ts | 8 ++-- .../es6/for-ofStatements/for-of15.ts | 8 ++-- .../es6/for-ofStatements/for-of16.ts | 8 ++-- .../es6/for-ofStatements/for-of17.ts | 8 ++-- .../es6/for-ofStatements/for-of18.ts | 8 ++-- .../es6/for-ofStatements/for-of19.ts | 8 ++-- .../es6/for-ofStatements/for-of20.ts | 8 ++-- .../es6/for-ofStatements/for-of21.ts | 8 ++-- .../es6/for-ofStatements/for-of22.ts | 10 ++-- .../es6/for-ofStatements/for-of23.ts | 8 ++-- .../es6/for-ofStatements/for-of25.ts | 8 ++-- .../es6/for-ofStatements/for-of26.ts | 8 ++-- .../es6/for-ofStatements/for-of27.ts | 6 +-- .../es6/for-ofStatements/for-of28.ts | 6 +-- .../es6/for-ofStatements/for-of30.ts | 6 +-- .../es6/for-ofStatements/for-of31.ts | 6 +-- .../es6/for-ofStatements/for-of33.ts | 6 +-- .../es6/for-ofStatements/for-of34.ts | 6 +-- .../es6/for-ofStatements/for-of35.ts | 6 +-- .../es6/spread/iteratorSpreadInArray.ts | 6 +-- .../es6/spread/iteratorSpreadInArray10.ts | 6 +-- .../es6/spread/iteratorSpreadInArray2.ts | 6 +-- .../es6/spread/iteratorSpreadInArray3.ts | 6 +-- .../es6/spread/iteratorSpreadInArray4.ts | 6 +-- .../es6/spread/iteratorSpreadInArray5.ts | 6 +-- .../es6/spread/iteratorSpreadInArray6.ts | 8 ++-- .../es6/spread/iteratorSpreadInArray7.ts | 8 ++-- .../es6/spread/iteratorSpreadInArray8.ts | 6 +-- .../es6/spread/iteratorSpreadInArray9.ts | 6 +-- .../es6/spread/iteratorSpreadInCall.ts | 6 +-- .../es6/spread/iteratorSpreadInCall10.ts | 7 ++- .../es6/spread/iteratorSpreadInCall11.ts | 7 ++- .../es6/spread/iteratorSpreadInCall12.ts | 6 +-- .../es6/spread/iteratorSpreadInCall2.ts | 6 +-- .../es6/spread/iteratorSpreadInCall3.ts | 6 +-- .../es6/spread/iteratorSpreadInCall4.ts | 6 +-- .../es6/spread/iteratorSpreadInCall5.ts | 6 +-- .../es6/spread/iteratorSpreadInCall6.ts | 6 +-- .../es6/spread/iteratorSpreadInCall7.ts | 6 +-- .../es6/spread/iteratorSpreadInCall8.ts | 6 +-- .../es6/spread/iteratorSpreadInCall9.ts | 6 +-- .../for-ofStatements/ES5For-ofTypeCheck10.ts | 5 +- .../classDoesNotDependOnBaseTypes.ts | 14 +++--- 223 files changed, 1628 insertions(+), 1561 deletions(-) create mode 100644 tests/baselines/reference/es5ExportDefaultClassDeclaration3.errors.txt delete mode 100644 tests/baselines/reference/es5ExportDefaultClassDeclaration3.symbols delete mode 100644 tests/baselines/reference/es5ExportDefaultClassDeclaration3.types create mode 100644 tests/baselines/reference/exportAssignmentOfGenericType1.errors.txt diff --git a/tests/baselines/reference/ES5For-ofTypeCheck10.errors.txt b/tests/baselines/reference/ES5For-ofTypeCheck10.errors.txt index b762db8a04..7839958ba5 100644 --- a/tests/baselines/reference/ES5For-ofTypeCheck10.errors.txt +++ b/tests/baselines/reference/ES5For-ofTypeCheck10.errors.txt @@ -1,11 +1,8 @@ -tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts(1,15): error TS2495: Type 'StringIterator' is not an array type or a string type. -tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts(11,6): error TS2304: Cannot find name 'Symbol'. +tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts(10,6): error TS2304: Cannot find name 'Symbol'. +tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts(15,15): error TS2495: Type 'StringIterator' is not an array type or a string type. ==== tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts (2 errors) ==== - for (var v of new StringIterator) { } - ~~~~~~~~~~~~~~~~~~ -!!! error TS2495: Type 'StringIterator' is not an array type or a string type. // In ES3/5, you cannot for...of over an arbitrary iterable. class StringIterator { @@ -20,4 +17,8 @@ tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts(11,6 !!! error TS2304: Cannot find name 'Symbol'. return this; } - } \ No newline at end of file + } + + for (var v of new StringIterator) { } + ~~~~~~~~~~~~~~~~~~ +!!! error TS2495: Type 'StringIterator' is not an array type or a string type. \ No newline at end of file diff --git a/tests/baselines/reference/ES5For-ofTypeCheck10.js b/tests/baselines/reference/ES5For-ofTypeCheck10.js index 0fe92e289a..9b197c2d20 100644 --- a/tests/baselines/reference/ES5For-ofTypeCheck10.js +++ b/tests/baselines/reference/ES5For-ofTypeCheck10.js @@ -1,5 +1,4 @@ //// [ES5For-ofTypeCheck10.ts] -for (var v of new StringIterator) { } // In ES3/5, you cannot for...of over an arbitrary iterable. class StringIterator { @@ -12,12 +11,11 @@ class StringIterator { [Symbol.iterator]() { return this; } -} +} + +for (var v of new StringIterator) { } //// [ES5For-ofTypeCheck10.js] -for (var _i = 0, _a = new StringIterator; _i < _a.length; _i++) { - var v = _a[_i]; -} // In ES3/5, you cannot for...of over an arbitrary iterable. var StringIterator = (function () { function StringIterator() { @@ -33,3 +31,6 @@ var StringIterator = (function () { }; return StringIterator; }()); +for (var _i = 0, _a = new StringIterator; _i < _a.length; _i++) { + var v = _a[_i]; +} diff --git a/tests/baselines/reference/classDoesNotDependOnBaseTypes.js b/tests/baselines/reference/classDoesNotDependOnBaseTypes.js index c1642125fe..5b9892b9ab 100644 --- a/tests/baselines/reference/classDoesNotDependOnBaseTypes.js +++ b/tests/baselines/reference/classDoesNotDependOnBaseTypes.js @@ -1,16 +1,16 @@ //// [classDoesNotDependOnBaseTypes.ts] -var x: StringTree; -if (typeof x !== "string") { - x[0] = ""; - x[0] = new StringTreeCollection; -} - type StringTree = string | StringTreeCollection; class StringTreeCollectionBase { [n: number]: StringTree; } -class StringTreeCollection extends StringTreeCollectionBase { } +class StringTreeCollection extends StringTreeCollectionBase { } + +var x: StringTree; +if (typeof x !== "string") { + x[0] = ""; + x[0] = new StringTreeCollection; +} //// [classDoesNotDependOnBaseTypes.js] var __extends = (this && this.__extends) || (function () { @@ -23,11 +23,6 @@ var __extends = (this && this.__extends) || (function () { d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); -var x; -if (typeof x !== "string") { - x[0] = ""; - x[0] = new StringTreeCollection; -} var StringTreeCollectionBase = (function () { function StringTreeCollectionBase() { } @@ -40,3 +35,8 @@ var StringTreeCollection = (function (_super) { } return StringTreeCollection; }(StringTreeCollectionBase)); +var x; +if (typeof x !== "string") { + x[0] = ""; + x[0] = new StringTreeCollection; +} diff --git a/tests/baselines/reference/classDoesNotDependOnBaseTypes.symbols b/tests/baselines/reference/classDoesNotDependOnBaseTypes.symbols index e45b00f1e8..a7a421ebf5 100644 --- a/tests/baselines/reference/classDoesNotDependOnBaseTypes.symbols +++ b/tests/baselines/reference/classDoesNotDependOnBaseTypes.symbols @@ -1,32 +1,31 @@ === tests/cases/conformance/types/typeAliases/classDoesNotDependOnBaseTypes.ts === -var x: StringTree; ->x : Symbol(x, Decl(classDoesNotDependOnBaseTypes.ts, 0, 3)) ->StringTree : Symbol(StringTree, Decl(classDoesNotDependOnBaseTypes.ts, 4, 1)) - -if (typeof x !== "string") { ->x : Symbol(x, Decl(classDoesNotDependOnBaseTypes.ts, 0, 3)) - - x[0] = ""; ->x : Symbol(x, Decl(classDoesNotDependOnBaseTypes.ts, 0, 3)) - - x[0] = new StringTreeCollection; ->x : Symbol(x, Decl(classDoesNotDependOnBaseTypes.ts, 0, 3)) ->StringTreeCollection : Symbol(StringTreeCollection, Decl(classDoesNotDependOnBaseTypes.ts, 9, 1)) -} - type StringTree = string | StringTreeCollection; ->StringTree : Symbol(StringTree, Decl(classDoesNotDependOnBaseTypes.ts, 4, 1)) ->StringTreeCollection : Symbol(StringTreeCollection, Decl(classDoesNotDependOnBaseTypes.ts, 9, 1)) +>StringTree : Symbol(StringTree, Decl(classDoesNotDependOnBaseTypes.ts, 0, 0)) +>StringTreeCollection : Symbol(StringTreeCollection, Decl(classDoesNotDependOnBaseTypes.ts, 3, 1)) class StringTreeCollectionBase { ->StringTreeCollectionBase : Symbol(StringTreeCollectionBase, Decl(classDoesNotDependOnBaseTypes.ts, 6, 48)) +>StringTreeCollectionBase : Symbol(StringTreeCollectionBase, Decl(classDoesNotDependOnBaseTypes.ts, 0, 48)) [n: number]: StringTree; ->n : Symbol(n, Decl(classDoesNotDependOnBaseTypes.ts, 8, 5)) ->StringTree : Symbol(StringTree, Decl(classDoesNotDependOnBaseTypes.ts, 4, 1)) +>n : Symbol(n, Decl(classDoesNotDependOnBaseTypes.ts, 2, 5)) +>StringTree : Symbol(StringTree, Decl(classDoesNotDependOnBaseTypes.ts, 0, 0)) } class StringTreeCollection extends StringTreeCollectionBase { } ->StringTreeCollection : Symbol(StringTreeCollection, Decl(classDoesNotDependOnBaseTypes.ts, 9, 1)) ->StringTreeCollectionBase : Symbol(StringTreeCollectionBase, Decl(classDoesNotDependOnBaseTypes.ts, 6, 48)) +>StringTreeCollection : Symbol(StringTreeCollection, Decl(classDoesNotDependOnBaseTypes.ts, 3, 1)) +>StringTreeCollectionBase : Symbol(StringTreeCollectionBase, Decl(classDoesNotDependOnBaseTypes.ts, 0, 48)) +var x: StringTree; +>x : Symbol(x, Decl(classDoesNotDependOnBaseTypes.ts, 7, 3)) +>StringTree : Symbol(StringTree, Decl(classDoesNotDependOnBaseTypes.ts, 0, 0)) + +if (typeof x !== "string") { +>x : Symbol(x, Decl(classDoesNotDependOnBaseTypes.ts, 7, 3)) + + x[0] = ""; +>x : Symbol(x, Decl(classDoesNotDependOnBaseTypes.ts, 7, 3)) + + x[0] = new StringTreeCollection; +>x : Symbol(x, Decl(classDoesNotDependOnBaseTypes.ts, 7, 3)) +>StringTreeCollection : Symbol(StringTreeCollection, Decl(classDoesNotDependOnBaseTypes.ts, 3, 1)) +} diff --git a/tests/baselines/reference/classDoesNotDependOnBaseTypes.types b/tests/baselines/reference/classDoesNotDependOnBaseTypes.types index 54b67dfd6a..16dc984dc8 100644 --- a/tests/baselines/reference/classDoesNotDependOnBaseTypes.types +++ b/tests/baselines/reference/classDoesNotDependOnBaseTypes.types @@ -1,4 +1,20 @@ === tests/cases/conformance/types/typeAliases/classDoesNotDependOnBaseTypes.ts === +type StringTree = string | StringTreeCollection; +>StringTree : StringTree +>StringTreeCollection : StringTreeCollection + +class StringTreeCollectionBase { +>StringTreeCollectionBase : StringTreeCollectionBase + + [n: number]: StringTree; +>n : number +>StringTree : StringTree +} + +class StringTreeCollection extends StringTreeCollectionBase { } +>StringTreeCollection : StringTreeCollection +>StringTreeCollectionBase : StringTreeCollectionBase + var x: StringTree; >x : StringTree >StringTree : StringTree @@ -24,20 +40,3 @@ if (typeof x !== "string") { >new StringTreeCollection : StringTreeCollection >StringTreeCollection : typeof StringTreeCollection } - -type StringTree = string | StringTreeCollection; ->StringTree : StringTree ->StringTreeCollection : StringTreeCollection - -class StringTreeCollectionBase { ->StringTreeCollectionBase : StringTreeCollectionBase - - [n: number]: StringTree; ->n : number ->StringTree : StringTree -} - -class StringTreeCollection extends StringTreeCollectionBase { } ->StringTreeCollection : StringTreeCollection ->StringTreeCollectionBase : StringTreeCollectionBase - diff --git a/tests/baselines/reference/es5ExportDefaultClassDeclaration3.errors.txt b/tests/baselines/reference/es5ExportDefaultClassDeclaration3.errors.txt new file mode 100644 index 0000000000..951e8bbffd --- /dev/null +++ b/tests/baselines/reference/es5ExportDefaultClassDeclaration3.errors.txt @@ -0,0 +1,20 @@ +tests/cases/compiler/es5ExportDefaultClassDeclaration3.ts(2,21): error TS2449: Class 'C' used before its declaration. + + +==== tests/cases/compiler/es5ExportDefaultClassDeclaration3.ts (1 errors) ==== + + var before: C = new C(); + ~ +!!! error TS2449: Class 'C' used before its declaration. + + export default class C { + method(): C { + return new C(); + } + } + + var after: C = new C(); + + var t: typeof C = C; + + \ No newline at end of file diff --git a/tests/baselines/reference/es5ExportDefaultClassDeclaration3.symbols b/tests/baselines/reference/es5ExportDefaultClassDeclaration3.symbols deleted file mode 100644 index d5c8243161..0000000000 --- a/tests/baselines/reference/es5ExportDefaultClassDeclaration3.symbols +++ /dev/null @@ -1,30 +0,0 @@ -=== tests/cases/compiler/es5ExportDefaultClassDeclaration3.ts === - -var before: C = new C(); ->before : Symbol(before, Decl(es5ExportDefaultClassDeclaration3.ts, 1, 3)) ->C : Symbol(C, Decl(es5ExportDefaultClassDeclaration3.ts, 1, 24)) ->C : Symbol(C, Decl(es5ExportDefaultClassDeclaration3.ts, 1, 24)) - -export default class C { ->C : Symbol(C, Decl(es5ExportDefaultClassDeclaration3.ts, 1, 24)) - - method(): C { ->method : Symbol(C.method, Decl(es5ExportDefaultClassDeclaration3.ts, 3, 24)) ->C : Symbol(C, Decl(es5ExportDefaultClassDeclaration3.ts, 1, 24)) - - return new C(); ->C : Symbol(C, Decl(es5ExportDefaultClassDeclaration3.ts, 1, 24)) - } -} - -var after: C = new C(); ->after : Symbol(after, Decl(es5ExportDefaultClassDeclaration3.ts, 9, 3)) ->C : Symbol(C, Decl(es5ExportDefaultClassDeclaration3.ts, 1, 24)) ->C : Symbol(C, Decl(es5ExportDefaultClassDeclaration3.ts, 1, 24)) - -var t: typeof C = C; ->t : Symbol(t, Decl(es5ExportDefaultClassDeclaration3.ts, 11, 3)) ->C : Symbol(C, Decl(es5ExportDefaultClassDeclaration3.ts, 1, 24)) ->C : Symbol(C, Decl(es5ExportDefaultClassDeclaration3.ts, 1, 24)) - - diff --git a/tests/baselines/reference/es5ExportDefaultClassDeclaration3.types b/tests/baselines/reference/es5ExportDefaultClassDeclaration3.types deleted file mode 100644 index 1ed302ac45..0000000000 --- a/tests/baselines/reference/es5ExportDefaultClassDeclaration3.types +++ /dev/null @@ -1,33 +0,0 @@ -=== tests/cases/compiler/es5ExportDefaultClassDeclaration3.ts === - -var before: C = new C(); ->before : C ->C : C ->new C() : C ->C : typeof C - -export default class C { ->C : C - - method(): C { ->method : () => C ->C : C - - return new C(); ->new C() : C ->C : typeof C - } -} - -var after: C = new C(); ->after : C ->C : C ->new C() : C ->C : typeof C - -var t: typeof C = C; ->t : typeof C ->C : typeof C ->C : typeof C - - diff --git a/tests/baselines/reference/exportAssignmentOfGenericType1.errors.txt b/tests/baselines/reference/exportAssignmentOfGenericType1.errors.txt new file mode 100644 index 0000000000..e484d4096b --- /dev/null +++ b/tests/baselines/reference/exportAssignmentOfGenericType1.errors.txt @@ -0,0 +1,17 @@ +tests/cases/compiler/exportAssignmentOfGenericType1_0.ts(1,10): error TS2449: Class 'T' used before its declaration. + + +==== tests/cases/compiler/exportAssignmentOfGenericType1_1.ts (0 errors) ==== + /// + import q = require("exportAssignmentOfGenericType1_0"); + + class M extends q { } + var m: M; + var r: string = m.foo; + +==== tests/cases/compiler/exportAssignmentOfGenericType1_0.ts (1 errors) ==== + export = T; + ~ +!!! error TS2449: Class 'T' used before its declaration. + class T { foo: X; } + \ No newline at end of file diff --git a/tests/baselines/reference/for-of14.errors.txt b/tests/baselines/reference/for-of14.errors.txt index ab95d04268..d4ec79620d 100644 --- a/tests/baselines/reference/for-of14.errors.txt +++ b/tests/baselines/reference/for-of14.errors.txt @@ -1,14 +1,14 @@ -tests/cases/conformance/es6/for-ofStatements/for-of14.ts(2,11): error TS2488: Type must have a '[Symbol.iterator]()' method that returns an iterator. +tests/cases/conformance/es6/for-ofStatements/for-of14.ts(8,11): error TS2488: Type must have a '[Symbol.iterator]()' method that returns an iterator. ==== tests/cases/conformance/es6/for-ofStatements/for-of14.ts (1 errors) ==== - var v: string; - for (v of new StringIterator) { } // Should fail because the iterator is not iterable - ~~~~~~~~~~~~~~~~~~ -!!! error TS2488: Type must have a '[Symbol.iterator]()' method that returns an iterator. - class StringIterator { next() { return ""; } - } \ No newline at end of file + } + + var v: string; + for (v of new StringIterator) { } // Should fail because the iterator is not iterable + ~~~~~~~~~~~~~~~~~~ +!!! error TS2488: Type must have a '[Symbol.iterator]()' method that returns an iterator. \ No newline at end of file diff --git a/tests/baselines/reference/for-of14.js b/tests/baselines/reference/for-of14.js index 42832f8e58..ac3af1ff1d 100644 --- a/tests/baselines/reference/for-of14.js +++ b/tests/baselines/reference/for-of14.js @@ -1,18 +1,18 @@ //// [for-of14.ts] -var v: string; -for (v of new StringIterator) { } // Should fail because the iterator is not iterable - class StringIterator { next() { return ""; } -} +} + +var v: string; +for (v of new StringIterator) { } // Should fail because the iterator is not iterable //// [for-of14.js] -var v; -for (v of new StringIterator) { } // Should fail because the iterator is not iterable class StringIterator { next() { return ""; } } +var v; +for (v of new StringIterator) { } // Should fail because the iterator is not iterable diff --git a/tests/baselines/reference/for-of15.errors.txt b/tests/baselines/reference/for-of15.errors.txt index 20a4abe4bd..6d990aa01f 100644 --- a/tests/baselines/reference/for-of15.errors.txt +++ b/tests/baselines/reference/for-of15.errors.txt @@ -1,12 +1,7 @@ -tests/cases/conformance/es6/for-ofStatements/for-of15.ts(2,11): error TS2490: The type returned by the 'next()' method of an iterator must have a 'value' property. +tests/cases/conformance/es6/for-ofStatements/for-of15.ts(11,11): error TS2490: The type returned by the 'next()' method of an iterator must have a 'value' property. ==== tests/cases/conformance/es6/for-ofStatements/for-of15.ts (1 errors) ==== - var v: string; - for (v of new StringIterator) { } // Should fail - ~~~~~~~~~~~~~~~~~~ -!!! error TS2490: The type returned by the 'next()' method of an iterator must have a 'value' property. - class StringIterator { next() { return ""; @@ -14,4 +9,9 @@ tests/cases/conformance/es6/for-ofStatements/for-of15.ts(2,11): error TS2490: Th [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + var v: string; + for (v of new StringIterator) { } // Should fail + ~~~~~~~~~~~~~~~~~~ +!!! error TS2490: The type returned by the 'next()' method of an iterator must have a 'value' property. \ No newline at end of file diff --git a/tests/baselines/reference/for-of15.js b/tests/baselines/reference/for-of15.js index 62232745c8..f88c864016 100644 --- a/tests/baselines/reference/for-of15.js +++ b/tests/baselines/reference/for-of15.js @@ -1,7 +1,4 @@ //// [for-of15.ts] -var v: string; -for (v of new StringIterator) { } // Should fail - class StringIterator { next() { return ""; @@ -9,11 +6,12 @@ class StringIterator { [Symbol.iterator]() { return this; } -} +} + +var v: string; +for (v of new StringIterator) { } // Should fail //// [for-of15.js] -var v; -for (v of new StringIterator) { } // Should fail class StringIterator { next() { return ""; @@ -22,3 +20,5 @@ class StringIterator { return this; } } +var v; +for (v of new StringIterator) { } // Should fail diff --git a/tests/baselines/reference/for-of16.errors.txt b/tests/baselines/reference/for-of16.errors.txt index 20e3e87653..7574f98e3d 100644 --- a/tests/baselines/reference/for-of16.errors.txt +++ b/tests/baselines/reference/for-of16.errors.txt @@ -1,14 +1,14 @@ -tests/cases/conformance/es6/for-ofStatements/for-of16.ts(2,11): error TS2489: An iterator must have a 'next()' method. +tests/cases/conformance/es6/for-ofStatements/for-of16.ts(8,11): error TS2489: An iterator must have a 'next()' method. ==== tests/cases/conformance/es6/for-ofStatements/for-of16.ts (1 errors) ==== - var v: string; - for (v of new StringIterator) { } // Should fail - ~~~~~~~~~~~~~~~~~~ -!!! error TS2489: An iterator must have a 'next()' method. - class StringIterator { [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + var v: string; + for (v of new StringIterator) { } // Should fail + ~~~~~~~~~~~~~~~~~~ +!!! error TS2489: An iterator must have a 'next()' method. \ No newline at end of file diff --git a/tests/baselines/reference/for-of16.js b/tests/baselines/reference/for-of16.js index 974be239fd..2219e15a6f 100644 --- a/tests/baselines/reference/for-of16.js +++ b/tests/baselines/reference/for-of16.js @@ -1,18 +1,18 @@ //// [for-of16.ts] -var v: string; -for (v of new StringIterator) { } // Should fail - class StringIterator { [Symbol.iterator]() { return this; } -} +} + +var v: string; +for (v of new StringIterator) { } // Should fail //// [for-of16.js] -var v; -for (v of new StringIterator) { } // Should fail class StringIterator { [Symbol.iterator]() { return this; } } +var v; +for (v of new StringIterator) { } // Should fail diff --git a/tests/baselines/reference/for-of17.errors.txt b/tests/baselines/reference/for-of17.errors.txt index dfdeb8db00..5a77815369 100644 --- a/tests/baselines/reference/for-of17.errors.txt +++ b/tests/baselines/reference/for-of17.errors.txt @@ -1,12 +1,7 @@ -tests/cases/conformance/es6/for-ofStatements/for-of17.ts(2,6): error TS2322: Type 'number' is not assignable to type 'string'. +tests/cases/conformance/es6/for-ofStatements/for-of17.ts(14,6): error TS2322: Type 'number' is not assignable to type 'string'. ==== tests/cases/conformance/es6/for-ofStatements/for-of17.ts (1 errors) ==== - var v: string; - for (v of new NumberIterator) { } // Should succeed - ~ -!!! error TS2322: Type 'number' is not assignable to type 'string'. - class NumberIterator { next() { return { @@ -17,4 +12,9 @@ tests/cases/conformance/es6/for-ofStatements/for-of17.ts(2,6): error TS2322: Typ [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + var v: string; + for (v of new NumberIterator) { } // Should succeed + ~ +!!! error TS2322: Type 'number' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/for-of17.js b/tests/baselines/reference/for-of17.js index a392764700..2cd6bbe0d2 100644 --- a/tests/baselines/reference/for-of17.js +++ b/tests/baselines/reference/for-of17.js @@ -1,7 +1,4 @@ //// [for-of17.ts] -var v: string; -for (v of new NumberIterator) { } // Should succeed - class NumberIterator { next() { return { @@ -12,11 +9,12 @@ class NumberIterator { [Symbol.iterator]() { return this; } -} +} + +var v: string; +for (v of new NumberIterator) { } // Should succeed //// [for-of17.js] -var v; -for (v of new NumberIterator) { } // Should succeed class NumberIterator { next() { return { @@ -28,3 +26,5 @@ class NumberIterator { return this; } } +var v; +for (v of new NumberIterator) { } // Should succeed diff --git a/tests/baselines/reference/for-of18.js b/tests/baselines/reference/for-of18.js index c31e6b6e8c..fb7a684098 100644 --- a/tests/baselines/reference/for-of18.js +++ b/tests/baselines/reference/for-of18.js @@ -1,7 +1,4 @@ //// [for-of18.ts] -var v: string; -for (v of new StringIterator) { } // Should succeed - class StringIterator { next() { return { @@ -12,11 +9,12 @@ class StringIterator { [Symbol.iterator]() { return this; } -} +} + +var v: string; +for (v of new StringIterator) { } // Should succeed //// [for-of18.js] -var v; -for (v of new StringIterator) { } // Should succeed class StringIterator { next() { return { @@ -28,3 +26,5 @@ class StringIterator { return this; } } +var v; +for (v of new StringIterator) { } // Should succeed diff --git a/tests/baselines/reference/for-of18.symbols b/tests/baselines/reference/for-of18.symbols index b9d3266271..8f552c2757 100644 --- a/tests/baselines/reference/for-of18.symbols +++ b/tests/baselines/reference/for-of18.symbols @@ -1,23 +1,16 @@ === tests/cases/conformance/es6/for-ofStatements/for-of18.ts === -var v: string; ->v : Symbol(v, Decl(for-of18.ts, 0, 3)) - -for (v of new StringIterator) { } // Should succeed ->v : Symbol(v, Decl(for-of18.ts, 0, 3)) ->StringIterator : Symbol(StringIterator, Decl(for-of18.ts, 1, 33)) - class StringIterator { ->StringIterator : Symbol(StringIterator, Decl(for-of18.ts, 1, 33)) +>StringIterator : Symbol(StringIterator, Decl(for-of18.ts, 0, 0)) next() { ->next : Symbol(StringIterator.next, Decl(for-of18.ts, 3, 22)) +>next : Symbol(StringIterator.next, Decl(for-of18.ts, 0, 22)) return { value: "", ->value : Symbol(value, Decl(for-of18.ts, 5, 16)) +>value : Symbol(value, Decl(for-of18.ts, 2, 16)) done: false ->done : Symbol(done, Decl(for-of18.ts, 6, 22)) +>done : Symbol(done, Decl(for-of18.ts, 3, 22)) }; } @@ -27,6 +20,14 @@ class StringIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(StringIterator, Decl(for-of18.ts, 1, 33)) +>this : Symbol(StringIterator, Decl(for-of18.ts, 0, 0)) } } + +var v: string; +>v : Symbol(v, Decl(for-of18.ts, 12, 3)) + +for (v of new StringIterator) { } // Should succeed +>v : Symbol(v, Decl(for-of18.ts, 12, 3)) +>StringIterator : Symbol(StringIterator, Decl(for-of18.ts, 0, 0)) + diff --git a/tests/baselines/reference/for-of18.types b/tests/baselines/reference/for-of18.types index 86978b62cc..8b70c44625 100644 --- a/tests/baselines/reference/for-of18.types +++ b/tests/baselines/reference/for-of18.types @@ -1,12 +1,4 @@ === tests/cases/conformance/es6/for-ofStatements/for-of18.ts === -var v: string; ->v : string - -for (v of new StringIterator) { } // Should succeed ->v : string ->new StringIterator : StringIterator ->StringIterator : typeof StringIterator - class StringIterator { >StringIterator : StringIterator @@ -35,3 +27,12 @@ class StringIterator { >this : this } } + +var v: string; +>v : string + +for (v of new StringIterator) { } // Should succeed +>v : string +>new StringIterator : StringIterator +>StringIterator : typeof StringIterator + diff --git a/tests/baselines/reference/for-of19.js b/tests/baselines/reference/for-of19.js index d0f95caa1e..c0000d8d10 100644 --- a/tests/baselines/reference/for-of19.js +++ b/tests/baselines/reference/for-of19.js @@ -1,8 +1,4 @@ //// [for-of19.ts] -for (var v of new FooIterator) { - v; -} - class Foo { } class FooIterator { next() { @@ -14,12 +10,13 @@ class FooIterator { [Symbol.iterator]() { return this; } +} + +for (var v of new FooIterator) { + v; } //// [for-of19.js] -for (var v of new FooIterator) { - v; -} class Foo { } class FooIterator { @@ -33,3 +30,6 @@ class FooIterator { return this; } } +for (var v of new FooIterator) { + v; +} diff --git a/tests/baselines/reference/for-of19.symbols b/tests/baselines/reference/for-of19.symbols index e1a129aa32..f36dd74f9b 100644 --- a/tests/baselines/reference/for-of19.symbols +++ b/tests/baselines/reference/for-of19.symbols @@ -1,28 +1,20 @@ === tests/cases/conformance/es6/for-ofStatements/for-of19.ts === -for (var v of new FooIterator) { ->v : Symbol(v, Decl(for-of19.ts, 0, 8)) ->FooIterator : Symbol(FooIterator, Decl(for-of19.ts, 4, 13)) - - v; ->v : Symbol(v, Decl(for-of19.ts, 0, 8)) -} - class Foo { } ->Foo : Symbol(Foo, Decl(for-of19.ts, 2, 1)) +>Foo : Symbol(Foo, Decl(for-of19.ts, 0, 0)) class FooIterator { ->FooIterator : Symbol(FooIterator, Decl(for-of19.ts, 4, 13)) +>FooIterator : Symbol(FooIterator, Decl(for-of19.ts, 0, 13)) next() { ->next : Symbol(FooIterator.next, Decl(for-of19.ts, 5, 19)) +>next : Symbol(FooIterator.next, Decl(for-of19.ts, 1, 19)) return { value: new Foo, ->value : Symbol(value, Decl(for-of19.ts, 7, 16)) ->Foo : Symbol(Foo, Decl(for-of19.ts, 2, 1)) +>value : Symbol(value, Decl(for-of19.ts, 3, 16)) +>Foo : Symbol(Foo, Decl(for-of19.ts, 0, 0)) done: false ->done : Symbol(done, Decl(for-of19.ts, 8, 27)) +>done : Symbol(done, Decl(for-of19.ts, 4, 27)) }; } @@ -32,6 +24,14 @@ class FooIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(FooIterator, Decl(for-of19.ts, 4, 13)) +>this : Symbol(FooIterator, Decl(for-of19.ts, 0, 13)) } } + +for (var v of new FooIterator) { +>v : Symbol(v, Decl(for-of19.ts, 13, 8)) +>FooIterator : Symbol(FooIterator, Decl(for-of19.ts, 0, 13)) + + v; +>v : Symbol(v, Decl(for-of19.ts, 13, 8)) +} diff --git a/tests/baselines/reference/for-of19.types b/tests/baselines/reference/for-of19.types index a2882ccf1a..a62b2d64c8 100644 --- a/tests/baselines/reference/for-of19.types +++ b/tests/baselines/reference/for-of19.types @@ -1,13 +1,4 @@ === tests/cases/conformance/es6/for-ofStatements/for-of19.ts === -for (var v of new FooIterator) { ->v : Foo ->new FooIterator : FooIterator ->FooIterator : typeof FooIterator - - v; ->v : Foo -} - class Foo { } >Foo : Foo @@ -40,3 +31,12 @@ class FooIterator { >this : this } } + +for (var v of new FooIterator) { +>v : Foo +>new FooIterator : FooIterator +>FooIterator : typeof FooIterator + + v; +>v : Foo +} diff --git a/tests/baselines/reference/for-of20.js b/tests/baselines/reference/for-of20.js index c098abd2f7..97259778d2 100644 --- a/tests/baselines/reference/for-of20.js +++ b/tests/baselines/reference/for-of20.js @@ -1,8 +1,4 @@ //// [for-of20.ts] -for (let v of new FooIterator) { - v; -} - class Foo { } class FooIterator { next() { @@ -14,12 +10,13 @@ class FooIterator { [Symbol.iterator]() { return this; } +} + +for (let v of new FooIterator) { + v; } //// [for-of20.js] -for (let v of new FooIterator) { - v; -} class Foo { } class FooIterator { @@ -33,3 +30,6 @@ class FooIterator { return this; } } +for (let v of new FooIterator) { + v; +} diff --git a/tests/baselines/reference/for-of20.symbols b/tests/baselines/reference/for-of20.symbols index 20b444e6bc..5fff9fd787 100644 --- a/tests/baselines/reference/for-of20.symbols +++ b/tests/baselines/reference/for-of20.symbols @@ -1,28 +1,20 @@ === tests/cases/conformance/es6/for-ofStatements/for-of20.ts === -for (let v of new FooIterator) { ->v : Symbol(v, Decl(for-of20.ts, 0, 8)) ->FooIterator : Symbol(FooIterator, Decl(for-of20.ts, 4, 13)) - - v; ->v : Symbol(v, Decl(for-of20.ts, 0, 8)) -} - class Foo { } ->Foo : Symbol(Foo, Decl(for-of20.ts, 2, 1)) +>Foo : Symbol(Foo, Decl(for-of20.ts, 0, 0)) class FooIterator { ->FooIterator : Symbol(FooIterator, Decl(for-of20.ts, 4, 13)) +>FooIterator : Symbol(FooIterator, Decl(for-of20.ts, 0, 13)) next() { ->next : Symbol(FooIterator.next, Decl(for-of20.ts, 5, 19)) +>next : Symbol(FooIterator.next, Decl(for-of20.ts, 1, 19)) return { value: new Foo, ->value : Symbol(value, Decl(for-of20.ts, 7, 16)) ->Foo : Symbol(Foo, Decl(for-of20.ts, 2, 1)) +>value : Symbol(value, Decl(for-of20.ts, 3, 16)) +>Foo : Symbol(Foo, Decl(for-of20.ts, 0, 0)) done: false ->done : Symbol(done, Decl(for-of20.ts, 8, 27)) +>done : Symbol(done, Decl(for-of20.ts, 4, 27)) }; } @@ -32,6 +24,14 @@ class FooIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(FooIterator, Decl(for-of20.ts, 4, 13)) +>this : Symbol(FooIterator, Decl(for-of20.ts, 0, 13)) } } + +for (let v of new FooIterator) { +>v : Symbol(v, Decl(for-of20.ts, 13, 8)) +>FooIterator : Symbol(FooIterator, Decl(for-of20.ts, 0, 13)) + + v; +>v : Symbol(v, Decl(for-of20.ts, 13, 8)) +} diff --git a/tests/baselines/reference/for-of20.types b/tests/baselines/reference/for-of20.types index 9274c7f4b9..e620b60310 100644 --- a/tests/baselines/reference/for-of20.types +++ b/tests/baselines/reference/for-of20.types @@ -1,13 +1,4 @@ === tests/cases/conformance/es6/for-ofStatements/for-of20.ts === -for (let v of new FooIterator) { ->v : Foo ->new FooIterator : FooIterator ->FooIterator : typeof FooIterator - - v; ->v : Foo -} - class Foo { } >Foo : Foo @@ -40,3 +31,12 @@ class FooIterator { >this : this } } + +for (let v of new FooIterator) { +>v : Foo +>new FooIterator : FooIterator +>FooIterator : typeof FooIterator + + v; +>v : Foo +} diff --git a/tests/baselines/reference/for-of21.js b/tests/baselines/reference/for-of21.js index 27da28e3b4..66791de89b 100644 --- a/tests/baselines/reference/for-of21.js +++ b/tests/baselines/reference/for-of21.js @@ -1,8 +1,4 @@ //// [for-of21.ts] -for (const v of new FooIterator) { - v; -} - class Foo { } class FooIterator { next() { @@ -14,12 +10,13 @@ class FooIterator { [Symbol.iterator]() { return this; } +} + +for (const v of new FooIterator) { + v; } //// [for-of21.js] -for (const v of new FooIterator) { - v; -} class Foo { } class FooIterator { @@ -33,3 +30,6 @@ class FooIterator { return this; } } +for (const v of new FooIterator) { + v; +} diff --git a/tests/baselines/reference/for-of21.symbols b/tests/baselines/reference/for-of21.symbols index 71403edfc9..0068c9ef4a 100644 --- a/tests/baselines/reference/for-of21.symbols +++ b/tests/baselines/reference/for-of21.symbols @@ -1,28 +1,20 @@ === tests/cases/conformance/es6/for-ofStatements/for-of21.ts === -for (const v of new FooIterator) { ->v : Symbol(v, Decl(for-of21.ts, 0, 10)) ->FooIterator : Symbol(FooIterator, Decl(for-of21.ts, 4, 13)) - - v; ->v : Symbol(v, Decl(for-of21.ts, 0, 10)) -} - class Foo { } ->Foo : Symbol(Foo, Decl(for-of21.ts, 2, 1)) +>Foo : Symbol(Foo, Decl(for-of21.ts, 0, 0)) class FooIterator { ->FooIterator : Symbol(FooIterator, Decl(for-of21.ts, 4, 13)) +>FooIterator : Symbol(FooIterator, Decl(for-of21.ts, 0, 13)) next() { ->next : Symbol(FooIterator.next, Decl(for-of21.ts, 5, 19)) +>next : Symbol(FooIterator.next, Decl(for-of21.ts, 1, 19)) return { value: new Foo, ->value : Symbol(value, Decl(for-of21.ts, 7, 16)) ->Foo : Symbol(Foo, Decl(for-of21.ts, 2, 1)) +>value : Symbol(value, Decl(for-of21.ts, 3, 16)) +>Foo : Symbol(Foo, Decl(for-of21.ts, 0, 0)) done: false ->done : Symbol(done, Decl(for-of21.ts, 8, 27)) +>done : Symbol(done, Decl(for-of21.ts, 4, 27)) }; } @@ -32,6 +24,14 @@ class FooIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(FooIterator, Decl(for-of21.ts, 4, 13)) +>this : Symbol(FooIterator, Decl(for-of21.ts, 0, 13)) } } + +for (const v of new FooIterator) { +>v : Symbol(v, Decl(for-of21.ts, 13, 10)) +>FooIterator : Symbol(FooIterator, Decl(for-of21.ts, 0, 13)) + + v; +>v : Symbol(v, Decl(for-of21.ts, 13, 10)) +} diff --git a/tests/baselines/reference/for-of21.types b/tests/baselines/reference/for-of21.types index 1366cb1a42..59c66b2a41 100644 --- a/tests/baselines/reference/for-of21.types +++ b/tests/baselines/reference/for-of21.types @@ -1,13 +1,4 @@ === tests/cases/conformance/es6/for-ofStatements/for-of21.ts === -for (const v of new FooIterator) { ->v : Foo ->new FooIterator : FooIterator ->FooIterator : typeof FooIterator - - v; ->v : Foo -} - class Foo { } >Foo : Foo @@ -40,3 +31,12 @@ class FooIterator { >this : this } } + +for (const v of new FooIterator) { +>v : Foo +>new FooIterator : FooIterator +>FooIterator : typeof FooIterator + + v; +>v : Foo +} diff --git a/tests/baselines/reference/for-of22.js b/tests/baselines/reference/for-of22.js index 886e8dba7c..767ed1cc15 100644 --- a/tests/baselines/reference/for-of22.js +++ b/tests/baselines/reference/for-of22.js @@ -1,9 +1,4 @@ //// [for-of22.ts] -v; -for (var v of new FooIterator) { - -} - class Foo { } class FooIterator { next() { @@ -15,12 +10,14 @@ class FooIterator { [Symbol.iterator]() { return this; } +} + +v; +for (var v of new FooIterator) { + } //// [for-of22.js] -v; -for (var v of new FooIterator) { -} class Foo { } class FooIterator { @@ -34,3 +31,6 @@ class FooIterator { return this; } } +v; +for (var v of new FooIterator) { +} diff --git a/tests/baselines/reference/for-of22.symbols b/tests/baselines/reference/for-of22.symbols index 36a522759c..929cae4ed7 100644 --- a/tests/baselines/reference/for-of22.symbols +++ b/tests/baselines/reference/for-of22.symbols @@ -1,29 +1,20 @@ === tests/cases/conformance/es6/for-ofStatements/for-of22.ts === -v; ->v : Symbol(v, Decl(for-of22.ts, 1, 8)) - -for (var v of new FooIterator) { ->v : Symbol(v, Decl(for-of22.ts, 1, 8)) ->FooIterator : Symbol(FooIterator, Decl(for-of22.ts, 5, 13)) - -} - class Foo { } ->Foo : Symbol(Foo, Decl(for-of22.ts, 3, 1)) +>Foo : Symbol(Foo, Decl(for-of22.ts, 0, 0)) class FooIterator { ->FooIterator : Symbol(FooIterator, Decl(for-of22.ts, 5, 13)) +>FooIterator : Symbol(FooIterator, Decl(for-of22.ts, 0, 13)) next() { ->next : Symbol(FooIterator.next, Decl(for-of22.ts, 6, 19)) +>next : Symbol(FooIterator.next, Decl(for-of22.ts, 1, 19)) return { value: new Foo, ->value : Symbol(value, Decl(for-of22.ts, 8, 16)) ->Foo : Symbol(Foo, Decl(for-of22.ts, 3, 1)) +>value : Symbol(value, Decl(for-of22.ts, 3, 16)) +>Foo : Symbol(Foo, Decl(for-of22.ts, 0, 0)) done: false ->done : Symbol(done, Decl(for-of22.ts, 9, 27)) +>done : Symbol(done, Decl(for-of22.ts, 4, 27)) }; } @@ -33,6 +24,15 @@ class FooIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(FooIterator, Decl(for-of22.ts, 5, 13)) +>this : Symbol(FooIterator, Decl(for-of22.ts, 0, 13)) } } + +v; +>v : Symbol(v, Decl(for-of22.ts, 14, 8)) + +for (var v of new FooIterator) { +>v : Symbol(v, Decl(for-of22.ts, 14, 8)) +>FooIterator : Symbol(FooIterator, Decl(for-of22.ts, 0, 13)) + +} diff --git a/tests/baselines/reference/for-of22.types b/tests/baselines/reference/for-of22.types index 80cd42b2b3..e1449875da 100644 --- a/tests/baselines/reference/for-of22.types +++ b/tests/baselines/reference/for-of22.types @@ -1,14 +1,4 @@ === tests/cases/conformance/es6/for-ofStatements/for-of22.ts === -v; ->v : Foo - -for (var v of new FooIterator) { ->v : Foo ->new FooIterator : FooIterator ->FooIterator : typeof FooIterator - -} - class Foo { } >Foo : Foo @@ -41,3 +31,13 @@ class FooIterator { >this : this } } + +v; +>v : Foo + +for (var v of new FooIterator) { +>v : Foo +>new FooIterator : FooIterator +>FooIterator : typeof FooIterator + +} diff --git a/tests/baselines/reference/for-of23.js b/tests/baselines/reference/for-of23.js index f5649128c1..9ad03c0109 100644 --- a/tests/baselines/reference/for-of23.js +++ b/tests/baselines/reference/for-of23.js @@ -1,8 +1,4 @@ //// [for-of23.ts] -for (const v of new FooIterator) { - const v = 0; // new scope -} - class Foo { } class FooIterator { next() { @@ -14,12 +10,13 @@ class FooIterator { [Symbol.iterator]() { return this; } +} + +for (const v of new FooIterator) { + const v = 0; // new scope } //// [for-of23.js] -for (const v of new FooIterator) { - const v = 0; // new scope -} class Foo { } class FooIterator { @@ -33,3 +30,6 @@ class FooIterator { return this; } } +for (const v of new FooIterator) { + const v = 0; // new scope +} diff --git a/tests/baselines/reference/for-of23.symbols b/tests/baselines/reference/for-of23.symbols index 3be07f4fd4..7a57e38baf 100644 --- a/tests/baselines/reference/for-of23.symbols +++ b/tests/baselines/reference/for-of23.symbols @@ -1,28 +1,20 @@ === tests/cases/conformance/es6/for-ofStatements/for-of23.ts === -for (const v of new FooIterator) { ->v : Symbol(v, Decl(for-of23.ts, 0, 10)) ->FooIterator : Symbol(FooIterator, Decl(for-of23.ts, 4, 13)) - - const v = 0; // new scope ->v : Symbol(v, Decl(for-of23.ts, 1, 9)) -} - class Foo { } ->Foo : Symbol(Foo, Decl(for-of23.ts, 2, 1)) +>Foo : Symbol(Foo, Decl(for-of23.ts, 0, 0)) class FooIterator { ->FooIterator : Symbol(FooIterator, Decl(for-of23.ts, 4, 13)) +>FooIterator : Symbol(FooIterator, Decl(for-of23.ts, 0, 13)) next() { ->next : Symbol(FooIterator.next, Decl(for-of23.ts, 5, 19)) +>next : Symbol(FooIterator.next, Decl(for-of23.ts, 1, 19)) return { value: new Foo, ->value : Symbol(value, Decl(for-of23.ts, 7, 16)) ->Foo : Symbol(Foo, Decl(for-of23.ts, 2, 1)) +>value : Symbol(value, Decl(for-of23.ts, 3, 16)) +>Foo : Symbol(Foo, Decl(for-of23.ts, 0, 0)) done: false ->done : Symbol(done, Decl(for-of23.ts, 8, 27)) +>done : Symbol(done, Decl(for-of23.ts, 4, 27)) }; } @@ -32,6 +24,14 @@ class FooIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(FooIterator, Decl(for-of23.ts, 4, 13)) +>this : Symbol(FooIterator, Decl(for-of23.ts, 0, 13)) } } + +for (const v of new FooIterator) { +>v : Symbol(v, Decl(for-of23.ts, 13, 10)) +>FooIterator : Symbol(FooIterator, Decl(for-of23.ts, 0, 13)) + + const v = 0; // new scope +>v : Symbol(v, Decl(for-of23.ts, 14, 9)) +} diff --git a/tests/baselines/reference/for-of23.types b/tests/baselines/reference/for-of23.types index ed74156f51..427eb57f5a 100644 --- a/tests/baselines/reference/for-of23.types +++ b/tests/baselines/reference/for-of23.types @@ -1,14 +1,4 @@ === tests/cases/conformance/es6/for-ofStatements/for-of23.ts === -for (const v of new FooIterator) { ->v : Foo ->new FooIterator : FooIterator ->FooIterator : typeof FooIterator - - const v = 0; // new scope ->v : 0 ->0 : 0 -} - class Foo { } >Foo : Foo @@ -41,3 +31,13 @@ class FooIterator { >this : this } } + +for (const v of new FooIterator) { +>v : Foo +>new FooIterator : FooIterator +>FooIterator : typeof FooIterator + + const v = 0; // new scope +>v : 0 +>0 : 0 +} diff --git a/tests/baselines/reference/for-of25.js b/tests/baselines/reference/for-of25.js index 5715f6e8a3..032efa52ae 100644 --- a/tests/baselines/reference/for-of25.js +++ b/tests/baselines/reference/for-of25.js @@ -1,18 +1,18 @@ //// [for-of25.ts] -var x: any; -for (var v of new StringIterator) { } - class StringIterator { [Symbol.iterator]() { return x; } -} +} + +var x: any; +for (var v of new StringIterator) { } //// [for-of25.js] -var x; -for (var v of new StringIterator) { } class StringIterator { [Symbol.iterator]() { return x; } } +var x; +for (var v of new StringIterator) { } diff --git a/tests/baselines/reference/for-of25.symbols b/tests/baselines/reference/for-of25.symbols index e21348ba56..e9304e517b 100644 --- a/tests/baselines/reference/for-of25.symbols +++ b/tests/baselines/reference/for-of25.symbols @@ -1,13 +1,6 @@ === tests/cases/conformance/es6/for-ofStatements/for-of25.ts === -var x: any; ->x : Symbol(x, Decl(for-of25.ts, 0, 3)) - -for (var v of new StringIterator) { } ->v : Symbol(v, Decl(for-of25.ts, 1, 8)) ->StringIterator : Symbol(StringIterator, Decl(for-of25.ts, 1, 37)) - class StringIterator { ->StringIterator : Symbol(StringIterator, Decl(for-of25.ts, 1, 37)) +>StringIterator : Symbol(StringIterator, Decl(for-of25.ts, 0, 0)) [Symbol.iterator]() { >Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) @@ -15,6 +8,14 @@ class StringIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return x; ->x : Symbol(x, Decl(for-of25.ts, 0, 3)) +>x : Symbol(x, Decl(for-of25.ts, 6, 3)) } } + +var x: any; +>x : Symbol(x, Decl(for-of25.ts, 6, 3)) + +for (var v of new StringIterator) { } +>v : Symbol(v, Decl(for-of25.ts, 7, 8)) +>StringIterator : Symbol(StringIterator, Decl(for-of25.ts, 0, 0)) + diff --git a/tests/baselines/reference/for-of25.types b/tests/baselines/reference/for-of25.types index c4d6b32aeb..7a11b7acf6 100644 --- a/tests/baselines/reference/for-of25.types +++ b/tests/baselines/reference/for-of25.types @@ -1,12 +1,4 @@ === tests/cases/conformance/es6/for-ofStatements/for-of25.ts === -var x: any; ->x : any - -for (var v of new StringIterator) { } ->v : any ->new StringIterator : StringIterator ->StringIterator : typeof StringIterator - class StringIterator { >StringIterator : StringIterator @@ -19,3 +11,12 @@ class StringIterator { >x : any } } + +var x: any; +>x : any + +for (var v of new StringIterator) { } +>v : any +>new StringIterator : StringIterator +>StringIterator : typeof StringIterator + diff --git a/tests/baselines/reference/for-of26.js b/tests/baselines/reference/for-of26.js index 33319f50ef..ab9c4fdca9 100644 --- a/tests/baselines/reference/for-of26.js +++ b/tests/baselines/reference/for-of26.js @@ -1,7 +1,4 @@ //// [for-of26.ts] -var x: any; -for (var v of new StringIterator) { } - class StringIterator { next() { return x; @@ -9,11 +6,12 @@ class StringIterator { [Symbol.iterator]() { return this; } -} +} + +var x: any; +for (var v of new StringIterator) { } //// [for-of26.js] -var x; -for (var v of new StringIterator) { } class StringIterator { next() { return x; @@ -22,3 +20,5 @@ class StringIterator { return this; } } +var x; +for (var v of new StringIterator) { } diff --git a/tests/baselines/reference/for-of26.symbols b/tests/baselines/reference/for-of26.symbols index 947240bf8e..2047389825 100644 --- a/tests/baselines/reference/for-of26.symbols +++ b/tests/baselines/reference/for-of26.symbols @@ -1,19 +1,12 @@ === tests/cases/conformance/es6/for-ofStatements/for-of26.ts === -var x: any; ->x : Symbol(x, Decl(for-of26.ts, 0, 3)) - -for (var v of new StringIterator) { } ->v : Symbol(v, Decl(for-of26.ts, 1, 8)) ->StringIterator : Symbol(StringIterator, Decl(for-of26.ts, 1, 37)) - class StringIterator { ->StringIterator : Symbol(StringIterator, Decl(for-of26.ts, 1, 37)) +>StringIterator : Symbol(StringIterator, Decl(for-of26.ts, 0, 0)) next() { ->next : Symbol(StringIterator.next, Decl(for-of26.ts, 3, 22)) +>next : Symbol(StringIterator.next, Decl(for-of26.ts, 0, 22)) return x; ->x : Symbol(x, Decl(for-of26.ts, 0, 3)) +>x : Symbol(x, Decl(for-of26.ts, 9, 3)) } [Symbol.iterator]() { >Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) @@ -21,6 +14,14 @@ class StringIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(StringIterator, Decl(for-of26.ts, 1, 37)) +>this : Symbol(StringIterator, Decl(for-of26.ts, 0, 0)) } } + +var x: any; +>x : Symbol(x, Decl(for-of26.ts, 9, 3)) + +for (var v of new StringIterator) { } +>v : Symbol(v, Decl(for-of26.ts, 10, 8)) +>StringIterator : Symbol(StringIterator, Decl(for-of26.ts, 0, 0)) + diff --git a/tests/baselines/reference/for-of26.types b/tests/baselines/reference/for-of26.types index fe930e2e57..b0cfd89174 100644 --- a/tests/baselines/reference/for-of26.types +++ b/tests/baselines/reference/for-of26.types @@ -1,12 +1,4 @@ === tests/cases/conformance/es6/for-ofStatements/for-of26.ts === -var x: any; ->x : any - -for (var v of new StringIterator) { } ->v : any ->new StringIterator : StringIterator ->StringIterator : typeof StringIterator - class StringIterator { >StringIterator : StringIterator @@ -25,3 +17,12 @@ class StringIterator { >this : this } } + +var x: any; +>x : any + +for (var v of new StringIterator) { } +>v : any +>new StringIterator : StringIterator +>StringIterator : typeof StringIterator + diff --git a/tests/baselines/reference/for-of27.js b/tests/baselines/reference/for-of27.js index 1ac3a1dfc4..6adc66e241 100644 --- a/tests/baselines/reference/for-of27.js +++ b/tests/baselines/reference/for-of27.js @@ -1,11 +1,11 @@ //// [for-of27.ts] -for (var v of new StringIterator) { } - class StringIterator { [Symbol.iterator]: any; -} +} + +for (var v of new StringIterator) { } //// [for-of27.js] -for (var v of new StringIterator) { } class StringIterator { } +for (var v of new StringIterator) { } diff --git a/tests/baselines/reference/for-of27.symbols b/tests/baselines/reference/for-of27.symbols index b2b733ab13..4799a13835 100644 --- a/tests/baselines/reference/for-of27.symbols +++ b/tests/baselines/reference/for-of27.symbols @@ -1,13 +1,14 @@ === tests/cases/conformance/es6/for-ofStatements/for-of27.ts === -for (var v of new StringIterator) { } ->v : Symbol(v, Decl(for-of27.ts, 0, 8)) ->StringIterator : Symbol(StringIterator, Decl(for-of27.ts, 0, 37)) - class StringIterator { ->StringIterator : Symbol(StringIterator, Decl(for-of27.ts, 0, 37)) +>StringIterator : Symbol(StringIterator, Decl(for-of27.ts, 0, 0)) [Symbol.iterator]: any; >Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) >Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) } + +for (var v of new StringIterator) { } +>v : Symbol(v, Decl(for-of27.ts, 4, 8)) +>StringIterator : Symbol(StringIterator, Decl(for-of27.ts, 0, 0)) + diff --git a/tests/baselines/reference/for-of27.types b/tests/baselines/reference/for-of27.types index 8e9130ce27..f6115ccf8c 100644 --- a/tests/baselines/reference/for-of27.types +++ b/tests/baselines/reference/for-of27.types @@ -1,9 +1,4 @@ === tests/cases/conformance/es6/for-ofStatements/for-of27.ts === -for (var v of new StringIterator) { } ->v : any ->new StringIterator : StringIterator ->StringIterator : typeof StringIterator - class StringIterator { >StringIterator : StringIterator @@ -12,3 +7,9 @@ class StringIterator { >Symbol : SymbolConstructor >iterator : symbol } + +for (var v of new StringIterator) { } +>v : any +>new StringIterator : StringIterator +>StringIterator : typeof StringIterator + diff --git a/tests/baselines/reference/for-of28.js b/tests/baselines/reference/for-of28.js index 78e8677481..e06e2fc6ab 100644 --- a/tests/baselines/reference/for-of28.js +++ b/tests/baselines/reference/for-of28.js @@ -1,17 +1,17 @@ //// [for-of28.ts] -for (var v of new StringIterator) { } - class StringIterator { next: any; [Symbol.iterator]() { return this; } -} +} + +for (var v of new StringIterator) { } //// [for-of28.js] -for (var v of new StringIterator) { } class StringIterator { [Symbol.iterator]() { return this; } } +for (var v of new StringIterator) { } diff --git a/tests/baselines/reference/for-of28.symbols b/tests/baselines/reference/for-of28.symbols index 52ed4fd745..ad5ea53a80 100644 --- a/tests/baselines/reference/for-of28.symbols +++ b/tests/baselines/reference/for-of28.symbols @@ -1,13 +1,9 @@ === tests/cases/conformance/es6/for-ofStatements/for-of28.ts === -for (var v of new StringIterator) { } ->v : Symbol(v, Decl(for-of28.ts, 0, 8)) ->StringIterator : Symbol(StringIterator, Decl(for-of28.ts, 0, 37)) - class StringIterator { ->StringIterator : Symbol(StringIterator, Decl(for-of28.ts, 0, 37)) +>StringIterator : Symbol(StringIterator, Decl(for-of28.ts, 0, 0)) next: any; ->next : Symbol(StringIterator.next, Decl(for-of28.ts, 2, 22)) +>next : Symbol(StringIterator.next, Decl(for-of28.ts, 0, 22)) [Symbol.iterator]() { >Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) @@ -15,6 +11,11 @@ class StringIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(StringIterator, Decl(for-of28.ts, 0, 37)) +>this : Symbol(StringIterator, Decl(for-of28.ts, 0, 0)) } } + +for (var v of new StringIterator) { } +>v : Symbol(v, Decl(for-of28.ts, 7, 8)) +>StringIterator : Symbol(StringIterator, Decl(for-of28.ts, 0, 0)) + diff --git a/tests/baselines/reference/for-of28.types b/tests/baselines/reference/for-of28.types index 882d2df618..a454a0c448 100644 --- a/tests/baselines/reference/for-of28.types +++ b/tests/baselines/reference/for-of28.types @@ -1,9 +1,4 @@ === tests/cases/conformance/es6/for-ofStatements/for-of28.ts === -for (var v of new StringIterator) { } ->v : any ->new StringIterator : StringIterator ->StringIterator : typeof StringIterator - class StringIterator { >StringIterator : StringIterator @@ -19,3 +14,9 @@ class StringIterator { >this : this } } + +for (var v of new StringIterator) { } +>v : any +>new StringIterator : StringIterator +>StringIterator : typeof StringIterator + diff --git a/tests/baselines/reference/for-of30.errors.txt b/tests/baselines/reference/for-of30.errors.txt index 6434b5294d..b0091c90b5 100644 --- a/tests/baselines/reference/for-of30.errors.txt +++ b/tests/baselines/reference/for-of30.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/for-ofStatements/for-of30.ts(1,15): error TS2322: Type 'StringIterator' is not assignable to type 'Iterable'. +tests/cases/conformance/es6/for-ofStatements/for-of30.ts(16,15): error TS2322: Type 'StringIterator' is not assignable to type 'Iterable'. Types of property '[Symbol.iterator]' are incompatible. Type '() => StringIterator' is not assignable to type '() => Iterator'. Type 'StringIterator' is not assignable to type 'Iterator'. @@ -7,15 +7,6 @@ tests/cases/conformance/es6/for-ofStatements/for-of30.ts(1,15): error TS2322: Ty ==== tests/cases/conformance/es6/for-ofStatements/for-of30.ts (1 errors) ==== - for (var v of new StringIterator) { } - ~~~~~~~~~~~~~~~~~~ -!!! error TS2322: Type 'StringIterator' is not assignable to type 'Iterable'. -!!! error TS2322: Types of property '[Symbol.iterator]' are incompatible. -!!! error TS2322: Type '() => StringIterator' is not assignable to type '() => Iterator'. -!!! error TS2322: Type 'StringIterator' is not assignable to type 'Iterator'. -!!! error TS2322: Types of property 'return' are incompatible. -!!! error TS2322: Type 'number' is not assignable to type '(value?: any) => IteratorResult'. - class StringIterator { next() { return { @@ -29,4 +20,13 @@ tests/cases/conformance/es6/for-ofStatements/for-of30.ts(1,15): error TS2322: Ty [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + for (var v of new StringIterator) { } + ~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'StringIterator' is not assignable to type 'Iterable'. +!!! error TS2322: Types of property '[Symbol.iterator]' are incompatible. +!!! error TS2322: Type '() => StringIterator' is not assignable to type '() => Iterator'. +!!! error TS2322: Type 'StringIterator' is not assignable to type 'Iterator'. +!!! error TS2322: Types of property 'return' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type '(value?: any) => IteratorResult'. \ No newline at end of file diff --git a/tests/baselines/reference/for-of30.js b/tests/baselines/reference/for-of30.js index 37316774c9..935944db64 100644 --- a/tests/baselines/reference/for-of30.js +++ b/tests/baselines/reference/for-of30.js @@ -1,6 +1,4 @@ //// [for-of30.ts] -for (var v of new StringIterator) { } - class StringIterator { next() { return { @@ -14,10 +12,11 @@ class StringIterator { [Symbol.iterator]() { return this; } -} +} + +for (var v of new StringIterator) { } //// [for-of30.js] -for (var v of new StringIterator) { } class StringIterator { constructor() { this.return = 0; @@ -32,3 +31,4 @@ class StringIterator { return this; } } +for (var v of new StringIterator) { } diff --git a/tests/baselines/reference/for-of31.errors.txt b/tests/baselines/reference/for-of31.errors.txt index 6d5f6e816b..bf38e0f500 100644 --- a/tests/baselines/reference/for-of31.errors.txt +++ b/tests/baselines/reference/for-of31.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/for-ofStatements/for-of31.ts(1,15): error TS2322: Type 'StringIterator' is not assignable to type 'Iterable'. +tests/cases/conformance/es6/for-ofStatements/for-of31.ts(14,15): error TS2322: Type 'StringIterator' is not assignable to type 'Iterable'. Types of property '[Symbol.iterator]' are incompatible. Type '() => StringIterator' is not assignable to type '() => Iterator'. Type 'StringIterator' is not assignable to type 'Iterator'. @@ -9,17 +9,6 @@ tests/cases/conformance/es6/for-ofStatements/for-of31.ts(1,15): error TS2322: Ty ==== tests/cases/conformance/es6/for-ofStatements/for-of31.ts (1 errors) ==== - for (var v of new StringIterator) { } - ~~~~~~~~~~~~~~~~~~ -!!! error TS2322: Type 'StringIterator' is not assignable to type 'Iterable'. -!!! error TS2322: Types of property '[Symbol.iterator]' are incompatible. -!!! error TS2322: Type '() => StringIterator' is not assignable to type '() => Iterator'. -!!! error TS2322: Type 'StringIterator' is not assignable to type 'Iterator'. -!!! error TS2322: Types of property 'next' are incompatible. -!!! error TS2322: Type '() => { value: string; }' is not assignable to type '(value?: any) => IteratorResult'. -!!! error TS2322: Type '{ value: string; }' is not assignable to type 'IteratorResult'. -!!! error TS2322: Property 'done' is missing in type '{ value: string; }'. - class StringIterator { next() { return { @@ -31,4 +20,15 @@ tests/cases/conformance/es6/for-ofStatements/for-of31.ts(1,15): error TS2322: Ty [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + for (var v of new StringIterator) { } + ~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'StringIterator' is not assignable to type 'Iterable'. +!!! error TS2322: Types of property '[Symbol.iterator]' are incompatible. +!!! error TS2322: Type '() => StringIterator' is not assignable to type '() => Iterator'. +!!! error TS2322: Type 'StringIterator' is not assignable to type 'Iterator'. +!!! error TS2322: Types of property 'next' are incompatible. +!!! error TS2322: Type '() => { value: string; }' is not assignable to type '(value?: any) => IteratorResult'. +!!! error TS2322: Type '{ value: string; }' is not assignable to type 'IteratorResult'. +!!! error TS2322: Property 'done' is missing in type '{ value: string; }'. \ No newline at end of file diff --git a/tests/baselines/reference/for-of31.js b/tests/baselines/reference/for-of31.js index a92e827b91..84e24bed5a 100644 --- a/tests/baselines/reference/for-of31.js +++ b/tests/baselines/reference/for-of31.js @@ -1,6 +1,4 @@ //// [for-of31.ts] -for (var v of new StringIterator) { } - class StringIterator { next() { return { @@ -12,10 +10,11 @@ class StringIterator { [Symbol.iterator]() { return this; } -} +} + +for (var v of new StringIterator) { } //// [for-of31.js] -for (var v of new StringIterator) { } class StringIterator { next() { return { @@ -27,3 +26,4 @@ class StringIterator { return this; } } +for (var v of new StringIterator) { } diff --git a/tests/baselines/reference/for-of33.errors.txt b/tests/baselines/reference/for-of33.errors.txt index ff1feacd7b..eba30ce9bf 100644 --- a/tests/baselines/reference/for-of33.errors.txt +++ b/tests/baselines/reference/for-of33.errors.txt @@ -1,16 +1,16 @@ -tests/cases/conformance/es6/for-ofStatements/for-of33.ts(1,10): error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. -tests/cases/conformance/es6/for-ofStatements/for-of33.ts(4,5): error TS7023: '[Symbol.iterator]' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. +tests/cases/conformance/es6/for-ofStatements/for-of33.ts(2,5): error TS7023: '[Symbol.iterator]' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. +tests/cases/conformance/es6/for-ofStatements/for-of33.ts(7,10): error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. ==== tests/cases/conformance/es6/for-ofStatements/for-of33.ts (2 errors) ==== - for (var v of new StringIterator) { } - ~ -!!! error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. - class StringIterator { [Symbol.iterator]() { ~~~~~~~~~~~~~~~~~ !!! error TS7023: '[Symbol.iterator]' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. return v; } - } \ No newline at end of file + } + + for (var v of new StringIterator) { } + ~ +!!! error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. \ No newline at end of file diff --git a/tests/baselines/reference/for-of33.js b/tests/baselines/reference/for-of33.js index b63aeedf77..e77d3cf5de 100644 --- a/tests/baselines/reference/for-of33.js +++ b/tests/baselines/reference/for-of33.js @@ -1,16 +1,16 @@ //// [for-of33.ts] -for (var v of new StringIterator) { } - class StringIterator { [Symbol.iterator]() { return v; } -} +} + +for (var v of new StringIterator) { } //// [for-of33.js] -for (var v of new StringIterator) { } class StringIterator { [Symbol.iterator]() { return v; } } +for (var v of new StringIterator) { } diff --git a/tests/baselines/reference/for-of34.errors.txt b/tests/baselines/reference/for-of34.errors.txt index c378a8f5bb..2d53ecb0a2 100644 --- a/tests/baselines/reference/for-of34.errors.txt +++ b/tests/baselines/reference/for-of34.errors.txt @@ -1,12 +1,8 @@ -tests/cases/conformance/es6/for-ofStatements/for-of34.ts(1,10): error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. -tests/cases/conformance/es6/for-ofStatements/for-of34.ts(4,5): error TS7023: 'next' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. +tests/cases/conformance/es6/for-ofStatements/for-of34.ts(2,5): error TS7023: 'next' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. +tests/cases/conformance/es6/for-ofStatements/for-of34.ts(11,10): error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. ==== tests/cases/conformance/es6/for-ofStatements/for-of34.ts (2 errors) ==== - for (var v of new StringIterator) { } - ~ -!!! error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. - class StringIterator { next() { ~~~~ @@ -17,4 +13,8 @@ tests/cases/conformance/es6/for-ofStatements/for-of34.ts(4,5): error TS7023: 'ne [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + for (var v of new StringIterator) { } + ~ +!!! error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. \ No newline at end of file diff --git a/tests/baselines/reference/for-of34.js b/tests/baselines/reference/for-of34.js index f61f04ea95..2d9af61d1a 100644 --- a/tests/baselines/reference/for-of34.js +++ b/tests/baselines/reference/for-of34.js @@ -1,6 +1,4 @@ //// [for-of34.ts] -for (var v of new StringIterator) { } - class StringIterator { next() { return v; @@ -9,10 +7,11 @@ class StringIterator { [Symbol.iterator]() { return this; } -} +} + +for (var v of new StringIterator) { } //// [for-of34.js] -for (var v of new StringIterator) { } class StringIterator { next() { return v; @@ -21,3 +20,4 @@ class StringIterator { return this; } } +for (var v of new StringIterator) { } diff --git a/tests/baselines/reference/for-of35.errors.txt b/tests/baselines/reference/for-of35.errors.txt index 58fb5056fd..6f14a24fb9 100644 --- a/tests/baselines/reference/for-of35.errors.txt +++ b/tests/baselines/reference/for-of35.errors.txt @@ -1,12 +1,8 @@ -tests/cases/conformance/es6/for-ofStatements/for-of35.ts(1,10): error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. -tests/cases/conformance/es6/for-ofStatements/for-of35.ts(4,5): error TS7023: 'next' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. +tests/cases/conformance/es6/for-ofStatements/for-of35.ts(2,5): error TS7023: 'next' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. +tests/cases/conformance/es6/for-ofStatements/for-of35.ts(14,10): error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. ==== tests/cases/conformance/es6/for-ofStatements/for-of35.ts (2 errors) ==== - for (var v of new StringIterator) { } - ~ -!!! error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. - class StringIterator { next() { ~~~~ @@ -20,4 +16,8 @@ tests/cases/conformance/es6/for-ofStatements/for-of35.ts(4,5): error TS7023: 'ne [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + for (var v of new StringIterator) { } + ~ +!!! error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. \ No newline at end of file diff --git a/tests/baselines/reference/for-of35.js b/tests/baselines/reference/for-of35.js index c7d7c5890d..a73f873d7c 100644 --- a/tests/baselines/reference/for-of35.js +++ b/tests/baselines/reference/for-of35.js @@ -1,6 +1,4 @@ //// [for-of35.ts] -for (var v of new StringIterator) { } - class StringIterator { next() { return { @@ -12,10 +10,11 @@ class StringIterator { [Symbol.iterator]() { return this; } -} +} + +for (var v of new StringIterator) { } //// [for-of35.js] -for (var v of new StringIterator) { } class StringIterator { next() { return { @@ -27,3 +26,4 @@ class StringIterator { return this; } } +for (var v of new StringIterator) { } diff --git a/tests/baselines/reference/iterableArrayPattern1.js b/tests/baselines/reference/iterableArrayPattern1.js index b45ac92d1f..6061b9950d 100644 --- a/tests/baselines/reference/iterableArrayPattern1.js +++ b/tests/baselines/reference/iterableArrayPattern1.js @@ -1,5 +1,4 @@ //// [iterableArrayPattern1.ts] -var [a, b] = new SymbolIterator; class SymbolIterator { next() { return { @@ -11,10 +10,11 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} +} + +var [a, b] = new SymbolIterator; //// [iterableArrayPattern1.js] -var [a, b] = new SymbolIterator; class SymbolIterator { next() { return { @@ -26,3 +26,4 @@ class SymbolIterator { return this; } } +var [a, b] = new SymbolIterator; diff --git a/tests/baselines/reference/iterableArrayPattern1.symbols b/tests/baselines/reference/iterableArrayPattern1.symbols index 4921fc8ec9..b901b43b7b 100644 --- a/tests/baselines/reference/iterableArrayPattern1.symbols +++ b/tests/baselines/reference/iterableArrayPattern1.symbols @@ -1,22 +1,17 @@ === tests/cases/conformance/es6/destructuring/iterableArrayPattern1.ts === -var [a, b] = new SymbolIterator; ->a : Symbol(a, Decl(iterableArrayPattern1.ts, 0, 5)) ->b : Symbol(b, Decl(iterableArrayPattern1.ts, 0, 7)) ->SymbolIterator : Symbol(SymbolIterator, Decl(iterableArrayPattern1.ts, 0, 32)) - class SymbolIterator { ->SymbolIterator : Symbol(SymbolIterator, Decl(iterableArrayPattern1.ts, 0, 32)) +>SymbolIterator : Symbol(SymbolIterator, Decl(iterableArrayPattern1.ts, 0, 0)) next() { ->next : Symbol(SymbolIterator.next, Decl(iterableArrayPattern1.ts, 1, 22)) +>next : Symbol(SymbolIterator.next, Decl(iterableArrayPattern1.ts, 0, 22)) return { value: Symbol(), ->value : Symbol(value, Decl(iterableArrayPattern1.ts, 3, 16)) +>value : Symbol(value, Decl(iterableArrayPattern1.ts, 2, 16)) >Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) done: false ->done : Symbol(done, Decl(iterableArrayPattern1.ts, 4, 28)) +>done : Symbol(done, Decl(iterableArrayPattern1.ts, 3, 28)) }; } @@ -27,6 +22,12 @@ class SymbolIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(SymbolIterator, Decl(iterableArrayPattern1.ts, 0, 32)) +>this : Symbol(SymbolIterator, Decl(iterableArrayPattern1.ts, 0, 0)) } } + +var [a, b] = new SymbolIterator; +>a : Symbol(a, Decl(iterableArrayPattern1.ts, 13, 5)) +>b : Symbol(b, Decl(iterableArrayPattern1.ts, 13, 7)) +>SymbolIterator : Symbol(SymbolIterator, Decl(iterableArrayPattern1.ts, 0, 0)) + diff --git a/tests/baselines/reference/iterableArrayPattern1.types b/tests/baselines/reference/iterableArrayPattern1.types index 816ce7ac6c..e7d307b2cb 100644 --- a/tests/baselines/reference/iterableArrayPattern1.types +++ b/tests/baselines/reference/iterableArrayPattern1.types @@ -1,10 +1,4 @@ === tests/cases/conformance/es6/destructuring/iterableArrayPattern1.ts === -var [a, b] = new SymbolIterator; ->a : symbol ->b : symbol ->new SymbolIterator : SymbolIterator ->SymbolIterator : typeof SymbolIterator - class SymbolIterator { >SymbolIterator : SymbolIterator @@ -35,3 +29,10 @@ class SymbolIterator { >this : this } } + +var [a, b] = new SymbolIterator; +>a : symbol +>b : symbol +>new SymbolIterator : SymbolIterator +>SymbolIterator : typeof SymbolIterator + diff --git a/tests/baselines/reference/iterableArrayPattern10.errors.txt b/tests/baselines/reference/iterableArrayPattern10.errors.txt index f06c4d7de1..f0b3e14c9f 100644 --- a/tests/baselines/reference/iterableArrayPattern10.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern10.errors.txt @@ -1,13 +1,8 @@ -tests/cases/conformance/es6/destructuring/iterableArrayPattern10.ts(2,5): error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type '[any, any]'. +tests/cases/conformance/es6/destructuring/iterableArrayPattern10.ts(17,5): error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type '[any, any]'. Property '0' is missing in type 'FooIterator'. ==== tests/cases/conformance/es6/destructuring/iterableArrayPattern10.ts (1 errors) ==== - function fun([a, b]) { } - fun(new FooIterator); - ~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type '[any, any]'. -!!! error TS2345: Property '0' is missing in type 'FooIterator'. class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -21,4 +16,10 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern10.ts(2,5): error [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + function fun([a, b]) { } + fun(new FooIterator); + ~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type '[any, any]'. +!!! error TS2345: Property '0' is missing in type 'FooIterator'. \ No newline at end of file diff --git a/tests/baselines/reference/iterableArrayPattern10.js b/tests/baselines/reference/iterableArrayPattern10.js index c8d37e3f89..530a21d6a1 100644 --- a/tests/baselines/reference/iterableArrayPattern10.js +++ b/tests/baselines/reference/iterableArrayPattern10.js @@ -1,6 +1,4 @@ //// [iterableArrayPattern10.ts] -function fun([a, b]) { } -fun(new FooIterator); class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,11 +12,12 @@ class FooIterator { [Symbol.iterator]() { return this; } -} +} + +function fun([a, b]) { } +fun(new FooIterator); //// [iterableArrayPattern10.js] -function fun([a, b]) { } -fun(new FooIterator); class Bar { } class Foo extends Bar { @@ -34,3 +33,5 @@ class FooIterator { return this; } } +function fun([a, b]) { } +fun(new FooIterator); diff --git a/tests/baselines/reference/iterableArrayPattern11.js b/tests/baselines/reference/iterableArrayPattern11.js index 85ed4ab971..92a9d9e200 100644 --- a/tests/baselines/reference/iterableArrayPattern11.js +++ b/tests/baselines/reference/iterableArrayPattern11.js @@ -1,6 +1,4 @@ //// [iterableArrayPattern11.ts] -function fun([a, b] = new FooIterator) { } -fun(new FooIterator); class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,11 +12,13 @@ class FooIterator { [Symbol.iterator]() { return this; } -} +} + +function fun([a, b] = new FooIterator) { } +fun(new FooIterator); + //// [iterableArrayPattern11.js] -function fun([a, b] = new FooIterator) { } -fun(new FooIterator); class Bar { } class Foo extends Bar { @@ -34,3 +34,5 @@ class FooIterator { return this; } } +function fun([a, b] = new FooIterator) { } +fun(new FooIterator); diff --git a/tests/baselines/reference/iterableArrayPattern11.symbols b/tests/baselines/reference/iterableArrayPattern11.symbols index e1b3713f9d..36871283fb 100644 --- a/tests/baselines/reference/iterableArrayPattern11.symbols +++ b/tests/baselines/reference/iterableArrayPattern11.symbols @@ -1,36 +1,26 @@ === tests/cases/conformance/es6/destructuring/iterableArrayPattern11.ts === -function fun([a, b] = new FooIterator) { } ->fun : Symbol(fun, Decl(iterableArrayPattern11.ts, 0, 0)) ->a : Symbol(a, Decl(iterableArrayPattern11.ts, 0, 14)) ->b : Symbol(b, Decl(iterableArrayPattern11.ts, 0, 16)) ->FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern11.ts, 3, 27)) - -fun(new FooIterator); ->fun : Symbol(fun, Decl(iterableArrayPattern11.ts, 0, 0)) ->FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern11.ts, 3, 27)) - class Bar { x } ->Bar : Symbol(Bar, Decl(iterableArrayPattern11.ts, 1, 21)) ->x : Symbol(Bar.x, Decl(iterableArrayPattern11.ts, 2, 11)) +>Bar : Symbol(Bar, Decl(iterableArrayPattern11.ts, 0, 0)) +>x : Symbol(Bar.x, Decl(iterableArrayPattern11.ts, 0, 11)) class Foo extends Bar { y } ->Foo : Symbol(Foo, Decl(iterableArrayPattern11.ts, 2, 15)) ->Bar : Symbol(Bar, Decl(iterableArrayPattern11.ts, 1, 21)) ->y : Symbol(Foo.y, Decl(iterableArrayPattern11.ts, 3, 23)) +>Foo : Symbol(Foo, Decl(iterableArrayPattern11.ts, 0, 15)) +>Bar : Symbol(Bar, Decl(iterableArrayPattern11.ts, 0, 0)) +>y : Symbol(Foo.y, Decl(iterableArrayPattern11.ts, 1, 23)) class FooIterator { ->FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern11.ts, 3, 27)) +>FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern11.ts, 1, 27)) next() { ->next : Symbol(FooIterator.next, Decl(iterableArrayPattern11.ts, 4, 19)) +>next : Symbol(FooIterator.next, Decl(iterableArrayPattern11.ts, 2, 19)) return { value: new Foo, ->value : Symbol(value, Decl(iterableArrayPattern11.ts, 6, 16)) ->Foo : Symbol(Foo, Decl(iterableArrayPattern11.ts, 2, 15)) +>value : Symbol(value, Decl(iterableArrayPattern11.ts, 4, 16)) +>Foo : Symbol(Foo, Decl(iterableArrayPattern11.ts, 0, 15)) done: false ->done : Symbol(done, Decl(iterableArrayPattern11.ts, 7, 27)) +>done : Symbol(done, Decl(iterableArrayPattern11.ts, 5, 27)) }; } @@ -41,6 +31,17 @@ class FooIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(FooIterator, Decl(iterableArrayPattern11.ts, 3, 27)) +>this : Symbol(FooIterator, Decl(iterableArrayPattern11.ts, 1, 27)) } } + +function fun([a, b] = new FooIterator) { } +>fun : Symbol(fun, Decl(iterableArrayPattern11.ts, 13, 1)) +>a : Symbol(a, Decl(iterableArrayPattern11.ts, 15, 14)) +>b : Symbol(b, Decl(iterableArrayPattern11.ts, 15, 16)) +>FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern11.ts, 1, 27)) + +fun(new FooIterator); +>fun : Symbol(fun, Decl(iterableArrayPattern11.ts, 13, 1)) +>FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern11.ts, 1, 27)) + diff --git a/tests/baselines/reference/iterableArrayPattern11.types b/tests/baselines/reference/iterableArrayPattern11.types index 0acadd7cfc..d3fa43d2f1 100644 --- a/tests/baselines/reference/iterableArrayPattern11.types +++ b/tests/baselines/reference/iterableArrayPattern11.types @@ -1,17 +1,4 @@ === tests/cases/conformance/es6/destructuring/iterableArrayPattern11.ts === -function fun([a, b] = new FooIterator) { } ->fun : ([a, b]?: FooIterator) => void ->a : Foo ->b : Foo ->new FooIterator : FooIterator ->FooIterator : typeof FooIterator - -fun(new FooIterator); ->fun(new FooIterator) : void ->fun : ([a, b]?: FooIterator) => void ->new FooIterator : FooIterator ->FooIterator : typeof FooIterator - class Bar { x } >Bar : Bar >x : any @@ -51,3 +38,17 @@ class FooIterator { >this : this } } + +function fun([a, b] = new FooIterator) { } +>fun : ([a, b]?: FooIterator) => void +>a : Foo +>b : Foo +>new FooIterator : FooIterator +>FooIterator : typeof FooIterator + +fun(new FooIterator); +>fun(new FooIterator) : void +>fun : ([a, b]?: FooIterator) => void +>new FooIterator : FooIterator +>FooIterator : typeof FooIterator + diff --git a/tests/baselines/reference/iterableArrayPattern12.js b/tests/baselines/reference/iterableArrayPattern12.js index 4856af9cb4..89694ffa0c 100644 --- a/tests/baselines/reference/iterableArrayPattern12.js +++ b/tests/baselines/reference/iterableArrayPattern12.js @@ -1,6 +1,4 @@ //// [iterableArrayPattern12.ts] -function fun([a, ...b] = new FooIterator) { } -fun(new FooIterator); class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,11 +12,12 @@ class FooIterator { [Symbol.iterator]() { return this; } -} +} + +function fun([a, ...b] = new FooIterator) { } +fun(new FooIterator); //// [iterableArrayPattern12.js] -function fun([a, ...b] = new FooIterator) { } -fun(new FooIterator); class Bar { } class Foo extends Bar { @@ -34,3 +33,5 @@ class FooIterator { return this; } } +function fun([a, ...b] = new FooIterator) { } +fun(new FooIterator); diff --git a/tests/baselines/reference/iterableArrayPattern12.symbols b/tests/baselines/reference/iterableArrayPattern12.symbols index 4044544d17..cb87637087 100644 --- a/tests/baselines/reference/iterableArrayPattern12.symbols +++ b/tests/baselines/reference/iterableArrayPattern12.symbols @@ -1,36 +1,26 @@ === tests/cases/conformance/es6/destructuring/iterableArrayPattern12.ts === -function fun([a, ...b] = new FooIterator) { } ->fun : Symbol(fun, Decl(iterableArrayPattern12.ts, 0, 0)) ->a : Symbol(a, Decl(iterableArrayPattern12.ts, 0, 14)) ->b : Symbol(b, Decl(iterableArrayPattern12.ts, 0, 16)) ->FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern12.ts, 3, 27)) - -fun(new FooIterator); ->fun : Symbol(fun, Decl(iterableArrayPattern12.ts, 0, 0)) ->FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern12.ts, 3, 27)) - class Bar { x } ->Bar : Symbol(Bar, Decl(iterableArrayPattern12.ts, 1, 21)) ->x : Symbol(Bar.x, Decl(iterableArrayPattern12.ts, 2, 11)) +>Bar : Symbol(Bar, Decl(iterableArrayPattern12.ts, 0, 0)) +>x : Symbol(Bar.x, Decl(iterableArrayPattern12.ts, 0, 11)) class Foo extends Bar { y } ->Foo : Symbol(Foo, Decl(iterableArrayPattern12.ts, 2, 15)) ->Bar : Symbol(Bar, Decl(iterableArrayPattern12.ts, 1, 21)) ->y : Symbol(Foo.y, Decl(iterableArrayPattern12.ts, 3, 23)) +>Foo : Symbol(Foo, Decl(iterableArrayPattern12.ts, 0, 15)) +>Bar : Symbol(Bar, Decl(iterableArrayPattern12.ts, 0, 0)) +>y : Symbol(Foo.y, Decl(iterableArrayPattern12.ts, 1, 23)) class FooIterator { ->FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern12.ts, 3, 27)) +>FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern12.ts, 1, 27)) next() { ->next : Symbol(FooIterator.next, Decl(iterableArrayPattern12.ts, 4, 19)) +>next : Symbol(FooIterator.next, Decl(iterableArrayPattern12.ts, 2, 19)) return { value: new Foo, ->value : Symbol(value, Decl(iterableArrayPattern12.ts, 6, 16)) ->Foo : Symbol(Foo, Decl(iterableArrayPattern12.ts, 2, 15)) +>value : Symbol(value, Decl(iterableArrayPattern12.ts, 4, 16)) +>Foo : Symbol(Foo, Decl(iterableArrayPattern12.ts, 0, 15)) done: false ->done : Symbol(done, Decl(iterableArrayPattern12.ts, 7, 27)) +>done : Symbol(done, Decl(iterableArrayPattern12.ts, 5, 27)) }; } @@ -41,6 +31,17 @@ class FooIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(FooIterator, Decl(iterableArrayPattern12.ts, 3, 27)) +>this : Symbol(FooIterator, Decl(iterableArrayPattern12.ts, 1, 27)) } } + +function fun([a, ...b] = new FooIterator) { } +>fun : Symbol(fun, Decl(iterableArrayPattern12.ts, 13, 1)) +>a : Symbol(a, Decl(iterableArrayPattern12.ts, 15, 14)) +>b : Symbol(b, Decl(iterableArrayPattern12.ts, 15, 16)) +>FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern12.ts, 1, 27)) + +fun(new FooIterator); +>fun : Symbol(fun, Decl(iterableArrayPattern12.ts, 13, 1)) +>FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern12.ts, 1, 27)) + diff --git a/tests/baselines/reference/iterableArrayPattern12.types b/tests/baselines/reference/iterableArrayPattern12.types index c00e1daae8..3c50058b3e 100644 --- a/tests/baselines/reference/iterableArrayPattern12.types +++ b/tests/baselines/reference/iterableArrayPattern12.types @@ -1,17 +1,4 @@ === tests/cases/conformance/es6/destructuring/iterableArrayPattern12.ts === -function fun([a, ...b] = new FooIterator) { } ->fun : ([a, ...b]?: FooIterator) => void ->a : Foo ->b : Foo[] ->new FooIterator : FooIterator ->FooIterator : typeof FooIterator - -fun(new FooIterator); ->fun(new FooIterator) : void ->fun : ([a, ...b]?: FooIterator) => void ->new FooIterator : FooIterator ->FooIterator : typeof FooIterator - class Bar { x } >Bar : Bar >x : any @@ -51,3 +38,17 @@ class FooIterator { >this : this } } + +function fun([a, ...b] = new FooIterator) { } +>fun : ([a, ...b]?: FooIterator) => void +>a : Foo +>b : Foo[] +>new FooIterator : FooIterator +>FooIterator : typeof FooIterator + +fun(new FooIterator); +>fun(new FooIterator) : void +>fun : ([a, ...b]?: FooIterator) => void +>new FooIterator : FooIterator +>FooIterator : typeof FooIterator + diff --git a/tests/baselines/reference/iterableArrayPattern13.js b/tests/baselines/reference/iterableArrayPattern13.js index 06f9901a85..efbce2bfd1 100644 --- a/tests/baselines/reference/iterableArrayPattern13.js +++ b/tests/baselines/reference/iterableArrayPattern13.js @@ -1,6 +1,4 @@ //// [iterableArrayPattern13.ts] -function fun([a, ...b]) { } -fun(new FooIterator); class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,11 +12,12 @@ class FooIterator { [Symbol.iterator]() { return this; } -} +} + +function fun([a, ...b]) { } +fun(new FooIterator); //// [iterableArrayPattern13.js] -function fun([a, ...b]) { } -fun(new FooIterator); class Bar { } class Foo extends Bar { @@ -34,3 +33,5 @@ class FooIterator { return this; } } +function fun([a, ...b]) { } +fun(new FooIterator); diff --git a/tests/baselines/reference/iterableArrayPattern13.symbols b/tests/baselines/reference/iterableArrayPattern13.symbols index c04d66fa6d..25241ab24b 100644 --- a/tests/baselines/reference/iterableArrayPattern13.symbols +++ b/tests/baselines/reference/iterableArrayPattern13.symbols @@ -1,35 +1,26 @@ === tests/cases/conformance/es6/destructuring/iterableArrayPattern13.ts === -function fun([a, ...b]) { } ->fun : Symbol(fun, Decl(iterableArrayPattern13.ts, 0, 0)) ->a : Symbol(a, Decl(iterableArrayPattern13.ts, 0, 14)) ->b : Symbol(b, Decl(iterableArrayPattern13.ts, 0, 16)) - -fun(new FooIterator); ->fun : Symbol(fun, Decl(iterableArrayPattern13.ts, 0, 0)) ->FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern13.ts, 3, 27)) - class Bar { x } ->Bar : Symbol(Bar, Decl(iterableArrayPattern13.ts, 1, 21)) ->x : Symbol(Bar.x, Decl(iterableArrayPattern13.ts, 2, 11)) +>Bar : Symbol(Bar, Decl(iterableArrayPattern13.ts, 0, 0)) +>x : Symbol(Bar.x, Decl(iterableArrayPattern13.ts, 0, 11)) class Foo extends Bar { y } ->Foo : Symbol(Foo, Decl(iterableArrayPattern13.ts, 2, 15)) ->Bar : Symbol(Bar, Decl(iterableArrayPattern13.ts, 1, 21)) ->y : Symbol(Foo.y, Decl(iterableArrayPattern13.ts, 3, 23)) +>Foo : Symbol(Foo, Decl(iterableArrayPattern13.ts, 0, 15)) +>Bar : Symbol(Bar, Decl(iterableArrayPattern13.ts, 0, 0)) +>y : Symbol(Foo.y, Decl(iterableArrayPattern13.ts, 1, 23)) class FooIterator { ->FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern13.ts, 3, 27)) +>FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern13.ts, 1, 27)) next() { ->next : Symbol(FooIterator.next, Decl(iterableArrayPattern13.ts, 4, 19)) +>next : Symbol(FooIterator.next, Decl(iterableArrayPattern13.ts, 2, 19)) return { value: new Foo, ->value : Symbol(value, Decl(iterableArrayPattern13.ts, 6, 16)) ->Foo : Symbol(Foo, Decl(iterableArrayPattern13.ts, 2, 15)) +>value : Symbol(value, Decl(iterableArrayPattern13.ts, 4, 16)) +>Foo : Symbol(Foo, Decl(iterableArrayPattern13.ts, 0, 15)) done: false ->done : Symbol(done, Decl(iterableArrayPattern13.ts, 7, 27)) +>done : Symbol(done, Decl(iterableArrayPattern13.ts, 5, 27)) }; } @@ -40,6 +31,16 @@ class FooIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(FooIterator, Decl(iterableArrayPattern13.ts, 3, 27)) +>this : Symbol(FooIterator, Decl(iterableArrayPattern13.ts, 1, 27)) } } + +function fun([a, ...b]) { } +>fun : Symbol(fun, Decl(iterableArrayPattern13.ts, 13, 1)) +>a : Symbol(a, Decl(iterableArrayPattern13.ts, 15, 14)) +>b : Symbol(b, Decl(iterableArrayPattern13.ts, 15, 16)) + +fun(new FooIterator); +>fun : Symbol(fun, Decl(iterableArrayPattern13.ts, 13, 1)) +>FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern13.ts, 1, 27)) + diff --git a/tests/baselines/reference/iterableArrayPattern13.types b/tests/baselines/reference/iterableArrayPattern13.types index 04dab57748..724a0795ef 100644 --- a/tests/baselines/reference/iterableArrayPattern13.types +++ b/tests/baselines/reference/iterableArrayPattern13.types @@ -1,15 +1,4 @@ === tests/cases/conformance/es6/destructuring/iterableArrayPattern13.ts === -function fun([a, ...b]) { } ->fun : ([a, ...b]: Iterable) => void ->a : any ->b : any[] - -fun(new FooIterator); ->fun(new FooIterator) : void ->fun : ([a, ...b]: Iterable) => void ->new FooIterator : FooIterator ->FooIterator : typeof FooIterator - class Bar { x } >Bar : Bar >x : any @@ -49,3 +38,15 @@ class FooIterator { >this : this } } + +function fun([a, ...b]) { } +>fun : ([a, ...b]: Iterable) => void +>a : any +>b : any[] + +fun(new FooIterator); +>fun(new FooIterator) : void +>fun : ([a, ...b]: Iterable) => void +>new FooIterator : FooIterator +>FooIterator : typeof FooIterator + diff --git a/tests/baselines/reference/iterableArrayPattern14.errors.txt b/tests/baselines/reference/iterableArrayPattern14.errors.txt index a14ddc4502..664f73e13a 100644 --- a/tests/baselines/reference/iterableArrayPattern14.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern14.errors.txt @@ -1,11 +1,7 @@ -tests/cases/conformance/es6/destructuring/iterableArrayPattern14.ts(1,17): error TS2501: A rest element cannot contain a binding pattern. +tests/cases/conformance/es6/destructuring/iterableArrayPattern14.ts(16,17): error TS2501: A rest element cannot contain a binding pattern. ==== tests/cases/conformance/es6/destructuring/iterableArrayPattern14.ts (1 errors) ==== - function fun(...[a, ...b]) { } - ~~~~~~~~~ -!!! error TS2501: A rest element cannot contain a binding pattern. - fun(new FooIterator); class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -19,4 +15,9 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern14.ts(1,17): error [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + function fun(...[a, ...b]) { } + ~~~~~~~~~ +!!! error TS2501: A rest element cannot contain a binding pattern. + fun(new FooIterator); \ No newline at end of file diff --git a/tests/baselines/reference/iterableArrayPattern14.js b/tests/baselines/reference/iterableArrayPattern14.js index a3595b0df0..bb1d416f4f 100644 --- a/tests/baselines/reference/iterableArrayPattern14.js +++ b/tests/baselines/reference/iterableArrayPattern14.js @@ -1,6 +1,4 @@ //// [iterableArrayPattern14.ts] -function fun(...[a, ...b]) { } -fun(new FooIterator); class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,11 +12,12 @@ class FooIterator { [Symbol.iterator]() { return this; } -} +} + +function fun(...[a, ...b]) { } +fun(new FooIterator); //// [iterableArrayPattern14.js] -function fun(...[a, ...b]) { } -fun(new FooIterator); class Bar { } class Foo extends Bar { @@ -34,3 +33,5 @@ class FooIterator { return this; } } +function fun(...[a, ...b]) { } +fun(new FooIterator); diff --git a/tests/baselines/reference/iterableArrayPattern15.errors.txt b/tests/baselines/reference/iterableArrayPattern15.errors.txt index bb2d1eb096..ce7559de94 100644 --- a/tests/baselines/reference/iterableArrayPattern15.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern15.errors.txt @@ -1,11 +1,7 @@ -tests/cases/conformance/es6/destructuring/iterableArrayPattern15.ts(1,17): error TS2501: A rest element cannot contain a binding pattern. +tests/cases/conformance/es6/destructuring/iterableArrayPattern15.ts(16,17): error TS2501: A rest element cannot contain a binding pattern. ==== tests/cases/conformance/es6/destructuring/iterableArrayPattern15.ts (1 errors) ==== - function fun(...[a, b]: Bar[]) { } - ~~~~~~ -!!! error TS2501: A rest element cannot contain a binding pattern. - fun(...new FooIterator); class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -19,4 +15,9 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern15.ts(1,17): error [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + function fun(...[a, b]: Bar[]) { } + ~~~~~~ +!!! error TS2501: A rest element cannot contain a binding pattern. + fun(...new FooIterator); \ No newline at end of file diff --git a/tests/baselines/reference/iterableArrayPattern15.js b/tests/baselines/reference/iterableArrayPattern15.js index 1c2050129c..d14fd1b364 100644 --- a/tests/baselines/reference/iterableArrayPattern15.js +++ b/tests/baselines/reference/iterableArrayPattern15.js @@ -1,6 +1,4 @@ //// [iterableArrayPattern15.ts] -function fun(...[a, b]: Bar[]) { } -fun(...new FooIterator); class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,11 +12,12 @@ class FooIterator { [Symbol.iterator]() { return this; } -} +} + +function fun(...[a, b]: Bar[]) { } +fun(...new FooIterator); //// [iterableArrayPattern15.js] -function fun(...[a, b]) { } -fun(...new FooIterator); class Bar { } class Foo extends Bar { @@ -34,3 +33,5 @@ class FooIterator { return this; } } +function fun(...[a, b]) { } +fun(...new FooIterator); diff --git a/tests/baselines/reference/iterableArrayPattern16.errors.txt b/tests/baselines/reference/iterableArrayPattern16.errors.txt index e03d0a799d..ba5531a0a5 100644 --- a/tests/baselines/reference/iterableArrayPattern16.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern16.errors.txt @@ -1,9 +1,10 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts(1,17): error TS2501: A rest element cannot contain a binding pattern. tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts(2,5): error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type '[Bar, Bar]'. Property '0' is missing in type 'FooIterator'. +tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts(2,12): error TS2449: Class 'FooIteratorIterator' used before its declaration. -==== tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts (2 errors) ==== +==== tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts (3 errors) ==== function fun(...[a, b]: [Bar, Bar][]) { } ~~~~~~ !!! error TS2501: A rest element cannot contain a binding pattern. @@ -11,6 +12,8 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts(2,5): error ~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type '[Bar, Bar]'. !!! error TS2345: Property '0' is missing in type 'FooIterator'. + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2449: Class 'FooIteratorIterator' used before its declaration. class Bar { x } class Foo extends Bar { y } class FooIterator { diff --git a/tests/baselines/reference/iterableArrayPattern17.errors.txt b/tests/baselines/reference/iterableArrayPattern17.errors.txt index 3cc04fadd1..d22d8580c7 100644 --- a/tests/baselines/reference/iterableArrayPattern17.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern17.errors.txt @@ -1,16 +1,9 @@ -tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts(1,17): error TS2501: A rest element cannot contain a binding pattern. -tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts(2,5): error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type 'Bar'. +tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts(16,17): error TS2501: A rest element cannot contain a binding pattern. +tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts(17,5): error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type 'Bar'. Property 'x' is missing in type 'FooIterator'. ==== tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts (2 errors) ==== - function fun(...[a, b]: Bar[]) { } - ~~~~~~ -!!! error TS2501: A rest element cannot contain a binding pattern. - fun(new FooIterator); - ~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type 'Bar'. -!!! error TS2345: Property 'x' is missing in type 'FooIterator'. class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -24,4 +17,12 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts(2,5): error [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + function fun(...[a, b]: Bar[]) { } + ~~~~~~ +!!! error TS2501: A rest element cannot contain a binding pattern. + fun(new FooIterator); + ~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type 'Bar'. +!!! error TS2345: Property 'x' is missing in type 'FooIterator'. \ No newline at end of file diff --git a/tests/baselines/reference/iterableArrayPattern17.js b/tests/baselines/reference/iterableArrayPattern17.js index c6274aabcd..e9979380af 100644 --- a/tests/baselines/reference/iterableArrayPattern17.js +++ b/tests/baselines/reference/iterableArrayPattern17.js @@ -1,6 +1,4 @@ //// [iterableArrayPattern17.ts] -function fun(...[a, b]: Bar[]) { } -fun(new FooIterator); class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,11 +12,12 @@ class FooIterator { [Symbol.iterator]() { return this; } -} +} + +function fun(...[a, b]: Bar[]) { } +fun(new FooIterator); //// [iterableArrayPattern17.js] -function fun(...[a, b]) { } -fun(new FooIterator); class Bar { } class Foo extends Bar { @@ -34,3 +33,5 @@ class FooIterator { return this; } } +function fun(...[a, b]) { } +fun(new FooIterator); diff --git a/tests/baselines/reference/iterableArrayPattern18.errors.txt b/tests/baselines/reference/iterableArrayPattern18.errors.txt index c6f8c5e28b..a3f8b6f840 100644 --- a/tests/baselines/reference/iterableArrayPattern18.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern18.errors.txt @@ -1,13 +1,8 @@ -tests/cases/conformance/es6/destructuring/iterableArrayPattern18.ts(2,5): error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type 'Bar[]'. +tests/cases/conformance/es6/destructuring/iterableArrayPattern18.ts(17,5): error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type 'Bar[]'. Property 'length' is missing in type 'FooIterator'. ==== tests/cases/conformance/es6/destructuring/iterableArrayPattern18.ts (1 errors) ==== - function fun([a, b]: Bar[]) { } - fun(new FooIterator); - ~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type 'Bar[]'. -!!! error TS2345: Property 'length' is missing in type 'FooIterator'. class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -21,4 +16,10 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern18.ts(2,5): error [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + function fun([a, b]: Bar[]) { } + fun(new FooIterator); + ~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type 'Bar[]'. +!!! error TS2345: Property 'length' is missing in type 'FooIterator'. \ No newline at end of file diff --git a/tests/baselines/reference/iterableArrayPattern18.js b/tests/baselines/reference/iterableArrayPattern18.js index e2016c4769..93b038cd32 100644 --- a/tests/baselines/reference/iterableArrayPattern18.js +++ b/tests/baselines/reference/iterableArrayPattern18.js @@ -1,6 +1,4 @@ //// [iterableArrayPattern18.ts] -function fun([a, b]: Bar[]) { } -fun(new FooIterator); class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,11 +12,12 @@ class FooIterator { [Symbol.iterator]() { return this; } -} +} + +function fun([a, b]: Bar[]) { } +fun(new FooIterator); //// [iterableArrayPattern18.js] -function fun([a, b]) { } -fun(new FooIterator); class Bar { } class Foo extends Bar { @@ -34,3 +33,5 @@ class FooIterator { return this; } } +function fun([a, b]) { } +fun(new FooIterator); diff --git a/tests/baselines/reference/iterableArrayPattern19.errors.txt b/tests/baselines/reference/iterableArrayPattern19.errors.txt index 3f8b550d28..f4a9fac0a0 100644 --- a/tests/baselines/reference/iterableArrayPattern19.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern19.errors.txt @@ -1,13 +1,8 @@ -tests/cases/conformance/es6/destructuring/iterableArrayPattern19.ts(2,5): error TS2345: Argument of type 'FooArrayIterator' is not assignable to parameter of type 'Bar[][]'. +tests/cases/conformance/es6/destructuring/iterableArrayPattern19.ts(17,5): error TS2345: Argument of type 'FooArrayIterator' is not assignable to parameter of type 'Bar[][]'. Property 'length' is missing in type 'FooArrayIterator'. ==== tests/cases/conformance/es6/destructuring/iterableArrayPattern19.ts (1 errors) ==== - function fun([[a], b]: Bar[][]) { } - fun(new FooArrayIterator); - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type 'FooArrayIterator' is not assignable to parameter of type 'Bar[][]'. -!!! error TS2345: Property 'length' is missing in type 'FooArrayIterator'. class Bar { x } class Foo extends Bar { y } class FooArrayIterator { @@ -21,4 +16,10 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern19.ts(2,5): error [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + function fun([[a], b]: Bar[][]) { } + fun(new FooArrayIterator); + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type 'FooArrayIterator' is not assignable to parameter of type 'Bar[][]'. +!!! error TS2345: Property 'length' is missing in type 'FooArrayIterator'. \ No newline at end of file diff --git a/tests/baselines/reference/iterableArrayPattern19.js b/tests/baselines/reference/iterableArrayPattern19.js index bc3cf33afc..3c930957f4 100644 --- a/tests/baselines/reference/iterableArrayPattern19.js +++ b/tests/baselines/reference/iterableArrayPattern19.js @@ -1,6 +1,4 @@ //// [iterableArrayPattern19.ts] -function fun([[a], b]: Bar[][]) { } -fun(new FooArrayIterator); class Bar { x } class Foo extends Bar { y } class FooArrayIterator { @@ -14,11 +12,12 @@ class FooArrayIterator { [Symbol.iterator]() { return this; } -} +} + +function fun([[a], b]: Bar[][]) { } +fun(new FooArrayIterator); //// [iterableArrayPattern19.js] -function fun([[a], b]) { } -fun(new FooArrayIterator); class Bar { } class Foo extends Bar { @@ -34,3 +33,5 @@ class FooArrayIterator { return this; } } +function fun([[a], b]) { } +fun(new FooArrayIterator); diff --git a/tests/baselines/reference/iterableArrayPattern2.js b/tests/baselines/reference/iterableArrayPattern2.js index 7392db7d6b..aab7ad9ec6 100644 --- a/tests/baselines/reference/iterableArrayPattern2.js +++ b/tests/baselines/reference/iterableArrayPattern2.js @@ -1,5 +1,4 @@ //// [iterableArrayPattern2.ts] -var [a, ...b] = new SymbolIterator; class SymbolIterator { next() { return { @@ -11,10 +10,11 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} +} + +var [a, ...b] = new SymbolIterator; //// [iterableArrayPattern2.js] -var [a, ...b] = new SymbolIterator; class SymbolIterator { next() { return { @@ -26,3 +26,4 @@ class SymbolIterator { return this; } } +var [a, ...b] = new SymbolIterator; diff --git a/tests/baselines/reference/iterableArrayPattern2.symbols b/tests/baselines/reference/iterableArrayPattern2.symbols index 50d3352b9e..db700cdd57 100644 --- a/tests/baselines/reference/iterableArrayPattern2.symbols +++ b/tests/baselines/reference/iterableArrayPattern2.symbols @@ -1,22 +1,17 @@ === tests/cases/conformance/es6/destructuring/iterableArrayPattern2.ts === -var [a, ...b] = new SymbolIterator; ->a : Symbol(a, Decl(iterableArrayPattern2.ts, 0, 5)) ->b : Symbol(b, Decl(iterableArrayPattern2.ts, 0, 7)) ->SymbolIterator : Symbol(SymbolIterator, Decl(iterableArrayPattern2.ts, 0, 35)) - class SymbolIterator { ->SymbolIterator : Symbol(SymbolIterator, Decl(iterableArrayPattern2.ts, 0, 35)) +>SymbolIterator : Symbol(SymbolIterator, Decl(iterableArrayPattern2.ts, 0, 0)) next() { ->next : Symbol(SymbolIterator.next, Decl(iterableArrayPattern2.ts, 1, 22)) +>next : Symbol(SymbolIterator.next, Decl(iterableArrayPattern2.ts, 0, 22)) return { value: Symbol(), ->value : Symbol(value, Decl(iterableArrayPattern2.ts, 3, 16)) +>value : Symbol(value, Decl(iterableArrayPattern2.ts, 2, 16)) >Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) done: false ->done : Symbol(done, Decl(iterableArrayPattern2.ts, 4, 28)) +>done : Symbol(done, Decl(iterableArrayPattern2.ts, 3, 28)) }; } @@ -27,6 +22,12 @@ class SymbolIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(SymbolIterator, Decl(iterableArrayPattern2.ts, 0, 35)) +>this : Symbol(SymbolIterator, Decl(iterableArrayPattern2.ts, 0, 0)) } } + +var [a, ...b] = new SymbolIterator; +>a : Symbol(a, Decl(iterableArrayPattern2.ts, 13, 5)) +>b : Symbol(b, Decl(iterableArrayPattern2.ts, 13, 7)) +>SymbolIterator : Symbol(SymbolIterator, Decl(iterableArrayPattern2.ts, 0, 0)) + diff --git a/tests/baselines/reference/iterableArrayPattern2.types b/tests/baselines/reference/iterableArrayPattern2.types index 63786a1d35..6a1bc9eb6f 100644 --- a/tests/baselines/reference/iterableArrayPattern2.types +++ b/tests/baselines/reference/iterableArrayPattern2.types @@ -1,10 +1,4 @@ === tests/cases/conformance/es6/destructuring/iterableArrayPattern2.ts === -var [a, ...b] = new SymbolIterator; ->a : symbol ->b : symbol[] ->new SymbolIterator : SymbolIterator ->SymbolIterator : typeof SymbolIterator - class SymbolIterator { >SymbolIterator : SymbolIterator @@ -35,3 +29,10 @@ class SymbolIterator { >this : this } } + +var [a, ...b] = new SymbolIterator; +>a : symbol +>b : symbol[] +>new SymbolIterator : SymbolIterator +>SymbolIterator : typeof SymbolIterator + diff --git a/tests/baselines/reference/iterableArrayPattern20.errors.txt b/tests/baselines/reference/iterableArrayPattern20.errors.txt index 4451a814bd..23f133238c 100644 --- a/tests/baselines/reference/iterableArrayPattern20.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern20.errors.txt @@ -1,11 +1,7 @@ -tests/cases/conformance/es6/destructuring/iterableArrayPattern20.ts(1,17): error TS2501: A rest element cannot contain a binding pattern. +tests/cases/conformance/es6/destructuring/iterableArrayPattern20.ts(16,17): error TS2501: A rest element cannot contain a binding pattern. ==== tests/cases/conformance/es6/destructuring/iterableArrayPattern20.ts (1 errors) ==== - function fun(...[[a = new Foo], b = [new Foo]]: Bar[][]) { } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2501: A rest element cannot contain a binding pattern. - fun(...new FooArrayIterator); class Bar { x } class Foo extends Bar { y } class FooArrayIterator { @@ -19,4 +15,9 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern20.ts(1,17): error [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + function fun(...[[a = new Foo], b = [new Foo]]: Bar[][]) { } + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2501: A rest element cannot contain a binding pattern. + fun(...new FooArrayIterator); \ No newline at end of file diff --git a/tests/baselines/reference/iterableArrayPattern20.js b/tests/baselines/reference/iterableArrayPattern20.js index 489f97a29f..a327cb3e47 100644 --- a/tests/baselines/reference/iterableArrayPattern20.js +++ b/tests/baselines/reference/iterableArrayPattern20.js @@ -1,6 +1,4 @@ //// [iterableArrayPattern20.ts] -function fun(...[[a = new Foo], b = [new Foo]]: Bar[][]) { } -fun(...new FooArrayIterator); class Bar { x } class Foo extends Bar { y } class FooArrayIterator { @@ -14,11 +12,12 @@ class FooArrayIterator { [Symbol.iterator]() { return this; } -} +} + +function fun(...[[a = new Foo], b = [new Foo]]: Bar[][]) { } +fun(...new FooArrayIterator); //// [iterableArrayPattern20.js] -function fun(...[[a = new Foo], b = [new Foo]]) { } -fun(...new FooArrayIterator); class Bar { } class Foo extends Bar { @@ -34,3 +33,5 @@ class FooArrayIterator { return this; } } +function fun(...[[a = new Foo], b = [new Foo]]) { } +fun(...new FooArrayIterator); diff --git a/tests/baselines/reference/iterableArrayPattern3.js b/tests/baselines/reference/iterableArrayPattern3.js index 7136c6ab20..e29a67af73 100644 --- a/tests/baselines/reference/iterableArrayPattern3.js +++ b/tests/baselines/reference/iterableArrayPattern3.js @@ -1,6 +1,4 @@ //// [iterableArrayPattern3.ts] -var a: Bar, b: Bar; -[a, b] = new FooIterator; class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,11 +12,12 @@ class FooIterator { [Symbol.iterator]() { return this; } -} +} + +var a: Bar, b: Bar; +[a, b] = new FooIterator; //// [iterableArrayPattern3.js] -var a, b; -[a, b] = new FooIterator; class Bar { } class Foo extends Bar { @@ -34,3 +33,5 @@ class FooIterator { return this; } } +var a, b; +[a, b] = new FooIterator; diff --git a/tests/baselines/reference/iterableArrayPattern3.symbols b/tests/baselines/reference/iterableArrayPattern3.symbols index 6cf0980138..a82c5f5e02 100644 --- a/tests/baselines/reference/iterableArrayPattern3.symbols +++ b/tests/baselines/reference/iterableArrayPattern3.symbols @@ -1,37 +1,26 @@ === tests/cases/conformance/es6/destructuring/iterableArrayPattern3.ts === -var a: Bar, b: Bar; ->a : Symbol(a, Decl(iterableArrayPattern3.ts, 0, 3)) ->Bar : Symbol(Bar, Decl(iterableArrayPattern3.ts, 1, 25)) ->b : Symbol(b, Decl(iterableArrayPattern3.ts, 0, 11)) ->Bar : Symbol(Bar, Decl(iterableArrayPattern3.ts, 1, 25)) - -[a, b] = new FooIterator; ->a : Symbol(a, Decl(iterableArrayPattern3.ts, 0, 3)) ->b : Symbol(b, Decl(iterableArrayPattern3.ts, 0, 11)) ->FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern3.ts, 3, 27)) - class Bar { x } ->Bar : Symbol(Bar, Decl(iterableArrayPattern3.ts, 1, 25)) ->x : Symbol(Bar.x, Decl(iterableArrayPattern3.ts, 2, 11)) +>Bar : Symbol(Bar, Decl(iterableArrayPattern3.ts, 0, 0)) +>x : Symbol(Bar.x, Decl(iterableArrayPattern3.ts, 0, 11)) class Foo extends Bar { y } ->Foo : Symbol(Foo, Decl(iterableArrayPattern3.ts, 2, 15)) ->Bar : Symbol(Bar, Decl(iterableArrayPattern3.ts, 1, 25)) ->y : Symbol(Foo.y, Decl(iterableArrayPattern3.ts, 3, 23)) +>Foo : Symbol(Foo, Decl(iterableArrayPattern3.ts, 0, 15)) +>Bar : Symbol(Bar, Decl(iterableArrayPattern3.ts, 0, 0)) +>y : Symbol(Foo.y, Decl(iterableArrayPattern3.ts, 1, 23)) class FooIterator { ->FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern3.ts, 3, 27)) +>FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern3.ts, 1, 27)) next() { ->next : Symbol(FooIterator.next, Decl(iterableArrayPattern3.ts, 4, 19)) +>next : Symbol(FooIterator.next, Decl(iterableArrayPattern3.ts, 2, 19)) return { value: new Foo, ->value : Symbol(value, Decl(iterableArrayPattern3.ts, 6, 16)) ->Foo : Symbol(Foo, Decl(iterableArrayPattern3.ts, 2, 15)) +>value : Symbol(value, Decl(iterableArrayPattern3.ts, 4, 16)) +>Foo : Symbol(Foo, Decl(iterableArrayPattern3.ts, 0, 15)) done: false ->done : Symbol(done, Decl(iterableArrayPattern3.ts, 7, 27)) +>done : Symbol(done, Decl(iterableArrayPattern3.ts, 5, 27)) }; } @@ -42,6 +31,18 @@ class FooIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(FooIterator, Decl(iterableArrayPattern3.ts, 3, 27)) +>this : Symbol(FooIterator, Decl(iterableArrayPattern3.ts, 1, 27)) } } + +var a: Bar, b: Bar; +>a : Symbol(a, Decl(iterableArrayPattern3.ts, 15, 3)) +>Bar : Symbol(Bar, Decl(iterableArrayPattern3.ts, 0, 0)) +>b : Symbol(b, Decl(iterableArrayPattern3.ts, 15, 11)) +>Bar : Symbol(Bar, Decl(iterableArrayPattern3.ts, 0, 0)) + +[a, b] = new FooIterator; +>a : Symbol(a, Decl(iterableArrayPattern3.ts, 15, 3)) +>b : Symbol(b, Decl(iterableArrayPattern3.ts, 15, 11)) +>FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern3.ts, 1, 27)) + diff --git a/tests/baselines/reference/iterableArrayPattern3.types b/tests/baselines/reference/iterableArrayPattern3.types index a21e702526..b138c8629d 100644 --- a/tests/baselines/reference/iterableArrayPattern3.types +++ b/tests/baselines/reference/iterableArrayPattern3.types @@ -1,18 +1,4 @@ === tests/cases/conformance/es6/destructuring/iterableArrayPattern3.ts === -var a: Bar, b: Bar; ->a : Bar ->Bar : Bar ->b : Bar ->Bar : Bar - -[a, b] = new FooIterator; ->[a, b] = new FooIterator : FooIterator ->[a, b] : [Bar, Bar] ->a : Bar ->b : Bar ->new FooIterator : FooIterator ->FooIterator : typeof FooIterator - class Bar { x } >Bar : Bar >x : any @@ -52,3 +38,18 @@ class FooIterator { >this : this } } + +var a: Bar, b: Bar; +>a : Bar +>Bar : Bar +>b : Bar +>Bar : Bar + +[a, b] = new FooIterator; +>[a, b] = new FooIterator : FooIterator +>[a, b] : [Bar, Bar] +>a : Bar +>b : Bar +>new FooIterator : FooIterator +>FooIterator : typeof FooIterator + diff --git a/tests/baselines/reference/iterableArrayPattern4.js b/tests/baselines/reference/iterableArrayPattern4.js index 6e60dadbd7..c53b6ef416 100644 --- a/tests/baselines/reference/iterableArrayPattern4.js +++ b/tests/baselines/reference/iterableArrayPattern4.js @@ -1,6 +1,4 @@ //// [iterableArrayPattern4.ts] -var a: Bar, b: Bar[]; -[a, ...b] = new FooIterator; class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,11 +12,12 @@ class FooIterator { [Symbol.iterator]() { return this; } -} +} + +var a: Bar, b: Bar[]; +[a, ...b] = new FooIterator //// [iterableArrayPattern4.js] -var a, b; -[a, ...b] = new FooIterator; class Bar { } class Foo extends Bar { @@ -34,3 +33,5 @@ class FooIterator { return this; } } +var a, b; +[a, ...b] = new FooIterator; diff --git a/tests/baselines/reference/iterableArrayPattern4.symbols b/tests/baselines/reference/iterableArrayPattern4.symbols index 651c60cf08..6a3526a348 100644 --- a/tests/baselines/reference/iterableArrayPattern4.symbols +++ b/tests/baselines/reference/iterableArrayPattern4.symbols @@ -1,37 +1,26 @@ === tests/cases/conformance/es6/destructuring/iterableArrayPattern4.ts === -var a: Bar, b: Bar[]; ->a : Symbol(a, Decl(iterableArrayPattern4.ts, 0, 3)) ->Bar : Symbol(Bar, Decl(iterableArrayPattern4.ts, 1, 28)) ->b : Symbol(b, Decl(iterableArrayPattern4.ts, 0, 11)) ->Bar : Symbol(Bar, Decl(iterableArrayPattern4.ts, 1, 28)) - -[a, ...b] = new FooIterator; ->a : Symbol(a, Decl(iterableArrayPattern4.ts, 0, 3)) ->b : Symbol(b, Decl(iterableArrayPattern4.ts, 0, 11)) ->FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern4.ts, 3, 27)) - class Bar { x } ->Bar : Symbol(Bar, Decl(iterableArrayPattern4.ts, 1, 28)) ->x : Symbol(Bar.x, Decl(iterableArrayPattern4.ts, 2, 11)) +>Bar : Symbol(Bar, Decl(iterableArrayPattern4.ts, 0, 0)) +>x : Symbol(Bar.x, Decl(iterableArrayPattern4.ts, 0, 11)) class Foo extends Bar { y } ->Foo : Symbol(Foo, Decl(iterableArrayPattern4.ts, 2, 15)) ->Bar : Symbol(Bar, Decl(iterableArrayPattern4.ts, 1, 28)) ->y : Symbol(Foo.y, Decl(iterableArrayPattern4.ts, 3, 23)) +>Foo : Symbol(Foo, Decl(iterableArrayPattern4.ts, 0, 15)) +>Bar : Symbol(Bar, Decl(iterableArrayPattern4.ts, 0, 0)) +>y : Symbol(Foo.y, Decl(iterableArrayPattern4.ts, 1, 23)) class FooIterator { ->FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern4.ts, 3, 27)) +>FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern4.ts, 1, 27)) next() { ->next : Symbol(FooIterator.next, Decl(iterableArrayPattern4.ts, 4, 19)) +>next : Symbol(FooIterator.next, Decl(iterableArrayPattern4.ts, 2, 19)) return { value: new Foo, ->value : Symbol(value, Decl(iterableArrayPattern4.ts, 6, 16)) ->Foo : Symbol(Foo, Decl(iterableArrayPattern4.ts, 2, 15)) +>value : Symbol(value, Decl(iterableArrayPattern4.ts, 4, 16)) +>Foo : Symbol(Foo, Decl(iterableArrayPattern4.ts, 0, 15)) done: false ->done : Symbol(done, Decl(iterableArrayPattern4.ts, 7, 27)) +>done : Symbol(done, Decl(iterableArrayPattern4.ts, 5, 27)) }; } @@ -42,6 +31,18 @@ class FooIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(FooIterator, Decl(iterableArrayPattern4.ts, 3, 27)) +>this : Symbol(FooIterator, Decl(iterableArrayPattern4.ts, 1, 27)) } } + +var a: Bar, b: Bar[]; +>a : Symbol(a, Decl(iterableArrayPattern4.ts, 15, 3)) +>Bar : Symbol(Bar, Decl(iterableArrayPattern4.ts, 0, 0)) +>b : Symbol(b, Decl(iterableArrayPattern4.ts, 15, 11)) +>Bar : Symbol(Bar, Decl(iterableArrayPattern4.ts, 0, 0)) + +[a, ...b] = new FooIterator +>a : Symbol(a, Decl(iterableArrayPattern4.ts, 15, 3)) +>b : Symbol(b, Decl(iterableArrayPattern4.ts, 15, 11)) +>FooIterator : Symbol(FooIterator, Decl(iterableArrayPattern4.ts, 1, 27)) + diff --git a/tests/baselines/reference/iterableArrayPattern4.types b/tests/baselines/reference/iterableArrayPattern4.types index a3be411449..1024f4c967 100644 --- a/tests/baselines/reference/iterableArrayPattern4.types +++ b/tests/baselines/reference/iterableArrayPattern4.types @@ -1,19 +1,4 @@ === tests/cases/conformance/es6/destructuring/iterableArrayPattern4.ts === -var a: Bar, b: Bar[]; ->a : Bar ->Bar : Bar ->b : Bar[] ->Bar : Bar - -[a, ...b] = new FooIterator; ->[a, ...b] = new FooIterator : FooIterator ->[a, ...b] : Bar[] ->a : Bar ->...b : Bar ->b : Bar[] ->new FooIterator : FooIterator ->FooIterator : typeof FooIterator - class Bar { x } >Bar : Bar >x : any @@ -53,3 +38,19 @@ class FooIterator { >this : this } } + +var a: Bar, b: Bar[]; +>a : Bar +>Bar : Bar +>b : Bar[] +>Bar : Bar + +[a, ...b] = new FooIterator +>[a, ...b] = new FooIterator : FooIterator +>[a, ...b] : Bar[] +>a : Bar +>...b : Bar +>b : Bar[] +>new FooIterator : FooIterator +>FooIterator : typeof FooIterator + diff --git a/tests/baselines/reference/iterableArrayPattern5.errors.txt b/tests/baselines/reference/iterableArrayPattern5.errors.txt index ca540d805b..1bbbe268e6 100644 --- a/tests/baselines/reference/iterableArrayPattern5.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern5.errors.txt @@ -1,11 +1,7 @@ -tests/cases/conformance/es6/destructuring/iterableArrayPattern5.ts(2,5): error TS2322: Type 'Foo' is not assignable to type 'string'. +tests/cases/conformance/es6/destructuring/iterableArrayPattern5.ts(17,5): error TS2322: Type 'Foo' is not assignable to type 'string'. ==== tests/cases/conformance/es6/destructuring/iterableArrayPattern5.ts (1 errors) ==== - var a: Bar, b: string; - [a, b] = new FooIterator; - ~ -!!! error TS2322: Type 'Foo' is not assignable to type 'string'. class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -19,4 +15,9 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern5.ts(2,5): error T [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + var a: Bar, b: string; + [a, b] = new FooIterator; + ~ +!!! error TS2322: Type 'Foo' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/iterableArrayPattern5.js b/tests/baselines/reference/iterableArrayPattern5.js index 77e71cac6d..56ed70b137 100644 --- a/tests/baselines/reference/iterableArrayPattern5.js +++ b/tests/baselines/reference/iterableArrayPattern5.js @@ -1,6 +1,4 @@ //// [iterableArrayPattern5.ts] -var a: Bar, b: string; -[a, b] = new FooIterator; class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,11 +12,12 @@ class FooIterator { [Symbol.iterator]() { return this; } -} +} + +var a: Bar, b: string; +[a, b] = new FooIterator; //// [iterableArrayPattern5.js] -var a, b; -[a, b] = new FooIterator; class Bar { } class Foo extends Bar { @@ -34,3 +33,5 @@ class FooIterator { return this; } } +var a, b; +[a, b] = new FooIterator; diff --git a/tests/baselines/reference/iterableArrayPattern6.errors.txt b/tests/baselines/reference/iterableArrayPattern6.errors.txt index e0a546d154..3a20f1f52c 100644 --- a/tests/baselines/reference/iterableArrayPattern6.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern6.errors.txt @@ -1,13 +1,8 @@ -tests/cases/conformance/es6/destructuring/iterableArrayPattern6.ts(2,8): error TS2322: Type 'Foo[]' is not assignable to type 'string[]'. +tests/cases/conformance/es6/destructuring/iterableArrayPattern6.ts(17,8): error TS2322: Type 'Foo[]' is not assignable to type 'string[]'. Type 'Foo' is not assignable to type 'string'. ==== tests/cases/conformance/es6/destructuring/iterableArrayPattern6.ts (1 errors) ==== - var a: Bar, b: string[]; - [a, ...b] = new FooIterator; - ~ -!!! error TS2322: Type 'Foo[]' is not assignable to type 'string[]'. -!!! error TS2322: Type 'Foo' is not assignable to type 'string'. class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -21,4 +16,10 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern6.ts(2,8): error T [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + var a: Bar, b: string[]; + [a, ...b] = new FooIterator; + ~ +!!! error TS2322: Type 'Foo[]' is not assignable to type 'string[]'. +!!! error TS2322: Type 'Foo' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/iterableArrayPattern6.js b/tests/baselines/reference/iterableArrayPattern6.js index 8c797e819f..1053cced9c 100644 --- a/tests/baselines/reference/iterableArrayPattern6.js +++ b/tests/baselines/reference/iterableArrayPattern6.js @@ -1,6 +1,4 @@ //// [iterableArrayPattern6.ts] -var a: Bar, b: string[]; -[a, ...b] = new FooIterator; class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,11 +12,12 @@ class FooIterator { [Symbol.iterator]() { return this; } -} +} + +var a: Bar, b: string[]; +[a, ...b] = new FooIterator; //// [iterableArrayPattern6.js] -var a, b; -[a, ...b] = new FooIterator; class Bar { } class Foo extends Bar { @@ -34,3 +33,5 @@ class FooIterator { return this; } } +var a, b; +[a, ...b] = new FooIterator; diff --git a/tests/baselines/reference/iterableArrayPattern7.errors.txt b/tests/baselines/reference/iterableArrayPattern7.errors.txt index 997cc21f38..972de74039 100644 --- a/tests/baselines/reference/iterableArrayPattern7.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern7.errors.txt @@ -1,13 +1,8 @@ -tests/cases/conformance/es6/destructuring/iterableArrayPattern7.ts(2,5): error TS2322: Type 'Foo' is not assignable to type 'string[]'. +tests/cases/conformance/es6/destructuring/iterableArrayPattern7.ts(17,5): error TS2322: Type 'Foo' is not assignable to type 'string[]'. Property 'length' is missing in type 'Foo'. ==== tests/cases/conformance/es6/destructuring/iterableArrayPattern7.ts (1 errors) ==== - var a: Bar, b: string[]; - [a, b] = new FooIterator; - ~ -!!! error TS2322: Type 'Foo' is not assignable to type 'string[]'. -!!! error TS2322: Property 'length' is missing in type 'Foo'. class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -21,4 +16,10 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern7.ts(2,5): error T [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + var a: Bar, b: string[]; + [a, b] = new FooIterator; + ~ +!!! error TS2322: Type 'Foo' is not assignable to type 'string[]'. +!!! error TS2322: Property 'length' is missing in type 'Foo'. \ No newline at end of file diff --git a/tests/baselines/reference/iterableArrayPattern7.js b/tests/baselines/reference/iterableArrayPattern7.js index 3f79e6bfba..74b25f1ec6 100644 --- a/tests/baselines/reference/iterableArrayPattern7.js +++ b/tests/baselines/reference/iterableArrayPattern7.js @@ -1,6 +1,4 @@ //// [iterableArrayPattern7.ts] -var a: Bar, b: string[]; -[a, b] = new FooIterator; class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,11 +12,12 @@ class FooIterator { [Symbol.iterator]() { return this; } -} +} + +var a: Bar, b: string[]; +[a, b] = new FooIterator; //// [iterableArrayPattern7.js] -var a, b; -[a, b] = new FooIterator; class Bar { } class Foo extends Bar { @@ -34,3 +33,5 @@ class FooIterator { return this; } } +var a, b; +[a, b] = new FooIterator; diff --git a/tests/baselines/reference/iterableArrayPattern8.errors.txt b/tests/baselines/reference/iterableArrayPattern8.errors.txt index c06e0c9543..94c6e9593e 100644 --- a/tests/baselines/reference/iterableArrayPattern8.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern8.errors.txt @@ -1,11 +1,7 @@ -tests/cases/conformance/es6/destructuring/iterableArrayPattern8.ts(2,8): error TS2322: Type 'Foo[]' is not assignable to type 'string'. +tests/cases/conformance/es6/destructuring/iterableArrayPattern8.ts(17,8): error TS2322: Type 'Foo[]' is not assignable to type 'string'. ==== tests/cases/conformance/es6/destructuring/iterableArrayPattern8.ts (1 errors) ==== - var a: Bar, b: string; - [a, ...b] = new FooIterator; - ~ -!!! error TS2322: Type 'Foo[]' is not assignable to type 'string'. class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -19,4 +15,9 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern8.ts(2,8): error T [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + var a: Bar, b: string; + [a, ...b] = new FooIterator; + ~ +!!! error TS2322: Type 'Foo[]' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/iterableArrayPattern8.js b/tests/baselines/reference/iterableArrayPattern8.js index dd1c76c1f5..b943953b15 100644 --- a/tests/baselines/reference/iterableArrayPattern8.js +++ b/tests/baselines/reference/iterableArrayPattern8.js @@ -1,6 +1,4 @@ //// [iterableArrayPattern8.ts] -var a: Bar, b: string; -[a, ...b] = new FooIterator; class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,11 +12,12 @@ class FooIterator { [Symbol.iterator]() { return this; } -} +} + +var a: Bar, b: string; +[a, ...b] = new FooIterator; //// [iterableArrayPattern8.js] -var a, b; -[a, ...b] = new FooIterator; class Bar { } class Foo extends Bar { @@ -34,3 +33,5 @@ class FooIterator { return this; } } +var a, b; +[a, ...b] = new FooIterator; diff --git a/tests/baselines/reference/iteratorSpreadInArray.js b/tests/baselines/reference/iteratorSpreadInArray.js index 8e25a2e7ec..0b64eb4b40 100644 --- a/tests/baselines/reference/iteratorSpreadInArray.js +++ b/tests/baselines/reference/iteratorSpreadInArray.js @@ -1,6 +1,4 @@ //// [iteratorSpreadInArray.ts] -var array = [...new SymbolIterator]; - class SymbolIterator { next() { return { @@ -12,10 +10,12 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} +} + +var array = [...new SymbolIterator]; + //// [iteratorSpreadInArray.js] -var array = [...new SymbolIterator]; class SymbolIterator { next() { return { @@ -27,3 +27,4 @@ class SymbolIterator { return this; } } +var array = [...new SymbolIterator]; diff --git a/tests/baselines/reference/iteratorSpreadInArray.symbols b/tests/baselines/reference/iteratorSpreadInArray.symbols index 7fc2d469ea..6d6656f0f7 100644 --- a/tests/baselines/reference/iteratorSpreadInArray.symbols +++ b/tests/baselines/reference/iteratorSpreadInArray.symbols @@ -1,21 +1,17 @@ === tests/cases/conformance/es6/spread/iteratorSpreadInArray.ts === -var array = [...new SymbolIterator]; ->array : Symbol(array, Decl(iteratorSpreadInArray.ts, 0, 3)) ->SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInArray.ts, 0, 36)) - class SymbolIterator { ->SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInArray.ts, 0, 36)) +>SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInArray.ts, 0, 0)) next() { ->next : Symbol(SymbolIterator.next, Decl(iteratorSpreadInArray.ts, 2, 22)) +>next : Symbol(SymbolIterator.next, Decl(iteratorSpreadInArray.ts, 0, 22)) return { value: Symbol(), ->value : Symbol(value, Decl(iteratorSpreadInArray.ts, 4, 16)) +>value : Symbol(value, Decl(iteratorSpreadInArray.ts, 2, 16)) >Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) done: false ->done : Symbol(done, Decl(iteratorSpreadInArray.ts, 5, 28)) +>done : Symbol(done, Decl(iteratorSpreadInArray.ts, 3, 28)) }; } @@ -26,6 +22,11 @@ class SymbolIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(SymbolIterator, Decl(iteratorSpreadInArray.ts, 0, 36)) +>this : Symbol(SymbolIterator, Decl(iteratorSpreadInArray.ts, 0, 0)) } } + +var array = [...new SymbolIterator]; +>array : Symbol(array, Decl(iteratorSpreadInArray.ts, 13, 3)) +>SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInArray.ts, 0, 0)) + diff --git a/tests/baselines/reference/iteratorSpreadInArray.types b/tests/baselines/reference/iteratorSpreadInArray.types index 4b5a63e5d5..9d43fa57b0 100644 --- a/tests/baselines/reference/iteratorSpreadInArray.types +++ b/tests/baselines/reference/iteratorSpreadInArray.types @@ -1,11 +1,4 @@ === tests/cases/conformance/es6/spread/iteratorSpreadInArray.ts === -var array = [...new SymbolIterator]; ->array : symbol[] ->[...new SymbolIterator] : symbol[] ->...new SymbolIterator : symbol ->new SymbolIterator : SymbolIterator ->SymbolIterator : typeof SymbolIterator - class SymbolIterator { >SymbolIterator : SymbolIterator @@ -36,3 +29,11 @@ class SymbolIterator { >this : this } } + +var array = [...new SymbolIterator]; +>array : symbol[] +>[...new SymbolIterator] : symbol[] +>...new SymbolIterator : symbol +>new SymbolIterator : SymbolIterator +>SymbolIterator : typeof SymbolIterator + diff --git a/tests/baselines/reference/iteratorSpreadInArray10.errors.txt b/tests/baselines/reference/iteratorSpreadInArray10.errors.txt index 90cde7d03b..28a878ac43 100644 --- a/tests/baselines/reference/iteratorSpreadInArray10.errors.txt +++ b/tests/baselines/reference/iteratorSpreadInArray10.errors.txt @@ -1,13 +1,13 @@ -tests/cases/conformance/es6/spread/iteratorSpreadInArray10.ts(1,17): error TS2489: An iterator must have a 'next()' method. +tests/cases/conformance/es6/spread/iteratorSpreadInArray10.ts(7,17): error TS2489: An iterator must have a 'next()' method. ==== tests/cases/conformance/es6/spread/iteratorSpreadInArray10.ts (1 errors) ==== - var array = [...new SymbolIterator]; - ~~~~~~~~~~~~~~~~~~ -!!! error TS2489: An iterator must have a 'next()' method. - class SymbolIterator { [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + var array = [...new SymbolIterator]; + ~~~~~~~~~~~~~~~~~~ +!!! error TS2489: An iterator must have a 'next()' method. \ No newline at end of file diff --git a/tests/baselines/reference/iteratorSpreadInArray10.js b/tests/baselines/reference/iteratorSpreadInArray10.js index 1004dbd7b3..196ca7c714 100644 --- a/tests/baselines/reference/iteratorSpreadInArray10.js +++ b/tests/baselines/reference/iteratorSpreadInArray10.js @@ -1,16 +1,16 @@ //// [iteratorSpreadInArray10.ts] -var array = [...new SymbolIterator]; - class SymbolIterator { [Symbol.iterator]() { return this; } -} +} + +var array = [...new SymbolIterator]; //// [iteratorSpreadInArray10.js] -var array = [...new SymbolIterator]; class SymbolIterator { [Symbol.iterator]() { return this; } } +var array = [...new SymbolIterator]; diff --git a/tests/baselines/reference/iteratorSpreadInArray2.js b/tests/baselines/reference/iteratorSpreadInArray2.js index aa4a1099a4..e766016389 100644 --- a/tests/baselines/reference/iteratorSpreadInArray2.js +++ b/tests/baselines/reference/iteratorSpreadInArray2.js @@ -1,6 +1,4 @@ //// [iteratorSpreadInArray2.ts] -var array = [...new NumberIterator, ...new SymbolIterator]; - class SymbolIterator { next() { return { @@ -25,10 +23,12 @@ class NumberIterator { [Symbol.iterator]() { return this; } -} +} + +var array = [...new NumberIterator, ...new SymbolIterator]; + //// [iteratorSpreadInArray2.js] -var array = [...new NumberIterator, ...new SymbolIterator]; class SymbolIterator { next() { return { @@ -51,3 +51,4 @@ class NumberIterator { return this; } } +var array = [...new NumberIterator, ...new SymbolIterator]; diff --git a/tests/baselines/reference/iteratorSpreadInArray2.symbols b/tests/baselines/reference/iteratorSpreadInArray2.symbols index 8d39834c17..6fd22547ee 100644 --- a/tests/baselines/reference/iteratorSpreadInArray2.symbols +++ b/tests/baselines/reference/iteratorSpreadInArray2.symbols @@ -1,22 +1,17 @@ === tests/cases/conformance/es6/spread/iteratorSpreadInArray2.ts === -var array = [...new NumberIterator, ...new SymbolIterator]; ->array : Symbol(array, Decl(iteratorSpreadInArray2.ts, 0, 3)) ->NumberIterator : Symbol(NumberIterator, Decl(iteratorSpreadInArray2.ts, 13, 1)) ->SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInArray2.ts, 0, 59)) - class SymbolIterator { ->SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInArray2.ts, 0, 59)) +>SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInArray2.ts, 0, 0)) next() { ->next : Symbol(SymbolIterator.next, Decl(iteratorSpreadInArray2.ts, 2, 22)) +>next : Symbol(SymbolIterator.next, Decl(iteratorSpreadInArray2.ts, 0, 22)) return { value: Symbol(), ->value : Symbol(value, Decl(iteratorSpreadInArray2.ts, 4, 16)) +>value : Symbol(value, Decl(iteratorSpreadInArray2.ts, 2, 16)) >Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) done: false ->done : Symbol(done, Decl(iteratorSpreadInArray2.ts, 5, 28)) +>done : Symbol(done, Decl(iteratorSpreadInArray2.ts, 3, 28)) }; } @@ -27,22 +22,22 @@ class SymbolIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(SymbolIterator, Decl(iteratorSpreadInArray2.ts, 0, 59)) +>this : Symbol(SymbolIterator, Decl(iteratorSpreadInArray2.ts, 0, 0)) } } class NumberIterator { ->NumberIterator : Symbol(NumberIterator, Decl(iteratorSpreadInArray2.ts, 13, 1)) +>NumberIterator : Symbol(NumberIterator, Decl(iteratorSpreadInArray2.ts, 11, 1)) next() { ->next : Symbol(NumberIterator.next, Decl(iteratorSpreadInArray2.ts, 15, 22)) +>next : Symbol(NumberIterator.next, Decl(iteratorSpreadInArray2.ts, 13, 22)) return { value: 0, ->value : Symbol(value, Decl(iteratorSpreadInArray2.ts, 17, 16)) +>value : Symbol(value, Decl(iteratorSpreadInArray2.ts, 15, 16)) done: false ->done : Symbol(done, Decl(iteratorSpreadInArray2.ts, 18, 21)) +>done : Symbol(done, Decl(iteratorSpreadInArray2.ts, 16, 21)) }; } @@ -53,6 +48,12 @@ class NumberIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(NumberIterator, Decl(iteratorSpreadInArray2.ts, 13, 1)) +>this : Symbol(NumberIterator, Decl(iteratorSpreadInArray2.ts, 11, 1)) } } + +var array = [...new NumberIterator, ...new SymbolIterator]; +>array : Symbol(array, Decl(iteratorSpreadInArray2.ts, 26, 3)) +>NumberIterator : Symbol(NumberIterator, Decl(iteratorSpreadInArray2.ts, 11, 1)) +>SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInArray2.ts, 0, 0)) + diff --git a/tests/baselines/reference/iteratorSpreadInArray2.types b/tests/baselines/reference/iteratorSpreadInArray2.types index 19bf5eab00..440a2bebcf 100644 --- a/tests/baselines/reference/iteratorSpreadInArray2.types +++ b/tests/baselines/reference/iteratorSpreadInArray2.types @@ -1,14 +1,4 @@ === tests/cases/conformance/es6/spread/iteratorSpreadInArray2.ts === -var array = [...new NumberIterator, ...new SymbolIterator]; ->array : (number | symbol)[] ->[...new NumberIterator, ...new SymbolIterator] : (number | symbol)[] ->...new NumberIterator : number ->new NumberIterator : NumberIterator ->NumberIterator : typeof NumberIterator ->...new SymbolIterator : symbol ->new SymbolIterator : SymbolIterator ->SymbolIterator : typeof SymbolIterator - class SymbolIterator { >SymbolIterator : SymbolIterator @@ -69,3 +59,14 @@ class NumberIterator { >this : this } } + +var array = [...new NumberIterator, ...new SymbolIterator]; +>array : (number | symbol)[] +>[...new NumberIterator, ...new SymbolIterator] : (number | symbol)[] +>...new NumberIterator : number +>new NumberIterator : NumberIterator +>NumberIterator : typeof NumberIterator +>...new SymbolIterator : symbol +>new SymbolIterator : SymbolIterator +>SymbolIterator : typeof SymbolIterator + diff --git a/tests/baselines/reference/iteratorSpreadInArray3.js b/tests/baselines/reference/iteratorSpreadInArray3.js index 1d468e4483..239a95020f 100644 --- a/tests/baselines/reference/iteratorSpreadInArray3.js +++ b/tests/baselines/reference/iteratorSpreadInArray3.js @@ -1,6 +1,4 @@ //// [iteratorSpreadInArray3.ts] -var array = [...[0, 1], ...new SymbolIterator]; - class SymbolIterator { next() { return { @@ -12,10 +10,11 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} +} + +var array = [...[0, 1], ...new SymbolIterator]; //// [iteratorSpreadInArray3.js] -var array = [...[0, 1], ...new SymbolIterator]; class SymbolIterator { next() { return { @@ -27,3 +26,4 @@ class SymbolIterator { return this; } } +var array = [...[0, 1], ...new SymbolIterator]; diff --git a/tests/baselines/reference/iteratorSpreadInArray3.symbols b/tests/baselines/reference/iteratorSpreadInArray3.symbols index c110733dd6..ff6bc66e9d 100644 --- a/tests/baselines/reference/iteratorSpreadInArray3.symbols +++ b/tests/baselines/reference/iteratorSpreadInArray3.symbols @@ -1,21 +1,17 @@ === tests/cases/conformance/es6/spread/iteratorSpreadInArray3.ts === -var array = [...[0, 1], ...new SymbolIterator]; ->array : Symbol(array, Decl(iteratorSpreadInArray3.ts, 0, 3)) ->SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInArray3.ts, 0, 47)) - class SymbolIterator { ->SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInArray3.ts, 0, 47)) +>SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInArray3.ts, 0, 0)) next() { ->next : Symbol(SymbolIterator.next, Decl(iteratorSpreadInArray3.ts, 2, 22)) +>next : Symbol(SymbolIterator.next, Decl(iteratorSpreadInArray3.ts, 0, 22)) return { value: Symbol(), ->value : Symbol(value, Decl(iteratorSpreadInArray3.ts, 4, 16)) +>value : Symbol(value, Decl(iteratorSpreadInArray3.ts, 2, 16)) >Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) done: false ->done : Symbol(done, Decl(iteratorSpreadInArray3.ts, 5, 28)) +>done : Symbol(done, Decl(iteratorSpreadInArray3.ts, 3, 28)) }; } @@ -26,6 +22,11 @@ class SymbolIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(SymbolIterator, Decl(iteratorSpreadInArray3.ts, 0, 47)) +>this : Symbol(SymbolIterator, Decl(iteratorSpreadInArray3.ts, 0, 0)) } } + +var array = [...[0, 1], ...new SymbolIterator]; +>array : Symbol(array, Decl(iteratorSpreadInArray3.ts, 13, 3)) +>SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInArray3.ts, 0, 0)) + diff --git a/tests/baselines/reference/iteratorSpreadInArray3.types b/tests/baselines/reference/iteratorSpreadInArray3.types index 1fd29bb238..b4c8f36f6d 100644 --- a/tests/baselines/reference/iteratorSpreadInArray3.types +++ b/tests/baselines/reference/iteratorSpreadInArray3.types @@ -1,15 +1,4 @@ === tests/cases/conformance/es6/spread/iteratorSpreadInArray3.ts === -var array = [...[0, 1], ...new SymbolIterator]; ->array : (number | symbol)[] ->[...[0, 1], ...new SymbolIterator] : (number | symbol)[] ->...[0, 1] : number ->[0, 1] : number[] ->0 : 0 ->1 : 1 ->...new SymbolIterator : symbol ->new SymbolIterator : SymbolIterator ->SymbolIterator : typeof SymbolIterator - class SymbolIterator { >SymbolIterator : SymbolIterator @@ -40,3 +29,15 @@ class SymbolIterator { >this : this } } + +var array = [...[0, 1], ...new SymbolIterator]; +>array : (number | symbol)[] +>[...[0, 1], ...new SymbolIterator] : (number | symbol)[] +>...[0, 1] : number +>[0, 1] : number[] +>0 : 0 +>1 : 1 +>...new SymbolIterator : symbol +>new SymbolIterator : SymbolIterator +>SymbolIterator : typeof SymbolIterator + diff --git a/tests/baselines/reference/iteratorSpreadInArray4.js b/tests/baselines/reference/iteratorSpreadInArray4.js index 82a08bfa96..95443f760c 100644 --- a/tests/baselines/reference/iteratorSpreadInArray4.js +++ b/tests/baselines/reference/iteratorSpreadInArray4.js @@ -1,6 +1,4 @@ //// [iteratorSpreadInArray4.ts] -var array = [0, 1, ...new SymbolIterator]; - class SymbolIterator { next() { return { @@ -12,10 +10,11 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} +} + +var array = [0, 1, ...new SymbolIterator]; //// [iteratorSpreadInArray4.js] -var array = [0, 1, ...new SymbolIterator]; class SymbolIterator { next() { return { @@ -27,3 +26,4 @@ class SymbolIterator { return this; } } +var array = [0, 1, ...new SymbolIterator]; diff --git a/tests/baselines/reference/iteratorSpreadInArray4.symbols b/tests/baselines/reference/iteratorSpreadInArray4.symbols index e1159ee0e9..16fa1c62c6 100644 --- a/tests/baselines/reference/iteratorSpreadInArray4.symbols +++ b/tests/baselines/reference/iteratorSpreadInArray4.symbols @@ -1,21 +1,17 @@ === tests/cases/conformance/es6/spread/iteratorSpreadInArray4.ts === -var array = [0, 1, ...new SymbolIterator]; ->array : Symbol(array, Decl(iteratorSpreadInArray4.ts, 0, 3)) ->SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInArray4.ts, 0, 42)) - class SymbolIterator { ->SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInArray4.ts, 0, 42)) +>SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInArray4.ts, 0, 0)) next() { ->next : Symbol(SymbolIterator.next, Decl(iteratorSpreadInArray4.ts, 2, 22)) +>next : Symbol(SymbolIterator.next, Decl(iteratorSpreadInArray4.ts, 0, 22)) return { value: Symbol(), ->value : Symbol(value, Decl(iteratorSpreadInArray4.ts, 4, 16)) +>value : Symbol(value, Decl(iteratorSpreadInArray4.ts, 2, 16)) >Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) done: false ->done : Symbol(done, Decl(iteratorSpreadInArray4.ts, 5, 28)) +>done : Symbol(done, Decl(iteratorSpreadInArray4.ts, 3, 28)) }; } @@ -26,6 +22,11 @@ class SymbolIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(SymbolIterator, Decl(iteratorSpreadInArray4.ts, 0, 42)) +>this : Symbol(SymbolIterator, Decl(iteratorSpreadInArray4.ts, 0, 0)) } } + +var array = [0, 1, ...new SymbolIterator]; +>array : Symbol(array, Decl(iteratorSpreadInArray4.ts, 13, 3)) +>SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInArray4.ts, 0, 0)) + diff --git a/tests/baselines/reference/iteratorSpreadInArray4.types b/tests/baselines/reference/iteratorSpreadInArray4.types index 6024e79dee..d473416113 100644 --- a/tests/baselines/reference/iteratorSpreadInArray4.types +++ b/tests/baselines/reference/iteratorSpreadInArray4.types @@ -1,13 +1,4 @@ === tests/cases/conformance/es6/spread/iteratorSpreadInArray4.ts === -var array = [0, 1, ...new SymbolIterator]; ->array : (number | symbol)[] ->[0, 1, ...new SymbolIterator] : (number | symbol)[] ->0 : 0 ->1 : 1 ->...new SymbolIterator : symbol ->new SymbolIterator : SymbolIterator ->SymbolIterator : typeof SymbolIterator - class SymbolIterator { >SymbolIterator : SymbolIterator @@ -38,3 +29,13 @@ class SymbolIterator { >this : this } } + +var array = [0, 1, ...new SymbolIterator]; +>array : (number | symbol)[] +>[0, 1, ...new SymbolIterator] : (number | symbol)[] +>0 : 0 +>1 : 1 +>...new SymbolIterator : symbol +>new SymbolIterator : SymbolIterator +>SymbolIterator : typeof SymbolIterator + diff --git a/tests/baselines/reference/iteratorSpreadInArray5.errors.txt b/tests/baselines/reference/iteratorSpreadInArray5.errors.txt index 498cc7d48e..02049824c4 100644 --- a/tests/baselines/reference/iteratorSpreadInArray5.errors.txt +++ b/tests/baselines/reference/iteratorSpreadInArray5.errors.txt @@ -1,15 +1,9 @@ -tests/cases/conformance/es6/spread/iteratorSpreadInArray5.ts(1,5): error TS2322: Type '(number | symbol)[]' is not assignable to type 'number[]'. +tests/cases/conformance/es6/spread/iteratorSpreadInArray5.ts(14,5): error TS2322: Type '(number | symbol)[]' is not assignable to type 'number[]'. Type 'number | symbol' is not assignable to type 'number'. Type 'symbol' is not assignable to type 'number'. ==== tests/cases/conformance/es6/spread/iteratorSpreadInArray5.ts (1 errors) ==== - var array: number[] = [0, 1, ...new SymbolIterator]; - ~~~~~ -!!! error TS2322: Type '(number | symbol)[]' is not assignable to type 'number[]'. -!!! error TS2322: Type 'number | symbol' is not assignable to type 'number'. -!!! error TS2322: Type 'symbol' is not assignable to type 'number'. - class SymbolIterator { next() { return { @@ -21,4 +15,10 @@ tests/cases/conformance/es6/spread/iteratorSpreadInArray5.ts(1,5): error TS2322: [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + var array: number[] = [0, 1, ...new SymbolIterator]; + ~~~~~ +!!! error TS2322: Type '(number | symbol)[]' is not assignable to type 'number[]'. +!!! error TS2322: Type 'number | symbol' is not assignable to type 'number'. +!!! error TS2322: Type 'symbol' is not assignable to type 'number'. \ No newline at end of file diff --git a/tests/baselines/reference/iteratorSpreadInArray5.js b/tests/baselines/reference/iteratorSpreadInArray5.js index 0aa158a5dc..ee0bf11676 100644 --- a/tests/baselines/reference/iteratorSpreadInArray5.js +++ b/tests/baselines/reference/iteratorSpreadInArray5.js @@ -1,6 +1,4 @@ //// [iteratorSpreadInArray5.ts] -var array: number[] = [0, 1, ...new SymbolIterator]; - class SymbolIterator { next() { return { @@ -12,10 +10,11 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} +} + +var array: number[] = [0, 1, ...new SymbolIterator]; //// [iteratorSpreadInArray5.js] -var array = [0, 1, ...new SymbolIterator]; class SymbolIterator { next() { return { @@ -27,3 +26,4 @@ class SymbolIterator { return this; } } +var array = [0, 1, ...new SymbolIterator]; diff --git a/tests/baselines/reference/iteratorSpreadInArray6.errors.txt b/tests/baselines/reference/iteratorSpreadInArray6.errors.txt index 8148ce43de..e9b6954e6e 100644 --- a/tests/baselines/reference/iteratorSpreadInArray6.errors.txt +++ b/tests/baselines/reference/iteratorSpreadInArray6.errors.txt @@ -1,16 +1,9 @@ -tests/cases/conformance/es6/spread/iteratorSpreadInArray6.ts(2,14): error TS2345: Argument of type 'symbol[]' is not assignable to parameter of type 'number | number[]'. +tests/cases/conformance/es6/spread/iteratorSpreadInArray6.ts(15,14): error TS2345: Argument of type 'symbol[]' is not assignable to parameter of type 'number | number[]'. Type 'symbol[]' is not assignable to type 'number[]'. Type 'symbol' is not assignable to type 'number'. ==== tests/cases/conformance/es6/spread/iteratorSpreadInArray6.ts (1 errors) ==== - var array: number[] = [0, 1]; - array.concat([...new SymbolIterator]); - ~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type 'symbol[]' is not assignable to parameter of type 'number | number[]'. -!!! error TS2345: Type 'symbol[]' is not assignable to type 'number[]'. -!!! error TS2345: Type 'symbol' is not assignable to type 'number'. - class SymbolIterator { next() { return { @@ -22,4 +15,11 @@ tests/cases/conformance/es6/spread/iteratorSpreadInArray6.ts(2,14): error TS2345 [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + var array: number[] = [0, 1]; + array.concat([...new SymbolIterator]); + ~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type 'symbol[]' is not assignable to parameter of type 'number | number[]'. +!!! error TS2345: Type 'symbol[]' is not assignable to type 'number[]'. +!!! error TS2345: Type 'symbol' is not assignable to type 'number'. \ No newline at end of file diff --git a/tests/baselines/reference/iteratorSpreadInArray6.js b/tests/baselines/reference/iteratorSpreadInArray6.js index 02d1c435b8..36b5fcf5cf 100644 --- a/tests/baselines/reference/iteratorSpreadInArray6.js +++ b/tests/baselines/reference/iteratorSpreadInArray6.js @@ -1,7 +1,4 @@ //// [iteratorSpreadInArray6.ts] -var array: number[] = [0, 1]; -array.concat([...new SymbolIterator]); - class SymbolIterator { next() { return { @@ -13,11 +10,12 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} +} + +var array: number[] = [0, 1]; +array.concat([...new SymbolIterator]); //// [iteratorSpreadInArray6.js] -var array = [0, 1]; -array.concat([...new SymbolIterator]); class SymbolIterator { next() { return { @@ -29,3 +27,5 @@ class SymbolIterator { return this; } } +var array = [0, 1]; +array.concat([...new SymbolIterator]); diff --git a/tests/baselines/reference/iteratorSpreadInArray7.js b/tests/baselines/reference/iteratorSpreadInArray7.js index 72a614ae4e..aa209609b2 100644 --- a/tests/baselines/reference/iteratorSpreadInArray7.js +++ b/tests/baselines/reference/iteratorSpreadInArray7.js @@ -1,7 +1,4 @@ //// [iteratorSpreadInArray7.ts] -var array: symbol[]; -array.concat([...new SymbolIterator]); - class SymbolIterator { next() { return { @@ -13,11 +10,12 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} +} + +var array: symbol[]; +array.concat([...new SymbolIterator]); //// [iteratorSpreadInArray7.js] -var array; -array.concat([...new SymbolIterator]); class SymbolIterator { next() { return { @@ -29,3 +27,5 @@ class SymbolIterator { return this; } } +var array; +array.concat([...new SymbolIterator]); diff --git a/tests/baselines/reference/iteratorSpreadInArray7.symbols b/tests/baselines/reference/iteratorSpreadInArray7.symbols index 57774bcd7e..534741a62a 100644 --- a/tests/baselines/reference/iteratorSpreadInArray7.symbols +++ b/tests/baselines/reference/iteratorSpreadInArray7.symbols @@ -1,26 +1,17 @@ === tests/cases/conformance/es6/spread/iteratorSpreadInArray7.ts === -var array: symbol[]; ->array : Symbol(array, Decl(iteratorSpreadInArray7.ts, 0, 3)) - -array.concat([...new SymbolIterator]); ->array.concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->array : Symbol(array, Decl(iteratorSpreadInArray7.ts, 0, 3)) ->concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInArray7.ts, 1, 38)) - class SymbolIterator { ->SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInArray7.ts, 1, 38)) +>SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInArray7.ts, 0, 0)) next() { ->next : Symbol(SymbolIterator.next, Decl(iteratorSpreadInArray7.ts, 3, 22)) +>next : Symbol(SymbolIterator.next, Decl(iteratorSpreadInArray7.ts, 0, 22)) return { value: Symbol(), ->value : Symbol(value, Decl(iteratorSpreadInArray7.ts, 5, 16)) +>value : Symbol(value, Decl(iteratorSpreadInArray7.ts, 2, 16)) >Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) done: false ->done : Symbol(done, Decl(iteratorSpreadInArray7.ts, 6, 28)) +>done : Symbol(done, Decl(iteratorSpreadInArray7.ts, 3, 28)) }; } @@ -31,6 +22,16 @@ class SymbolIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(SymbolIterator, Decl(iteratorSpreadInArray7.ts, 1, 38)) +>this : Symbol(SymbolIterator, Decl(iteratorSpreadInArray7.ts, 0, 0)) } } + +var array: symbol[]; +>array : Symbol(array, Decl(iteratorSpreadInArray7.ts, 13, 3)) + +array.concat([...new SymbolIterator]); +>array.concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>array : Symbol(array, Decl(iteratorSpreadInArray7.ts, 13, 3)) +>concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInArray7.ts, 0, 0)) + diff --git a/tests/baselines/reference/iteratorSpreadInArray7.types b/tests/baselines/reference/iteratorSpreadInArray7.types index ef0e3898e0..b102c72486 100644 --- a/tests/baselines/reference/iteratorSpreadInArray7.types +++ b/tests/baselines/reference/iteratorSpreadInArray7.types @@ -1,17 +1,4 @@ === tests/cases/conformance/es6/spread/iteratorSpreadInArray7.ts === -var array: symbol[]; ->array : symbol[] - -array.concat([...new SymbolIterator]); ->array.concat([...new SymbolIterator]) : symbol[] ->array.concat : { (...items: symbol[][]): symbol[]; (...items: (symbol | symbol[])[]): symbol[]; } ->array : symbol[] ->concat : { (...items: symbol[][]): symbol[]; (...items: (symbol | symbol[])[]): symbol[]; } ->[...new SymbolIterator] : symbol[] ->...new SymbolIterator : symbol ->new SymbolIterator : SymbolIterator ->SymbolIterator : typeof SymbolIterator - class SymbolIterator { >SymbolIterator : SymbolIterator @@ -42,3 +29,17 @@ class SymbolIterator { >this : this } } + +var array: symbol[]; +>array : symbol[] + +array.concat([...new SymbolIterator]); +>array.concat([...new SymbolIterator]) : symbol[] +>array.concat : { (...items: symbol[][]): symbol[]; (...items: (symbol | symbol[])[]): symbol[]; } +>array : symbol[] +>concat : { (...items: symbol[][]): symbol[]; (...items: (symbol | symbol[])[]): symbol[]; } +>[...new SymbolIterator] : symbol[] +>...new SymbolIterator : symbol +>new SymbolIterator : SymbolIterator +>SymbolIterator : typeof SymbolIterator + diff --git a/tests/baselines/reference/iteratorSpreadInArray8.errors.txt b/tests/baselines/reference/iteratorSpreadInArray8.errors.txt index 365bc8db9c..1f8c962942 100644 --- a/tests/baselines/reference/iteratorSpreadInArray8.errors.txt +++ b/tests/baselines/reference/iteratorSpreadInArray8.errors.txt @@ -1,11 +1,7 @@ -tests/cases/conformance/es6/spread/iteratorSpreadInArray8.ts(1,17): error TS2488: Type must have a '[Symbol.iterator]()' method that returns an iterator. +tests/cases/conformance/es6/spread/iteratorSpreadInArray8.ts(10,17): error TS2488: Type must have a '[Symbol.iterator]()' method that returns an iterator. ==== tests/cases/conformance/es6/spread/iteratorSpreadInArray8.ts (1 errors) ==== - var array = [...new SymbolIterator]; - ~~~~~~~~~~~~~~~~~~ -!!! error TS2488: Type must have a '[Symbol.iterator]()' method that returns an iterator. - class SymbolIterator { next() { return { @@ -13,4 +9,8 @@ tests/cases/conformance/es6/spread/iteratorSpreadInArray8.ts(1,17): error TS2488 done: false }; } - } \ No newline at end of file + } + + var array = [...new SymbolIterator]; + ~~~~~~~~~~~~~~~~~~ +!!! error TS2488: Type must have a '[Symbol.iterator]()' method that returns an iterator. \ No newline at end of file diff --git a/tests/baselines/reference/iteratorSpreadInArray8.js b/tests/baselines/reference/iteratorSpreadInArray8.js index 0837869912..c2a0becb0d 100644 --- a/tests/baselines/reference/iteratorSpreadInArray8.js +++ b/tests/baselines/reference/iteratorSpreadInArray8.js @@ -1,6 +1,4 @@ //// [iteratorSpreadInArray8.ts] -var array = [...new SymbolIterator]; - class SymbolIterator { next() { return { @@ -8,10 +6,11 @@ class SymbolIterator { done: false }; } -} +} + +var array = [...new SymbolIterator]; //// [iteratorSpreadInArray8.js] -var array = [...new SymbolIterator]; class SymbolIterator { next() { return { @@ -20,3 +19,4 @@ class SymbolIterator { }; } } +var array = [...new SymbolIterator]; diff --git a/tests/baselines/reference/iteratorSpreadInArray9.errors.txt b/tests/baselines/reference/iteratorSpreadInArray9.errors.txt index 90b8bdbeb4..5f43bb4f5a 100644 --- a/tests/baselines/reference/iteratorSpreadInArray9.errors.txt +++ b/tests/baselines/reference/iteratorSpreadInArray9.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/spread/iteratorSpreadInArray9.ts(1,17): error TS2322: Type 'SymbolIterator' is not assignable to type 'Iterable'. +tests/cases/conformance/es6/spread/iteratorSpreadInArray9.ts(13,17): error TS2322: Type 'SymbolIterator' is not assignable to type 'Iterable'. Types of property '[Symbol.iterator]' are incompatible. Type '() => SymbolIterator' is not assignable to type '() => Iterator'. Type 'SymbolIterator' is not assignable to type 'Iterator'. @@ -9,17 +9,6 @@ tests/cases/conformance/es6/spread/iteratorSpreadInArray9.ts(1,17): error TS2322 ==== tests/cases/conformance/es6/spread/iteratorSpreadInArray9.ts (1 errors) ==== - var array = [...new SymbolIterator]; - ~~~~~~~~~~~~~~~~~~ -!!! error TS2322: Type 'SymbolIterator' is not assignable to type 'Iterable'. -!!! error TS2322: Types of property '[Symbol.iterator]' are incompatible. -!!! error TS2322: Type '() => SymbolIterator' is not assignable to type '() => Iterator'. -!!! error TS2322: Type 'SymbolIterator' is not assignable to type 'Iterator'. -!!! error TS2322: Types of property 'next' are incompatible. -!!! error TS2322: Type '() => { value: symbol; }' is not assignable to type '(value?: any) => IteratorResult'. -!!! error TS2322: Type '{ value: symbol; }' is not assignable to type 'IteratorResult'. -!!! error TS2322: Property 'done' is missing in type '{ value: symbol; }'. - class SymbolIterator { next() { return { @@ -30,4 +19,15 @@ tests/cases/conformance/es6/spread/iteratorSpreadInArray9.ts(1,17): error TS2322 [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + var array = [...new SymbolIterator]; + ~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'SymbolIterator' is not assignable to type 'Iterable'. +!!! error TS2322: Types of property '[Symbol.iterator]' are incompatible. +!!! error TS2322: Type '() => SymbolIterator' is not assignable to type '() => Iterator'. +!!! error TS2322: Type 'SymbolIterator' is not assignable to type 'Iterator'. +!!! error TS2322: Types of property 'next' are incompatible. +!!! error TS2322: Type '() => { value: symbol; }' is not assignable to type '(value?: any) => IteratorResult'. +!!! error TS2322: Type '{ value: symbol; }' is not assignable to type 'IteratorResult'. +!!! error TS2322: Property 'done' is missing in type '{ value: symbol; }'. \ No newline at end of file diff --git a/tests/baselines/reference/iteratorSpreadInArray9.js b/tests/baselines/reference/iteratorSpreadInArray9.js index ed0a9b4ebe..8b3a02e5e1 100644 --- a/tests/baselines/reference/iteratorSpreadInArray9.js +++ b/tests/baselines/reference/iteratorSpreadInArray9.js @@ -1,6 +1,4 @@ //// [iteratorSpreadInArray9.ts] -var array = [...new SymbolIterator]; - class SymbolIterator { next() { return { @@ -11,10 +9,11 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} +} + +var array = [...new SymbolIterator]; //// [iteratorSpreadInArray9.js] -var array = [...new SymbolIterator]; class SymbolIterator { next() { return { @@ -25,3 +24,4 @@ class SymbolIterator { return this; } } +var array = [...new SymbolIterator]; diff --git a/tests/baselines/reference/iteratorSpreadInCall.errors.txt b/tests/baselines/reference/iteratorSpreadInCall.errors.txt index 614153192d..d26f9ab644 100644 --- a/tests/baselines/reference/iteratorSpreadInCall.errors.txt +++ b/tests/baselines/reference/iteratorSpreadInCall.errors.txt @@ -1,11 +1,7 @@ -tests/cases/conformance/es6/spread/iteratorSpreadInCall.ts(1,1): error TS2346: Supplied parameters do not match any signature of call target. +tests/cases/conformance/es6/spread/iteratorSpreadInCall.ts(15,1): error TS2346: Supplied parameters do not match any signature of call target. ==== tests/cases/conformance/es6/spread/iteratorSpreadInCall.ts (1 errors) ==== - foo(...new SymbolIterator); - ~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2346: Supplied parameters do not match any signature of call target. - function foo(s: symbol) { } class SymbolIterator { next() { @@ -18,4 +14,8 @@ tests/cases/conformance/es6/spread/iteratorSpreadInCall.ts(1,1): error TS2346: S [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + foo(...new SymbolIterator); + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. \ No newline at end of file diff --git a/tests/baselines/reference/iteratorSpreadInCall.js b/tests/baselines/reference/iteratorSpreadInCall.js index f3bf17c032..a4b17cfb5e 100644 --- a/tests/baselines/reference/iteratorSpreadInCall.js +++ b/tests/baselines/reference/iteratorSpreadInCall.js @@ -1,6 +1,4 @@ //// [iteratorSpreadInCall.ts] -foo(...new SymbolIterator); - function foo(s: symbol) { } class SymbolIterator { next() { @@ -13,10 +11,11 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} +} + +foo(...new SymbolIterator); //// [iteratorSpreadInCall.js] -foo(...new SymbolIterator); function foo(s) { } class SymbolIterator { next() { @@ -29,3 +28,4 @@ class SymbolIterator { return this; } } +foo(...new SymbolIterator); diff --git a/tests/baselines/reference/iteratorSpreadInCall10.errors.txt b/tests/baselines/reference/iteratorSpreadInCall10.errors.txt index 04d9045e86..bf478012c5 100644 --- a/tests/baselines/reference/iteratorSpreadInCall10.errors.txt +++ b/tests/baselines/reference/iteratorSpreadInCall10.errors.txt @@ -1,13 +1,8 @@ -tests/cases/conformance/es6/spread/iteratorSpreadInCall10.ts(1,1): error TS2346: Supplied parameters do not match any signature of call target. +tests/cases/conformance/es6/spread/iteratorSpreadInCall10.ts(15,1): error TS2346: Supplied parameters do not match any signature of call target. ==== tests/cases/conformance/es6/spread/iteratorSpreadInCall10.ts (1 errors) ==== - foo(...new SymbolIterator); - ~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2346: Supplied parameters do not match any signature of call target. - function foo(s: T[]) { return s[0] } - class SymbolIterator { next() { return { @@ -19,4 +14,8 @@ tests/cases/conformance/es6/spread/iteratorSpreadInCall10.ts(1,1): error TS2346: [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + foo(...new SymbolIterator); + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. \ No newline at end of file diff --git a/tests/baselines/reference/iteratorSpreadInCall10.js b/tests/baselines/reference/iteratorSpreadInCall10.js index 14a08c9700..9fb1cf20a6 100644 --- a/tests/baselines/reference/iteratorSpreadInCall10.js +++ b/tests/baselines/reference/iteratorSpreadInCall10.js @@ -1,8 +1,5 @@ //// [iteratorSpreadInCall10.ts] -foo(...new SymbolIterator); - function foo(s: T[]) { return s[0] } - class SymbolIterator { next() { return { @@ -14,10 +11,11 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} +} + +foo(...new SymbolIterator); //// [iteratorSpreadInCall10.js] -foo(...new SymbolIterator); function foo(s) { return s[0]; } class SymbolIterator { next() { @@ -30,3 +28,4 @@ class SymbolIterator { return this; } } +foo(...new SymbolIterator); diff --git a/tests/baselines/reference/iteratorSpreadInCall11.js b/tests/baselines/reference/iteratorSpreadInCall11.js index d01eb259ef..adfbb03d71 100644 --- a/tests/baselines/reference/iteratorSpreadInCall11.js +++ b/tests/baselines/reference/iteratorSpreadInCall11.js @@ -1,8 +1,5 @@ //// [iteratorSpreadInCall11.ts] -foo(...new SymbolIterator); - function foo(...s: T[]) { return s[0] } - class SymbolIterator { next() { return { @@ -14,10 +11,11 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} +} + +foo(...new SymbolIterator); //// [iteratorSpreadInCall11.js] -foo(...new SymbolIterator); function foo(...s) { return s[0]; } class SymbolIterator { next() { @@ -30,3 +28,4 @@ class SymbolIterator { return this; } } +foo(...new SymbolIterator); diff --git a/tests/baselines/reference/iteratorSpreadInCall11.symbols b/tests/baselines/reference/iteratorSpreadInCall11.symbols index 098a7b9b9c..b6db07942d 100644 --- a/tests/baselines/reference/iteratorSpreadInCall11.symbols +++ b/tests/baselines/reference/iteratorSpreadInCall11.symbols @@ -1,28 +1,24 @@ === tests/cases/conformance/es6/spread/iteratorSpreadInCall11.ts === -foo(...new SymbolIterator); ->foo : Symbol(foo, Decl(iteratorSpreadInCall11.ts, 0, 27)) ->SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInCall11.ts, 2, 42)) - function foo(...s: T[]) { return s[0] } ->foo : Symbol(foo, Decl(iteratorSpreadInCall11.ts, 0, 27)) ->T : Symbol(T, Decl(iteratorSpreadInCall11.ts, 2, 13)) ->s : Symbol(s, Decl(iteratorSpreadInCall11.ts, 2, 16)) ->T : Symbol(T, Decl(iteratorSpreadInCall11.ts, 2, 13)) ->s : Symbol(s, Decl(iteratorSpreadInCall11.ts, 2, 16)) +>foo : Symbol(foo, Decl(iteratorSpreadInCall11.ts, 0, 0)) +>T : Symbol(T, Decl(iteratorSpreadInCall11.ts, 0, 13)) +>s : Symbol(s, Decl(iteratorSpreadInCall11.ts, 0, 16)) +>T : Symbol(T, Decl(iteratorSpreadInCall11.ts, 0, 13)) +>s : Symbol(s, Decl(iteratorSpreadInCall11.ts, 0, 16)) class SymbolIterator { ->SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInCall11.ts, 2, 42)) +>SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInCall11.ts, 0, 42)) next() { ->next : Symbol(SymbolIterator.next, Decl(iteratorSpreadInCall11.ts, 4, 22)) +>next : Symbol(SymbolIterator.next, Decl(iteratorSpreadInCall11.ts, 1, 22)) return { value: Symbol(), ->value : Symbol(value, Decl(iteratorSpreadInCall11.ts, 6, 16)) +>value : Symbol(value, Decl(iteratorSpreadInCall11.ts, 3, 16)) >Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) done: false ->done : Symbol(done, Decl(iteratorSpreadInCall11.ts, 7, 28)) +>done : Symbol(done, Decl(iteratorSpreadInCall11.ts, 4, 28)) }; } @@ -33,6 +29,11 @@ class SymbolIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(SymbolIterator, Decl(iteratorSpreadInCall11.ts, 2, 42)) +>this : Symbol(SymbolIterator, Decl(iteratorSpreadInCall11.ts, 0, 42)) } } + +foo(...new SymbolIterator); +>foo : Symbol(foo, Decl(iteratorSpreadInCall11.ts, 0, 0)) +>SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInCall11.ts, 0, 42)) + diff --git a/tests/baselines/reference/iteratorSpreadInCall11.types b/tests/baselines/reference/iteratorSpreadInCall11.types index 5990b26df6..4a3d73d36d 100644 --- a/tests/baselines/reference/iteratorSpreadInCall11.types +++ b/tests/baselines/reference/iteratorSpreadInCall11.types @@ -1,11 +1,4 @@ === tests/cases/conformance/es6/spread/iteratorSpreadInCall11.ts === -foo(...new SymbolIterator); ->foo(...new SymbolIterator) : symbol ->foo : (...s: T[]) => T ->...new SymbolIterator : symbol ->new SymbolIterator : SymbolIterator ->SymbolIterator : typeof SymbolIterator - function foo(...s: T[]) { return s[0] } >foo : (...s: T[]) => T >T : T @@ -45,3 +38,11 @@ class SymbolIterator { >this : this } } + +foo(...new SymbolIterator); +>foo(...new SymbolIterator) : symbol +>foo : (...s: T[]) => T +>...new SymbolIterator : symbol +>new SymbolIterator : SymbolIterator +>SymbolIterator : typeof SymbolIterator + diff --git a/tests/baselines/reference/iteratorSpreadInCall12.js b/tests/baselines/reference/iteratorSpreadInCall12.js index b138192826..ba8149e29d 100644 --- a/tests/baselines/reference/iteratorSpreadInCall12.js +++ b/tests/baselines/reference/iteratorSpreadInCall12.js @@ -1,6 +1,4 @@ //// [iteratorSpreadInCall12.ts] -new Foo(...[...new SymbolIterator, ...[...new StringIterator]]); - class Foo { constructor(...s: T[]) { } } @@ -29,10 +27,11 @@ class StringIterator { [Symbol.iterator]() { return this; } -} +} + +new Foo(...[...new SymbolIterator, ...[...new StringIterator]]); //// [iteratorSpreadInCall12.js] -new Foo(...[...new SymbolIterator, ...[...new StringIterator]]); class Foo { constructor(...s) { } } @@ -58,3 +57,4 @@ class StringIterator { return this; } } +new Foo(...[...new SymbolIterator, ...[...new StringIterator]]); diff --git a/tests/baselines/reference/iteratorSpreadInCall12.symbols b/tests/baselines/reference/iteratorSpreadInCall12.symbols index f989860f04..983ab8fcd9 100644 --- a/tests/baselines/reference/iteratorSpreadInCall12.symbols +++ b/tests/baselines/reference/iteratorSpreadInCall12.symbols @@ -1,31 +1,26 @@ === tests/cases/conformance/es6/spread/iteratorSpreadInCall12.ts === -new Foo(...[...new SymbolIterator, ...[...new StringIterator]]); ->Foo : Symbol(Foo, Decl(iteratorSpreadInCall12.ts, 0, 64)) ->SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInCall12.ts, 4, 1)) ->StringIterator : Symbol(StringIterator, Decl(iteratorSpreadInCall12.ts, 17, 1)) - class Foo { ->Foo : Symbol(Foo, Decl(iteratorSpreadInCall12.ts, 0, 64)) ->T : Symbol(T, Decl(iteratorSpreadInCall12.ts, 2, 10)) +>Foo : Symbol(Foo, Decl(iteratorSpreadInCall12.ts, 0, 0)) +>T : Symbol(T, Decl(iteratorSpreadInCall12.ts, 0, 10)) constructor(...s: T[]) { } ->s : Symbol(s, Decl(iteratorSpreadInCall12.ts, 3, 16)) ->T : Symbol(T, Decl(iteratorSpreadInCall12.ts, 2, 10)) +>s : Symbol(s, Decl(iteratorSpreadInCall12.ts, 1, 16)) +>T : Symbol(T, Decl(iteratorSpreadInCall12.ts, 0, 10)) } class SymbolIterator { ->SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInCall12.ts, 4, 1)) +>SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInCall12.ts, 2, 1)) next() { ->next : Symbol(SymbolIterator.next, Decl(iteratorSpreadInCall12.ts, 6, 22)) +>next : Symbol(SymbolIterator.next, Decl(iteratorSpreadInCall12.ts, 4, 22)) return { value: Symbol(), ->value : Symbol(value, Decl(iteratorSpreadInCall12.ts, 8, 16)) +>value : Symbol(value, Decl(iteratorSpreadInCall12.ts, 6, 16)) >Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) done: false ->done : Symbol(done, Decl(iteratorSpreadInCall12.ts, 9, 28)) +>done : Symbol(done, Decl(iteratorSpreadInCall12.ts, 7, 28)) }; } @@ -36,22 +31,22 @@ class SymbolIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(SymbolIterator, Decl(iteratorSpreadInCall12.ts, 4, 1)) +>this : Symbol(SymbolIterator, Decl(iteratorSpreadInCall12.ts, 2, 1)) } } class StringIterator { ->StringIterator : Symbol(StringIterator, Decl(iteratorSpreadInCall12.ts, 17, 1)) +>StringIterator : Symbol(StringIterator, Decl(iteratorSpreadInCall12.ts, 15, 1)) next() { ->next : Symbol(StringIterator.next, Decl(iteratorSpreadInCall12.ts, 19, 22)) +>next : Symbol(StringIterator.next, Decl(iteratorSpreadInCall12.ts, 17, 22)) return { value: "", ->value : Symbol(value, Decl(iteratorSpreadInCall12.ts, 21, 16)) +>value : Symbol(value, Decl(iteratorSpreadInCall12.ts, 19, 16)) done: false ->done : Symbol(done, Decl(iteratorSpreadInCall12.ts, 22, 22)) +>done : Symbol(done, Decl(iteratorSpreadInCall12.ts, 20, 22)) }; } @@ -62,6 +57,12 @@ class StringIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(StringIterator, Decl(iteratorSpreadInCall12.ts, 17, 1)) +>this : Symbol(StringIterator, Decl(iteratorSpreadInCall12.ts, 15, 1)) } } + +new Foo(...[...new SymbolIterator, ...[...new StringIterator]]); +>Foo : Symbol(Foo, Decl(iteratorSpreadInCall12.ts, 0, 0)) +>SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInCall12.ts, 2, 1)) +>StringIterator : Symbol(StringIterator, Decl(iteratorSpreadInCall12.ts, 15, 1)) + diff --git a/tests/baselines/reference/iteratorSpreadInCall12.types b/tests/baselines/reference/iteratorSpreadInCall12.types index b614fdde16..55986b5764 100644 --- a/tests/baselines/reference/iteratorSpreadInCall12.types +++ b/tests/baselines/reference/iteratorSpreadInCall12.types @@ -1,18 +1,4 @@ === tests/cases/conformance/es6/spread/iteratorSpreadInCall12.ts === -new Foo(...[...new SymbolIterator, ...[...new StringIterator]]); ->new Foo(...[...new SymbolIterator, ...[...new StringIterator]]) : Foo ->Foo : typeof Foo ->...[...new SymbolIterator, ...[...new StringIterator]] : string | symbol ->[...new SymbolIterator, ...[...new StringIterator]] : (string | symbol)[] ->...new SymbolIterator : symbol ->new SymbolIterator : SymbolIterator ->SymbolIterator : typeof SymbolIterator ->...[...new StringIterator] : string ->[...new StringIterator] : string[] ->...new StringIterator : string ->new StringIterator : StringIterator ->StringIterator : typeof StringIterator - class Foo { >Foo : Foo >T : T @@ -82,3 +68,18 @@ class StringIterator { >this : this } } + +new Foo(...[...new SymbolIterator, ...[...new StringIterator]]); +>new Foo(...[...new SymbolIterator, ...[...new StringIterator]]) : Foo +>Foo : typeof Foo +>...[...new SymbolIterator, ...[...new StringIterator]] : string | symbol +>[...new SymbolIterator, ...[...new StringIterator]] : (string | symbol)[] +>...new SymbolIterator : symbol +>new SymbolIterator : SymbolIterator +>SymbolIterator : typeof SymbolIterator +>...[...new StringIterator] : string +>[...new StringIterator] : string[] +>...new StringIterator : string +>new StringIterator : StringIterator +>StringIterator : typeof StringIterator + diff --git a/tests/baselines/reference/iteratorSpreadInCall2.errors.txt b/tests/baselines/reference/iteratorSpreadInCall2.errors.txt index bd994ab37b..abf8fc71ed 100644 --- a/tests/baselines/reference/iteratorSpreadInCall2.errors.txt +++ b/tests/baselines/reference/iteratorSpreadInCall2.errors.txt @@ -1,11 +1,7 @@ -tests/cases/conformance/es6/spread/iteratorSpreadInCall2.ts(1,1): error TS2346: Supplied parameters do not match any signature of call target. +tests/cases/conformance/es6/spread/iteratorSpreadInCall2.ts(15,1): error TS2346: Supplied parameters do not match any signature of call target. ==== tests/cases/conformance/es6/spread/iteratorSpreadInCall2.ts (1 errors) ==== - foo(...new SymbolIterator); - ~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2346: Supplied parameters do not match any signature of call target. - function foo(s: symbol[]) { } class SymbolIterator { next() { @@ -18,4 +14,8 @@ tests/cases/conformance/es6/spread/iteratorSpreadInCall2.ts(1,1): error TS2346: [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + foo(...new SymbolIterator); + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. \ No newline at end of file diff --git a/tests/baselines/reference/iteratorSpreadInCall2.js b/tests/baselines/reference/iteratorSpreadInCall2.js index 6c3517857d..e858a7cd72 100644 --- a/tests/baselines/reference/iteratorSpreadInCall2.js +++ b/tests/baselines/reference/iteratorSpreadInCall2.js @@ -1,6 +1,4 @@ //// [iteratorSpreadInCall2.ts] -foo(...new SymbolIterator); - function foo(s: symbol[]) { } class SymbolIterator { next() { @@ -13,10 +11,11 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} +} + +foo(...new SymbolIterator); //// [iteratorSpreadInCall2.js] -foo(...new SymbolIterator); function foo(s) { } class SymbolIterator { next() { @@ -29,3 +28,4 @@ class SymbolIterator { return this; } } +foo(...new SymbolIterator); diff --git a/tests/baselines/reference/iteratorSpreadInCall3.js b/tests/baselines/reference/iteratorSpreadInCall3.js index b33ceae7bf..9dd0c23add 100644 --- a/tests/baselines/reference/iteratorSpreadInCall3.js +++ b/tests/baselines/reference/iteratorSpreadInCall3.js @@ -1,6 +1,4 @@ //// [iteratorSpreadInCall3.ts] -foo(...new SymbolIterator); - function foo(...s: symbol[]) { } class SymbolIterator { next() { @@ -13,10 +11,11 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} +} + +foo(...new SymbolIterator); //// [iteratorSpreadInCall3.js] -foo(...new SymbolIterator); function foo(...s) { } class SymbolIterator { next() { @@ -29,3 +28,4 @@ class SymbolIterator { return this; } } +foo(...new SymbolIterator); diff --git a/tests/baselines/reference/iteratorSpreadInCall3.symbols b/tests/baselines/reference/iteratorSpreadInCall3.symbols index 8557b6c831..d8f414bcd7 100644 --- a/tests/baselines/reference/iteratorSpreadInCall3.symbols +++ b/tests/baselines/reference/iteratorSpreadInCall3.symbols @@ -1,25 +1,21 @@ === tests/cases/conformance/es6/spread/iteratorSpreadInCall3.ts === -foo(...new SymbolIterator); ->foo : Symbol(foo, Decl(iteratorSpreadInCall3.ts, 0, 27)) ->SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInCall3.ts, 2, 32)) - function foo(...s: symbol[]) { } ->foo : Symbol(foo, Decl(iteratorSpreadInCall3.ts, 0, 27)) ->s : Symbol(s, Decl(iteratorSpreadInCall3.ts, 2, 13)) +>foo : Symbol(foo, Decl(iteratorSpreadInCall3.ts, 0, 0)) +>s : Symbol(s, Decl(iteratorSpreadInCall3.ts, 0, 13)) class SymbolIterator { ->SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInCall3.ts, 2, 32)) +>SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInCall3.ts, 0, 32)) next() { ->next : Symbol(SymbolIterator.next, Decl(iteratorSpreadInCall3.ts, 3, 22)) +>next : Symbol(SymbolIterator.next, Decl(iteratorSpreadInCall3.ts, 1, 22)) return { value: Symbol(), ->value : Symbol(value, Decl(iteratorSpreadInCall3.ts, 5, 16)) +>value : Symbol(value, Decl(iteratorSpreadInCall3.ts, 3, 16)) >Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) done: false ->done : Symbol(done, Decl(iteratorSpreadInCall3.ts, 6, 28)) +>done : Symbol(done, Decl(iteratorSpreadInCall3.ts, 4, 28)) }; } @@ -30,6 +26,11 @@ class SymbolIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(SymbolIterator, Decl(iteratorSpreadInCall3.ts, 2, 32)) +>this : Symbol(SymbolIterator, Decl(iteratorSpreadInCall3.ts, 0, 32)) } } + +foo(...new SymbolIterator); +>foo : Symbol(foo, Decl(iteratorSpreadInCall3.ts, 0, 0)) +>SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInCall3.ts, 0, 32)) + diff --git a/tests/baselines/reference/iteratorSpreadInCall3.types b/tests/baselines/reference/iteratorSpreadInCall3.types index 56b7f6db6d..fef9f7dcab 100644 --- a/tests/baselines/reference/iteratorSpreadInCall3.types +++ b/tests/baselines/reference/iteratorSpreadInCall3.types @@ -1,11 +1,4 @@ === tests/cases/conformance/es6/spread/iteratorSpreadInCall3.ts === -foo(...new SymbolIterator); ->foo(...new SymbolIterator) : void ->foo : (...s: symbol[]) => void ->...new SymbolIterator : symbol ->new SymbolIterator : SymbolIterator ->SymbolIterator : typeof SymbolIterator - function foo(...s: symbol[]) { } >foo : (...s: symbol[]) => void >s : symbol[] @@ -40,3 +33,11 @@ class SymbolIterator { >this : this } } + +foo(...new SymbolIterator); +>foo(...new SymbolIterator) : void +>foo : (...s: symbol[]) => void +>...new SymbolIterator : symbol +>new SymbolIterator : SymbolIterator +>SymbolIterator : typeof SymbolIterator + diff --git a/tests/baselines/reference/iteratorSpreadInCall4.errors.txt b/tests/baselines/reference/iteratorSpreadInCall4.errors.txt index 0e0a40a512..3beaf2ce65 100644 --- a/tests/baselines/reference/iteratorSpreadInCall4.errors.txt +++ b/tests/baselines/reference/iteratorSpreadInCall4.errors.txt @@ -1,11 +1,7 @@ -tests/cases/conformance/es6/spread/iteratorSpreadInCall4.ts(1,1): error TS2346: Supplied parameters do not match any signature of call target. +tests/cases/conformance/es6/spread/iteratorSpreadInCall4.ts(15,1): error TS2346: Supplied parameters do not match any signature of call target. ==== tests/cases/conformance/es6/spread/iteratorSpreadInCall4.ts (1 errors) ==== - foo(...new SymbolIterator); - ~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2346: Supplied parameters do not match any signature of call target. - function foo(s1: symbol, ...s: symbol[]) { } class SymbolIterator { next() { @@ -18,4 +14,8 @@ tests/cases/conformance/es6/spread/iteratorSpreadInCall4.ts(1,1): error TS2346: [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + foo(...new SymbolIterator); + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. \ No newline at end of file diff --git a/tests/baselines/reference/iteratorSpreadInCall4.js b/tests/baselines/reference/iteratorSpreadInCall4.js index 7819a1ba6f..a0d655c25a 100644 --- a/tests/baselines/reference/iteratorSpreadInCall4.js +++ b/tests/baselines/reference/iteratorSpreadInCall4.js @@ -1,6 +1,4 @@ //// [iteratorSpreadInCall4.ts] -foo(...new SymbolIterator); - function foo(s1: symbol, ...s: symbol[]) { } class SymbolIterator { next() { @@ -13,10 +11,11 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} +} + +foo(...new SymbolIterator); //// [iteratorSpreadInCall4.js] -foo(...new SymbolIterator); function foo(s1, ...s) { } class SymbolIterator { next() { @@ -29,3 +28,4 @@ class SymbolIterator { return this; } } +foo(...new SymbolIterator); diff --git a/tests/baselines/reference/iteratorSpreadInCall5.js b/tests/baselines/reference/iteratorSpreadInCall5.js index a4a30ee016..b17054363e 100644 --- a/tests/baselines/reference/iteratorSpreadInCall5.js +++ b/tests/baselines/reference/iteratorSpreadInCall5.js @@ -1,6 +1,4 @@ //// [iteratorSpreadInCall5.ts] -foo(...new SymbolIterator, ...new StringIterator); - function foo(...s: (symbol | string)[]) { } class SymbolIterator { next() { @@ -26,10 +24,11 @@ class StringIterator { [Symbol.iterator]() { return this; } -} +} + +foo(...new SymbolIterator, ...new StringIterator); //// [iteratorSpreadInCall5.js] -foo(...new SymbolIterator, ...new StringIterator); function foo(...s) { } class SymbolIterator { next() { @@ -53,3 +52,4 @@ class StringIterator { return this; } } +foo(...new SymbolIterator, ...new StringIterator); diff --git a/tests/baselines/reference/iteratorSpreadInCall5.symbols b/tests/baselines/reference/iteratorSpreadInCall5.symbols index 0ed608e058..81143b79f2 100644 --- a/tests/baselines/reference/iteratorSpreadInCall5.symbols +++ b/tests/baselines/reference/iteratorSpreadInCall5.symbols @@ -1,26 +1,21 @@ === tests/cases/conformance/es6/spread/iteratorSpreadInCall5.ts === -foo(...new SymbolIterator, ...new StringIterator); ->foo : Symbol(foo, Decl(iteratorSpreadInCall5.ts, 0, 50)) ->SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInCall5.ts, 2, 43)) ->StringIterator : Symbol(StringIterator, Decl(iteratorSpreadInCall5.ts, 14, 1)) - function foo(...s: (symbol | string)[]) { } ->foo : Symbol(foo, Decl(iteratorSpreadInCall5.ts, 0, 50)) ->s : Symbol(s, Decl(iteratorSpreadInCall5.ts, 2, 13)) +>foo : Symbol(foo, Decl(iteratorSpreadInCall5.ts, 0, 0)) +>s : Symbol(s, Decl(iteratorSpreadInCall5.ts, 0, 13)) class SymbolIterator { ->SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInCall5.ts, 2, 43)) +>SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInCall5.ts, 0, 43)) next() { ->next : Symbol(SymbolIterator.next, Decl(iteratorSpreadInCall5.ts, 3, 22)) +>next : Symbol(SymbolIterator.next, Decl(iteratorSpreadInCall5.ts, 1, 22)) return { value: Symbol(), ->value : Symbol(value, Decl(iteratorSpreadInCall5.ts, 5, 16)) +>value : Symbol(value, Decl(iteratorSpreadInCall5.ts, 3, 16)) >Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) done: false ->done : Symbol(done, Decl(iteratorSpreadInCall5.ts, 6, 28)) +>done : Symbol(done, Decl(iteratorSpreadInCall5.ts, 4, 28)) }; } @@ -31,22 +26,22 @@ class SymbolIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(SymbolIterator, Decl(iteratorSpreadInCall5.ts, 2, 43)) +>this : Symbol(SymbolIterator, Decl(iteratorSpreadInCall5.ts, 0, 43)) } } class StringIterator { ->StringIterator : Symbol(StringIterator, Decl(iteratorSpreadInCall5.ts, 14, 1)) +>StringIterator : Symbol(StringIterator, Decl(iteratorSpreadInCall5.ts, 12, 1)) next() { ->next : Symbol(StringIterator.next, Decl(iteratorSpreadInCall5.ts, 16, 22)) +>next : Symbol(StringIterator.next, Decl(iteratorSpreadInCall5.ts, 14, 22)) return { value: "", ->value : Symbol(value, Decl(iteratorSpreadInCall5.ts, 18, 16)) +>value : Symbol(value, Decl(iteratorSpreadInCall5.ts, 16, 16)) done: false ->done : Symbol(done, Decl(iteratorSpreadInCall5.ts, 19, 22)) +>done : Symbol(done, Decl(iteratorSpreadInCall5.ts, 17, 22)) }; } @@ -57,6 +52,12 @@ class StringIterator { >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) return this; ->this : Symbol(StringIterator, Decl(iteratorSpreadInCall5.ts, 14, 1)) +>this : Symbol(StringIterator, Decl(iteratorSpreadInCall5.ts, 12, 1)) } } + +foo(...new SymbolIterator, ...new StringIterator); +>foo : Symbol(foo, Decl(iteratorSpreadInCall5.ts, 0, 0)) +>SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInCall5.ts, 0, 43)) +>StringIterator : Symbol(StringIterator, Decl(iteratorSpreadInCall5.ts, 12, 1)) + diff --git a/tests/baselines/reference/iteratorSpreadInCall5.types b/tests/baselines/reference/iteratorSpreadInCall5.types index 9542a76daf..a4f16829d5 100644 --- a/tests/baselines/reference/iteratorSpreadInCall5.types +++ b/tests/baselines/reference/iteratorSpreadInCall5.types @@ -1,14 +1,4 @@ === tests/cases/conformance/es6/spread/iteratorSpreadInCall5.ts === -foo(...new SymbolIterator, ...new StringIterator); ->foo(...new SymbolIterator, ...new StringIterator) : void ->foo : (...s: (string | symbol)[]) => void ->...new SymbolIterator : symbol ->new SymbolIterator : SymbolIterator ->SymbolIterator : typeof SymbolIterator ->...new StringIterator : string ->new StringIterator : StringIterator ->StringIterator : typeof StringIterator - function foo(...s: (symbol | string)[]) { } >foo : (...s: (string | symbol)[]) => void >s : (string | symbol)[] @@ -73,3 +63,14 @@ class StringIterator { >this : this } } + +foo(...new SymbolIterator, ...new StringIterator); +>foo(...new SymbolIterator, ...new StringIterator) : void +>foo : (...s: (string | symbol)[]) => void +>...new SymbolIterator : symbol +>new SymbolIterator : SymbolIterator +>SymbolIterator : typeof SymbolIterator +>...new StringIterator : string +>new StringIterator : StringIterator +>StringIterator : typeof StringIterator + diff --git a/tests/baselines/reference/iteratorSpreadInCall6.errors.txt b/tests/baselines/reference/iteratorSpreadInCall6.errors.txt index 93aaec8c33..2c89c7bb49 100644 --- a/tests/baselines/reference/iteratorSpreadInCall6.errors.txt +++ b/tests/baselines/reference/iteratorSpreadInCall6.errors.txt @@ -1,11 +1,7 @@ -tests/cases/conformance/es6/spread/iteratorSpreadInCall6.ts(1,28): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number | symbol'. +tests/cases/conformance/es6/spread/iteratorSpreadInCall6.ts(28,28): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number | symbol'. ==== tests/cases/conformance/es6/spread/iteratorSpreadInCall6.ts (1 errors) ==== - foo(...new SymbolIterator, ...new StringIterator); - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number | symbol'. - function foo(...s: (symbol | number)[]) { } class SymbolIterator { next() { @@ -31,4 +27,8 @@ tests/cases/conformance/es6/spread/iteratorSpreadInCall6.ts(1,28): error TS2345: [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + foo(...new SymbolIterator, ...new StringIterator); + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number | symbol'. \ No newline at end of file diff --git a/tests/baselines/reference/iteratorSpreadInCall6.js b/tests/baselines/reference/iteratorSpreadInCall6.js index 8ad60be911..161f420ce0 100644 --- a/tests/baselines/reference/iteratorSpreadInCall6.js +++ b/tests/baselines/reference/iteratorSpreadInCall6.js @@ -1,6 +1,4 @@ //// [iteratorSpreadInCall6.ts] -foo(...new SymbolIterator, ...new StringIterator); - function foo(...s: (symbol | number)[]) { } class SymbolIterator { next() { @@ -26,10 +24,11 @@ class StringIterator { [Symbol.iterator]() { return this; } -} +} + +foo(...new SymbolIterator, ...new StringIterator); //// [iteratorSpreadInCall6.js] -foo(...new SymbolIterator, ...new StringIterator); function foo(...s) { } class SymbolIterator { next() { @@ -53,3 +52,4 @@ class StringIterator { return this; } } +foo(...new SymbolIterator, ...new StringIterator); diff --git a/tests/baselines/reference/iteratorSpreadInCall7.errors.txt b/tests/baselines/reference/iteratorSpreadInCall7.errors.txt index 51cae1d72b..30096c90db 100644 --- a/tests/baselines/reference/iteratorSpreadInCall7.errors.txt +++ b/tests/baselines/reference/iteratorSpreadInCall7.errors.txt @@ -1,13 +1,8 @@ -tests/cases/conformance/es6/spread/iteratorSpreadInCall7.ts(1,1): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. +tests/cases/conformance/es6/spread/iteratorSpreadInCall7.ts(28,1): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. Type argument candidate 'symbol' is not a valid type argument because it is not a supertype of candidate 'string'. ==== tests/cases/conformance/es6/spread/iteratorSpreadInCall7.ts (1 errors) ==== - foo(...new SymbolIterator, ...new StringIterator); - ~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'symbol' is not a valid type argument because it is not a supertype of candidate 'string'. - function foo(...s: T[]) { return s[0]; } class SymbolIterator { next() { @@ -33,4 +28,9 @@ tests/cases/conformance/es6/spread/iteratorSpreadInCall7.ts(1,1): error TS2453: [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + foo(...new SymbolIterator, ...new StringIterator); + ~~~ +!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. +!!! error TS2453: Type argument candidate 'symbol' is not a valid type argument because it is not a supertype of candidate 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/iteratorSpreadInCall7.js b/tests/baselines/reference/iteratorSpreadInCall7.js index 4a56b75d23..e7c354413d 100644 --- a/tests/baselines/reference/iteratorSpreadInCall7.js +++ b/tests/baselines/reference/iteratorSpreadInCall7.js @@ -1,6 +1,4 @@ //// [iteratorSpreadInCall7.ts] -foo(...new SymbolIterator, ...new StringIterator); - function foo(...s: T[]) { return s[0]; } class SymbolIterator { next() { @@ -26,10 +24,11 @@ class StringIterator { [Symbol.iterator]() { return this; } -} +} + +foo(...new SymbolIterator, ...new StringIterator); //// [iteratorSpreadInCall7.js] -foo(...new SymbolIterator, ...new StringIterator); function foo(...s) { return s[0]; } class SymbolIterator { next() { @@ -53,3 +52,4 @@ class StringIterator { return this; } } +foo(...new SymbolIterator, ...new StringIterator); diff --git a/tests/baselines/reference/iteratorSpreadInCall8.errors.txt b/tests/baselines/reference/iteratorSpreadInCall8.errors.txt index d7913458b6..5fd0b43ce5 100644 --- a/tests/baselines/reference/iteratorSpreadInCall8.errors.txt +++ b/tests/baselines/reference/iteratorSpreadInCall8.errors.txt @@ -1,13 +1,8 @@ -tests/cases/conformance/es6/spread/iteratorSpreadInCall8.ts(1,5): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. +tests/cases/conformance/es6/spread/iteratorSpreadInCall8.ts(31,5): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. Type argument candidate 'symbol' is not a valid type argument because it is not a supertype of candidate 'string'. ==== tests/cases/conformance/es6/spread/iteratorSpreadInCall8.ts (1 errors) ==== - new Foo(...new SymbolIterator, ...new StringIterator); - ~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'symbol' is not a valid type argument because it is not a supertype of candidate 'string'. - class Foo { constructor(...s: T[]) { } } @@ -36,4 +31,9 @@ tests/cases/conformance/es6/spread/iteratorSpreadInCall8.ts(1,5): error TS2453: [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + new Foo(...new SymbolIterator, ...new StringIterator); + ~~~ +!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. +!!! error TS2453: Type argument candidate 'symbol' is not a valid type argument because it is not a supertype of candidate 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/iteratorSpreadInCall8.js b/tests/baselines/reference/iteratorSpreadInCall8.js index 3871ff83bc..a591fd363a 100644 --- a/tests/baselines/reference/iteratorSpreadInCall8.js +++ b/tests/baselines/reference/iteratorSpreadInCall8.js @@ -1,6 +1,4 @@ //// [iteratorSpreadInCall8.ts] -new Foo(...new SymbolIterator, ...new StringIterator); - class Foo { constructor(...s: T[]) { } } @@ -29,10 +27,11 @@ class StringIterator { [Symbol.iterator]() { return this; } -} +} + +new Foo(...new SymbolIterator, ...new StringIterator); //// [iteratorSpreadInCall8.js] -new Foo(...new SymbolIterator, ...new StringIterator); class Foo { constructor(...s) { } } @@ -58,3 +57,4 @@ class StringIterator { return this; } } +new Foo(...new SymbolIterator, ...new StringIterator); diff --git a/tests/baselines/reference/iteratorSpreadInCall9.errors.txt b/tests/baselines/reference/iteratorSpreadInCall9.errors.txt index da2ee7f8ef..59854bd36a 100644 --- a/tests/baselines/reference/iteratorSpreadInCall9.errors.txt +++ b/tests/baselines/reference/iteratorSpreadInCall9.errors.txt @@ -1,13 +1,8 @@ -tests/cases/conformance/es6/spread/iteratorSpreadInCall9.ts(1,5): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. +tests/cases/conformance/es6/spread/iteratorSpreadInCall9.ts(31,5): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. Type argument candidate 'symbol' is not a valid type argument because it is not a supertype of candidate 'string'. ==== tests/cases/conformance/es6/spread/iteratorSpreadInCall9.ts (1 errors) ==== - new Foo(...new SymbolIterator, ...[...new StringIterator]); - ~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'symbol' is not a valid type argument because it is not a supertype of candidate 'string'. - class Foo { constructor(...s: T[]) { } } @@ -36,4 +31,10 @@ tests/cases/conformance/es6/spread/iteratorSpreadInCall9.ts(1,5): error TS2453: [Symbol.iterator]() { return this; } - } \ No newline at end of file + } + + new Foo(...new SymbolIterator, ...[...new StringIterator]); + ~~~ +!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. +!!! error TS2453: Type argument candidate 'symbol' is not a valid type argument because it is not a supertype of candidate 'string'. + \ No newline at end of file diff --git a/tests/baselines/reference/iteratorSpreadInCall9.js b/tests/baselines/reference/iteratorSpreadInCall9.js index da80c461b1..3f54728fd8 100644 --- a/tests/baselines/reference/iteratorSpreadInCall9.js +++ b/tests/baselines/reference/iteratorSpreadInCall9.js @@ -1,6 +1,4 @@ //// [iteratorSpreadInCall9.ts] -new Foo(...new SymbolIterator, ...[...new StringIterator]); - class Foo { constructor(...s: T[]) { } } @@ -29,10 +27,12 @@ class StringIterator { [Symbol.iterator]() { return this; } -} +} + +new Foo(...new SymbolIterator, ...[...new StringIterator]); + //// [iteratorSpreadInCall9.js] -new Foo(...new SymbolIterator, ...[...new StringIterator]); class Foo { constructor(...s) { } } @@ -58,3 +58,4 @@ class StringIterator { return this; } } +new Foo(...new SymbolIterator, ...[...new StringIterator]); diff --git a/tests/baselines/reference/recursiveClassInstantiationsWithDefaultConstructors.js b/tests/baselines/reference/recursiveClassInstantiationsWithDefaultConstructors.js index 704c39891e..616d5392c8 100644 --- a/tests/baselines/reference/recursiveClassInstantiationsWithDefaultConstructors.js +++ b/tests/baselines/reference/recursiveClassInstantiationsWithDefaultConstructors.js @@ -1,13 +1,13 @@ //// [recursiveClassInstantiationsWithDefaultConstructors.ts] -var a = new TypeScript2.MemberNameArray() module TypeScript2 { -export class MemberName { -public prefix: string = ""; + export class MemberName { + public prefix: string = ""; + } + export class MemberNameArray extends MemberName { + } } -export class MemberNameArray extends MemberName { -} -} - + +var a = new TypeScript2.MemberNameArray() //// [recursiveClassInstantiationsWithDefaultConstructors.js] var __extends = (this && this.__extends) || (function () { @@ -20,7 +20,6 @@ var __extends = (this && this.__extends) || (function () { d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); -var a = new TypeScript2.MemberNameArray(); var TypeScript2; (function (TypeScript2) { var MemberName = (function () { @@ -39,3 +38,4 @@ var TypeScript2; }(MemberName)); TypeScript2.MemberNameArray = MemberNameArray; })(TypeScript2 || (TypeScript2 = {})); +var a = new TypeScript2.MemberNameArray(); diff --git a/tests/baselines/reference/recursiveClassInstantiationsWithDefaultConstructors.symbols b/tests/baselines/reference/recursiveClassInstantiationsWithDefaultConstructors.symbols index c722d8ef8f..7d87f5ec91 100644 --- a/tests/baselines/reference/recursiveClassInstantiationsWithDefaultConstructors.symbols +++ b/tests/baselines/reference/recursiveClassInstantiationsWithDefaultConstructors.symbols @@ -1,22 +1,22 @@ === tests/cases/compiler/recursiveClassInstantiationsWithDefaultConstructors.ts === -var a = new TypeScript2.MemberNameArray() ->a : Symbol(a, Decl(recursiveClassInstantiationsWithDefaultConstructors.ts, 0, 3)) ->TypeScript2.MemberNameArray : Symbol(TypeScript2.MemberNameArray, Decl(recursiveClassInstantiationsWithDefaultConstructors.ts, 4, 1)) ->TypeScript2 : Symbol(TypeScript2, Decl(recursiveClassInstantiationsWithDefaultConstructors.ts, 0, 41)) ->MemberNameArray : Symbol(TypeScript2.MemberNameArray, Decl(recursiveClassInstantiationsWithDefaultConstructors.ts, 4, 1)) - module TypeScript2 { ->TypeScript2 : Symbol(TypeScript2, Decl(recursiveClassInstantiationsWithDefaultConstructors.ts, 0, 41)) +>TypeScript2 : Symbol(TypeScript2, Decl(recursiveClassInstantiationsWithDefaultConstructors.ts, 0, 0)) -export class MemberName { ->MemberName : Symbol(MemberName, Decl(recursiveClassInstantiationsWithDefaultConstructors.ts, 1, 20)) + export class MemberName { +>MemberName : Symbol(MemberName, Decl(recursiveClassInstantiationsWithDefaultConstructors.ts, 0, 20)) -public prefix: string = ""; ->prefix : Symbol(MemberName.prefix, Decl(recursiveClassInstantiationsWithDefaultConstructors.ts, 2, 25)) -} -export class MemberNameArray extends MemberName { ->MemberNameArray : Symbol(MemberNameArray, Decl(recursiveClassInstantiationsWithDefaultConstructors.ts, 4, 1)) ->MemberName : Symbol(MemberName, Decl(recursiveClassInstantiationsWithDefaultConstructors.ts, 1, 20)) -} + public prefix: string = ""; +>prefix : Symbol(MemberName.prefix, Decl(recursiveClassInstantiationsWithDefaultConstructors.ts, 1, 29)) + } + export class MemberNameArray extends MemberName { +>MemberNameArray : Symbol(MemberNameArray, Decl(recursiveClassInstantiationsWithDefaultConstructors.ts, 3, 5)) +>MemberName : Symbol(MemberName, Decl(recursiveClassInstantiationsWithDefaultConstructors.ts, 0, 20)) + } } +var a = new TypeScript2.MemberNameArray() +>a : Symbol(a, Decl(recursiveClassInstantiationsWithDefaultConstructors.ts, 8, 3)) +>TypeScript2.MemberNameArray : Symbol(TypeScript2.MemberNameArray, Decl(recursiveClassInstantiationsWithDefaultConstructors.ts, 3, 5)) +>TypeScript2 : Symbol(TypeScript2, Decl(recursiveClassInstantiationsWithDefaultConstructors.ts, 0, 0)) +>MemberNameArray : Symbol(TypeScript2.MemberNameArray, Decl(recursiveClassInstantiationsWithDefaultConstructors.ts, 3, 5)) + diff --git a/tests/baselines/reference/recursiveClassInstantiationsWithDefaultConstructors.types b/tests/baselines/reference/recursiveClassInstantiationsWithDefaultConstructors.types index 3e74ba7f57..f1cf5894cd 100644 --- a/tests/baselines/reference/recursiveClassInstantiationsWithDefaultConstructors.types +++ b/tests/baselines/reference/recursiveClassInstantiationsWithDefaultConstructors.types @@ -1,4 +1,20 @@ === tests/cases/compiler/recursiveClassInstantiationsWithDefaultConstructors.ts === +module TypeScript2 { +>TypeScript2 : typeof TypeScript2 + + export class MemberName { +>MemberName : MemberName + + public prefix: string = ""; +>prefix : string +>"" : "" + } + export class MemberNameArray extends MemberName { +>MemberNameArray : MemberNameArray +>MemberName : MemberName + } +} + var a = new TypeScript2.MemberNameArray() >a : TypeScript2.MemberNameArray >new TypeScript2.MemberNameArray() : TypeScript2.MemberNameArray @@ -6,19 +22,3 @@ var a = new TypeScript2.MemberNameArray() >TypeScript2 : typeof TypeScript2 >MemberNameArray : typeof TypeScript2.MemberNameArray -module TypeScript2 { ->TypeScript2 : typeof TypeScript2 - -export class MemberName { ->MemberName : MemberName - -public prefix: string = ""; ->prefix : string ->"" : "" -} -export class MemberNameArray extends MemberName { ->MemberNameArray : MemberNameArray ->MemberName : MemberName -} -} - diff --git a/tests/baselines/reference/typeArgumentInferenceOrdering.js b/tests/baselines/reference/typeArgumentInferenceOrdering.js index d6e5666b55..f7a46c8438 100644 --- a/tests/baselines/reference/typeArgumentInferenceOrdering.js +++ b/tests/baselines/reference/typeArgumentInferenceOrdering.js @@ -1,7 +1,4 @@ //// [typeArgumentInferenceOrdering.ts] -function foo(f: { y: T }): T { return null } -var x = foo(new C()).x; // was Error that property x does not exist on type {} - class C { y: I; } @@ -13,13 +10,15 @@ interface I { interface Goo { p: string; } - + +function foo(f: { y: T }): T { return null } +var x = foo(new C()).x; // was Error that property x does not exist on type {} //// [typeArgumentInferenceOrdering.js] -function foo(f) { return null; } -var x = foo(new C()).x; // was Error that property x does not exist on type {} var C = (function () { function C() { } return C; }()); +function foo(f) { return null; } +var x = foo(new C()).x; // was Error that property x does not exist on type {} diff --git a/tests/baselines/reference/typeArgumentInferenceOrdering.symbols b/tests/baselines/reference/typeArgumentInferenceOrdering.symbols index 630aebcf18..0c01b4d8a5 100644 --- a/tests/baselines/reference/typeArgumentInferenceOrdering.symbols +++ b/tests/baselines/reference/typeArgumentInferenceOrdering.symbols @@ -1,39 +1,39 @@ === tests/cases/compiler/typeArgumentInferenceOrdering.ts === -function foo(f: { y: T }): T { return null } ->foo : Symbol(foo, Decl(typeArgumentInferenceOrdering.ts, 0, 0)) ->T : Symbol(T, Decl(typeArgumentInferenceOrdering.ts, 0, 13)) ->f : Symbol(f, Decl(typeArgumentInferenceOrdering.ts, 0, 16)) ->y : Symbol(y, Decl(typeArgumentInferenceOrdering.ts, 0, 20)) ->T : Symbol(T, Decl(typeArgumentInferenceOrdering.ts, 0, 13)) ->T : Symbol(T, Decl(typeArgumentInferenceOrdering.ts, 0, 13)) - -var x = foo(new C()).x; // was Error that property x does not exist on type {} ->x : Symbol(x, Decl(typeArgumentInferenceOrdering.ts, 1, 3)) ->foo(new C()).x : Symbol(I.x, Decl(typeArgumentInferenceOrdering.ts, 7, 13)) ->foo : Symbol(foo, Decl(typeArgumentInferenceOrdering.ts, 0, 0)) ->C : Symbol(C, Decl(typeArgumentInferenceOrdering.ts, 1, 23)) ->x : Symbol(I.x, Decl(typeArgumentInferenceOrdering.ts, 7, 13)) - class C { ->C : Symbol(C, Decl(typeArgumentInferenceOrdering.ts, 1, 23)) +>C : Symbol(C, Decl(typeArgumentInferenceOrdering.ts, 0, 0)) y: I; ->y : Symbol(C.y, Decl(typeArgumentInferenceOrdering.ts, 3, 9)) ->I : Symbol(I, Decl(typeArgumentInferenceOrdering.ts, 5, 1)) +>y : Symbol(C.y, Decl(typeArgumentInferenceOrdering.ts, 0, 9)) +>I : Symbol(I, Decl(typeArgumentInferenceOrdering.ts, 2, 1)) } interface I { ->I : Symbol(I, Decl(typeArgumentInferenceOrdering.ts, 5, 1)) +>I : Symbol(I, Decl(typeArgumentInferenceOrdering.ts, 2, 1)) x(): Goo; ->x : Symbol(I.x, Decl(typeArgumentInferenceOrdering.ts, 7, 13)) ->Goo : Symbol(Goo, Decl(typeArgumentInferenceOrdering.ts, 9, 1)) +>x : Symbol(I.x, Decl(typeArgumentInferenceOrdering.ts, 4, 13)) +>Goo : Symbol(Goo, Decl(typeArgumentInferenceOrdering.ts, 6, 1)) } interface Goo { ->Goo : Symbol(Goo, Decl(typeArgumentInferenceOrdering.ts, 9, 1)) +>Goo : Symbol(Goo, Decl(typeArgumentInferenceOrdering.ts, 6, 1)) p: string; ->p : Symbol(Goo.p, Decl(typeArgumentInferenceOrdering.ts, 11, 15)) +>p : Symbol(Goo.p, Decl(typeArgumentInferenceOrdering.ts, 8, 15)) } +function foo(f: { y: T }): T { return null } +>foo : Symbol(foo, Decl(typeArgumentInferenceOrdering.ts, 10, 1)) +>T : Symbol(T, Decl(typeArgumentInferenceOrdering.ts, 12, 13)) +>f : Symbol(f, Decl(typeArgumentInferenceOrdering.ts, 12, 16)) +>y : Symbol(y, Decl(typeArgumentInferenceOrdering.ts, 12, 20)) +>T : Symbol(T, Decl(typeArgumentInferenceOrdering.ts, 12, 13)) +>T : Symbol(T, Decl(typeArgumentInferenceOrdering.ts, 12, 13)) + +var x = foo(new C()).x; // was Error that property x does not exist on type {} +>x : Symbol(x, Decl(typeArgumentInferenceOrdering.ts, 13, 3)) +>foo(new C()).x : Symbol(I.x, Decl(typeArgumentInferenceOrdering.ts, 4, 13)) +>foo : Symbol(foo, Decl(typeArgumentInferenceOrdering.ts, 10, 1)) +>C : Symbol(C, Decl(typeArgumentInferenceOrdering.ts, 0, 0)) +>x : Symbol(I.x, Decl(typeArgumentInferenceOrdering.ts, 4, 13)) + diff --git a/tests/baselines/reference/typeArgumentInferenceOrdering.types b/tests/baselines/reference/typeArgumentInferenceOrdering.types index 1bbeadcf4d..788ab2285a 100644 --- a/tests/baselines/reference/typeArgumentInferenceOrdering.types +++ b/tests/baselines/reference/typeArgumentInferenceOrdering.types @@ -1,22 +1,4 @@ === tests/cases/compiler/typeArgumentInferenceOrdering.ts === -function foo(f: { y: T }): T { return null } ->foo : (f: { y: T; }) => T ->T : T ->f : { y: T; } ->y : T ->T : T ->T : T ->null : null - -var x = foo(new C()).x; // was Error that property x does not exist on type {} ->x : () => Goo ->foo(new C()).x : () => Goo ->foo(new C()) : I ->foo : (f: { y: T; }) => T ->new C() : C ->C : typeof C ->x : () => Goo - class C { >C : C @@ -40,3 +22,21 @@ interface Goo { >p : string } +function foo(f: { y: T }): T { return null } +>foo : (f: { y: T; }) => T +>T : T +>f : { y: T; } +>y : T +>T : T +>T : T +>null : null + +var x = foo(new C()).x; // was Error that property x does not exist on type {} +>x : () => Goo +>foo(new C()).x : () => Goo +>foo(new C()) : I +>foo : (f: { y: T; }) => T +>new C() : C +>C : typeof C +>x : () => Goo + diff --git a/tests/cases/compiler/recursiveClassInstantiationsWithDefaultConstructors.ts b/tests/cases/compiler/recursiveClassInstantiationsWithDefaultConstructors.ts index 1f76e4e6b5..9f008cd2b1 100644 --- a/tests/cases/compiler/recursiveClassInstantiationsWithDefaultConstructors.ts +++ b/tests/cases/compiler/recursiveClassInstantiationsWithDefaultConstructors.ts @@ -1,8 +1,9 @@ -var a = new TypeScript2.MemberNameArray() module TypeScript2 { -export class MemberName { -public prefix: string = ""; -} -export class MemberNameArray extends MemberName { -} + export class MemberName { + public prefix: string = ""; + } + export class MemberNameArray extends MemberName { + } } + +var a = new TypeScript2.MemberNameArray() \ No newline at end of file diff --git a/tests/cases/compiler/typeArgumentInferenceOrdering.ts b/tests/cases/compiler/typeArgumentInferenceOrdering.ts index 6887f7455d..faa7b45a4a 100644 --- a/tests/cases/compiler/typeArgumentInferenceOrdering.ts +++ b/tests/cases/compiler/typeArgumentInferenceOrdering.ts @@ -1,6 +1,3 @@ -function foo(f: { y: T }): T { return null } -var x = foo(new C()).x; // was Error that property x does not exist on type {} - class C { y: I; } @@ -12,3 +9,6 @@ interface I { interface Goo { p: string; } + +function foo(f: { y: T }): T { return null } +var x = foo(new C()).x; // was Error that property x does not exist on type {} \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/iterableArrayPattern1.ts b/tests/cases/conformance/es6/destructuring/iterableArrayPattern1.ts index 7b3be0365e..7a4cd1a2e4 100644 --- a/tests/cases/conformance/es6/destructuring/iterableArrayPattern1.ts +++ b/tests/cases/conformance/es6/destructuring/iterableArrayPattern1.ts @@ -1,5 +1,4 @@ //@target: ES6 -var [a, b] = new SymbolIterator; class SymbolIterator { next() { return { @@ -11,4 +10,6 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +var [a, b] = new SymbolIterator; \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/iterableArrayPattern10.ts b/tests/cases/conformance/es6/destructuring/iterableArrayPattern10.ts index 35d05ef1f9..591cdd2b6a 100644 --- a/tests/cases/conformance/es6/destructuring/iterableArrayPattern10.ts +++ b/tests/cases/conformance/es6/destructuring/iterableArrayPattern10.ts @@ -1,6 +1,4 @@ //@target: ES6 -function fun([a, b]) { } -fun(new FooIterator); class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,4 +12,7 @@ class FooIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +function fun([a, b]) { } +fun(new FooIterator); \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/iterableArrayPattern11.ts b/tests/cases/conformance/es6/destructuring/iterableArrayPattern11.ts index ed93b5175d..83ab94dece 100644 --- a/tests/cases/conformance/es6/destructuring/iterableArrayPattern11.ts +++ b/tests/cases/conformance/es6/destructuring/iterableArrayPattern11.ts @@ -1,6 +1,4 @@ //@target: ES6 -function fun([a, b] = new FooIterator) { } -fun(new FooIterator); class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,4 +12,7 @@ class FooIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +function fun([a, b] = new FooIterator) { } +fun(new FooIterator); diff --git a/tests/cases/conformance/es6/destructuring/iterableArrayPattern12.ts b/tests/cases/conformance/es6/destructuring/iterableArrayPattern12.ts index b7e763694e..079eb25df4 100644 --- a/tests/cases/conformance/es6/destructuring/iterableArrayPattern12.ts +++ b/tests/cases/conformance/es6/destructuring/iterableArrayPattern12.ts @@ -1,6 +1,4 @@ //@target: ES6 -function fun([a, ...b] = new FooIterator) { } -fun(new FooIterator); class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,4 +12,7 @@ class FooIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +function fun([a, ...b] = new FooIterator) { } +fun(new FooIterator); \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/iterableArrayPattern13.ts b/tests/cases/conformance/es6/destructuring/iterableArrayPattern13.ts index f0b9b142f4..f4909547e2 100644 --- a/tests/cases/conformance/es6/destructuring/iterableArrayPattern13.ts +++ b/tests/cases/conformance/es6/destructuring/iterableArrayPattern13.ts @@ -1,6 +1,4 @@ //@target: ES6 -function fun([a, ...b]) { } -fun(new FooIterator); class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,4 +12,7 @@ class FooIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +function fun([a, ...b]) { } +fun(new FooIterator); \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/iterableArrayPattern14.ts b/tests/cases/conformance/es6/destructuring/iterableArrayPattern14.ts index c327efa3ec..976c514823 100644 --- a/tests/cases/conformance/es6/destructuring/iterableArrayPattern14.ts +++ b/tests/cases/conformance/es6/destructuring/iterableArrayPattern14.ts @@ -1,6 +1,4 @@ //@target: ES6 -function fun(...[a, ...b]) { } -fun(new FooIterator); class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,4 +12,7 @@ class FooIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +function fun(...[a, ...b]) { } +fun(new FooIterator); \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/iterableArrayPattern15.ts b/tests/cases/conformance/es6/destructuring/iterableArrayPattern15.ts index 21d632fd54..ecc686b634 100644 --- a/tests/cases/conformance/es6/destructuring/iterableArrayPattern15.ts +++ b/tests/cases/conformance/es6/destructuring/iterableArrayPattern15.ts @@ -1,6 +1,4 @@ //@target: ES6 -function fun(...[a, b]: Bar[]) { } -fun(...new FooIterator); class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,4 +12,7 @@ class FooIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +function fun(...[a, b]: Bar[]) { } +fun(...new FooIterator); \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts b/tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts index 90db0e5edb..b81114cab2 100644 --- a/tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts +++ b/tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts @@ -1,6 +1,4 @@ //@target: ES6 -function fun(...[a, b]: Bar[]) { } -fun(new FooIterator); class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,4 +12,7 @@ class FooIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +function fun(...[a, b]: Bar[]) { } +fun(new FooIterator); \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/iterableArrayPattern18.ts b/tests/cases/conformance/es6/destructuring/iterableArrayPattern18.ts index e6e5ad617b..a03713037d 100644 --- a/tests/cases/conformance/es6/destructuring/iterableArrayPattern18.ts +++ b/tests/cases/conformance/es6/destructuring/iterableArrayPattern18.ts @@ -1,6 +1,4 @@ //@target: ES6 -function fun([a, b]: Bar[]) { } -fun(new FooIterator); class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,4 +12,7 @@ class FooIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +function fun([a, b]: Bar[]) { } +fun(new FooIterator); \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/iterableArrayPattern19.ts b/tests/cases/conformance/es6/destructuring/iterableArrayPattern19.ts index 8513dd0764..32024e83b1 100644 --- a/tests/cases/conformance/es6/destructuring/iterableArrayPattern19.ts +++ b/tests/cases/conformance/es6/destructuring/iterableArrayPattern19.ts @@ -1,6 +1,4 @@ //@target: ES6 -function fun([[a], b]: Bar[][]) { } -fun(new FooArrayIterator); class Bar { x } class Foo extends Bar { y } class FooArrayIterator { @@ -14,4 +12,7 @@ class FooArrayIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +function fun([[a], b]: Bar[][]) { } +fun(new FooArrayIterator); \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/iterableArrayPattern2.ts b/tests/cases/conformance/es6/destructuring/iterableArrayPattern2.ts index 587f1f0b05..d5543c0aed 100644 --- a/tests/cases/conformance/es6/destructuring/iterableArrayPattern2.ts +++ b/tests/cases/conformance/es6/destructuring/iterableArrayPattern2.ts @@ -1,5 +1,4 @@ //@target: ES6 -var [a, ...b] = new SymbolIterator; class SymbolIterator { next() { return { @@ -11,4 +10,6 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +var [a, ...b] = new SymbolIterator; \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/iterableArrayPattern20.ts b/tests/cases/conformance/es6/destructuring/iterableArrayPattern20.ts index b5be67b393..6a0e912673 100644 --- a/tests/cases/conformance/es6/destructuring/iterableArrayPattern20.ts +++ b/tests/cases/conformance/es6/destructuring/iterableArrayPattern20.ts @@ -1,6 +1,4 @@ //@target: ES6 -function fun(...[[a = new Foo], b = [new Foo]]: Bar[][]) { } -fun(...new FooArrayIterator); class Bar { x } class Foo extends Bar { y } class FooArrayIterator { @@ -14,4 +12,7 @@ class FooArrayIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +function fun(...[[a = new Foo], b = [new Foo]]: Bar[][]) { } +fun(...new FooArrayIterator); \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/iterableArrayPattern3.ts b/tests/cases/conformance/es6/destructuring/iterableArrayPattern3.ts index 31656b5661..ff63aa7417 100644 --- a/tests/cases/conformance/es6/destructuring/iterableArrayPattern3.ts +++ b/tests/cases/conformance/es6/destructuring/iterableArrayPattern3.ts @@ -1,6 +1,4 @@ //@target: ES6 -var a: Bar, b: Bar; -[a, b] = new FooIterator; class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,4 +12,7 @@ class FooIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +var a: Bar, b: Bar; +[a, b] = new FooIterator; \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/iterableArrayPattern4.ts b/tests/cases/conformance/es6/destructuring/iterableArrayPattern4.ts index edd95be159..b5aef9003b 100644 --- a/tests/cases/conformance/es6/destructuring/iterableArrayPattern4.ts +++ b/tests/cases/conformance/es6/destructuring/iterableArrayPattern4.ts @@ -1,6 +1,4 @@ //@target: ES6 -var a: Bar, b: Bar[]; -[a, ...b] = new FooIterator; class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,4 +12,7 @@ class FooIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +var a: Bar, b: Bar[]; +[a, ...b] = new FooIterator \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/iterableArrayPattern5.ts b/tests/cases/conformance/es6/destructuring/iterableArrayPattern5.ts index b51d0f09d0..a3911b1f5e 100644 --- a/tests/cases/conformance/es6/destructuring/iterableArrayPattern5.ts +++ b/tests/cases/conformance/es6/destructuring/iterableArrayPattern5.ts @@ -1,6 +1,4 @@ //@target: ES6 -var a: Bar, b: string; -[a, b] = new FooIterator; class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,4 +12,7 @@ class FooIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +var a: Bar, b: string; +[a, b] = new FooIterator; \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/iterableArrayPattern6.ts b/tests/cases/conformance/es6/destructuring/iterableArrayPattern6.ts index fc9395ed6a..057b9aeaff 100644 --- a/tests/cases/conformance/es6/destructuring/iterableArrayPattern6.ts +++ b/tests/cases/conformance/es6/destructuring/iterableArrayPattern6.ts @@ -1,6 +1,4 @@ //@target: ES6 -var a: Bar, b: string[]; -[a, ...b] = new FooIterator; class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,4 +12,7 @@ class FooIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +var a: Bar, b: string[]; +[a, ...b] = new FooIterator; \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/iterableArrayPattern7.ts b/tests/cases/conformance/es6/destructuring/iterableArrayPattern7.ts index 85b2f2e54e..965b715767 100644 --- a/tests/cases/conformance/es6/destructuring/iterableArrayPattern7.ts +++ b/tests/cases/conformance/es6/destructuring/iterableArrayPattern7.ts @@ -1,6 +1,4 @@ //@target: ES6 -var a: Bar, b: string[]; -[a, b] = new FooIterator; class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,4 +12,7 @@ class FooIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +var a: Bar, b: string[]; +[a, b] = new FooIterator; \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/iterableArrayPattern8.ts b/tests/cases/conformance/es6/destructuring/iterableArrayPattern8.ts index dd49205d6e..5638b4c49c 100644 --- a/tests/cases/conformance/es6/destructuring/iterableArrayPattern8.ts +++ b/tests/cases/conformance/es6/destructuring/iterableArrayPattern8.ts @@ -1,6 +1,4 @@ //@target: ES6 -var a: Bar, b: string; -[a, ...b] = new FooIterator; class Bar { x } class Foo extends Bar { y } class FooIterator { @@ -14,4 +12,7 @@ class FooIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +var a: Bar, b: string; +[a, ...b] = new FooIterator; \ No newline at end of file diff --git a/tests/cases/conformance/es6/for-ofStatements/for-of14.ts b/tests/cases/conformance/es6/for-ofStatements/for-of14.ts index 84fbda4825..f79794d59d 100644 --- a/tests/cases/conformance/es6/for-ofStatements/for-of14.ts +++ b/tests/cases/conformance/es6/for-ofStatements/for-of14.ts @@ -1,9 +1,9 @@ //@target: ES6 -var v: string; -for (v of new StringIterator) { } // Should fail because the iterator is not iterable - class StringIterator { next() { return ""; } -} \ No newline at end of file +} + +var v: string; +for (v of new StringIterator) { } // Should fail because the iterator is not iterable \ No newline at end of file diff --git a/tests/cases/conformance/es6/for-ofStatements/for-of15.ts b/tests/cases/conformance/es6/for-ofStatements/for-of15.ts index 1973e7ff95..b2e788bdef 100644 --- a/tests/cases/conformance/es6/for-ofStatements/for-of15.ts +++ b/tests/cases/conformance/es6/for-ofStatements/for-of15.ts @@ -1,7 +1,4 @@ //@target: ES6 -var v: string; -for (v of new StringIterator) { } // Should fail - class StringIterator { next() { return ""; @@ -9,4 +6,7 @@ class StringIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +var v: string; +for (v of new StringIterator) { } // Should fail \ No newline at end of file diff --git a/tests/cases/conformance/es6/for-ofStatements/for-of16.ts b/tests/cases/conformance/es6/for-ofStatements/for-of16.ts index 8f7bd6d848..fe78bae2ae 100644 --- a/tests/cases/conformance/es6/for-ofStatements/for-of16.ts +++ b/tests/cases/conformance/es6/for-ofStatements/for-of16.ts @@ -1,9 +1,9 @@ //@target: ES6 -var v: string; -for (v of new StringIterator) { } // Should fail - class StringIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +var v: string; +for (v of new StringIterator) { } // Should fail \ No newline at end of file diff --git a/tests/cases/conformance/es6/for-ofStatements/for-of17.ts b/tests/cases/conformance/es6/for-ofStatements/for-of17.ts index 431f066d47..b7270cbb81 100644 --- a/tests/cases/conformance/es6/for-ofStatements/for-of17.ts +++ b/tests/cases/conformance/es6/for-ofStatements/for-of17.ts @@ -1,7 +1,4 @@ //@target: ES6 -var v: string; -for (v of new NumberIterator) { } // Should succeed - class NumberIterator { next() { return { @@ -12,4 +9,7 @@ class NumberIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +var v: string; +for (v of new NumberIterator) { } // Should succeed \ No newline at end of file diff --git a/tests/cases/conformance/es6/for-ofStatements/for-of18.ts b/tests/cases/conformance/es6/for-ofStatements/for-of18.ts index 407ad7f0ed..647ae314b4 100644 --- a/tests/cases/conformance/es6/for-ofStatements/for-of18.ts +++ b/tests/cases/conformance/es6/for-ofStatements/for-of18.ts @@ -1,7 +1,4 @@ //@target: ES6 -var v: string; -for (v of new StringIterator) { } // Should succeed - class StringIterator { next() { return { @@ -12,4 +9,7 @@ class StringIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +var v: string; +for (v of new StringIterator) { } // Should succeed \ No newline at end of file diff --git a/tests/cases/conformance/es6/for-ofStatements/for-of19.ts b/tests/cases/conformance/es6/for-ofStatements/for-of19.ts index ff80b2690e..be51d219dc 100644 --- a/tests/cases/conformance/es6/for-ofStatements/for-of19.ts +++ b/tests/cases/conformance/es6/for-ofStatements/for-of19.ts @@ -1,8 +1,4 @@ //@target: ES6 -for (var v of new FooIterator) { - v; -} - class Foo { } class FooIterator { next() { @@ -14,4 +10,8 @@ class FooIterator { [Symbol.iterator]() { return this; } +} + +for (var v of new FooIterator) { + v; } \ No newline at end of file diff --git a/tests/cases/conformance/es6/for-ofStatements/for-of20.ts b/tests/cases/conformance/es6/for-ofStatements/for-of20.ts index 615f514937..3aa537a9f6 100644 --- a/tests/cases/conformance/es6/for-ofStatements/for-of20.ts +++ b/tests/cases/conformance/es6/for-ofStatements/for-of20.ts @@ -1,8 +1,4 @@ //@target: ES6 -for (let v of new FooIterator) { - v; -} - class Foo { } class FooIterator { next() { @@ -14,4 +10,8 @@ class FooIterator { [Symbol.iterator]() { return this; } +} + +for (let v of new FooIterator) { + v; } \ No newline at end of file diff --git a/tests/cases/conformance/es6/for-ofStatements/for-of21.ts b/tests/cases/conformance/es6/for-ofStatements/for-of21.ts index 4e4621034e..ab1e6fff26 100644 --- a/tests/cases/conformance/es6/for-ofStatements/for-of21.ts +++ b/tests/cases/conformance/es6/for-ofStatements/for-of21.ts @@ -1,8 +1,4 @@ //@target: ES6 -for (const v of new FooIterator) { - v; -} - class Foo { } class FooIterator { next() { @@ -14,4 +10,8 @@ class FooIterator { [Symbol.iterator]() { return this; } +} + +for (const v of new FooIterator) { + v; } \ No newline at end of file diff --git a/tests/cases/conformance/es6/for-ofStatements/for-of22.ts b/tests/cases/conformance/es6/for-ofStatements/for-of22.ts index 10a96502cd..c9a8834079 100644 --- a/tests/cases/conformance/es6/for-ofStatements/for-of22.ts +++ b/tests/cases/conformance/es6/for-ofStatements/for-of22.ts @@ -1,9 +1,4 @@ //@target: ES6 -v; -for (var v of new FooIterator) { - -} - class Foo { } class FooIterator { next() { @@ -15,4 +10,9 @@ class FooIterator { [Symbol.iterator]() { return this; } +} + +v; +for (var v of new FooIterator) { + } \ No newline at end of file diff --git a/tests/cases/conformance/es6/for-ofStatements/for-of23.ts b/tests/cases/conformance/es6/for-ofStatements/for-of23.ts index 81227cd066..df73418107 100644 --- a/tests/cases/conformance/es6/for-ofStatements/for-of23.ts +++ b/tests/cases/conformance/es6/for-ofStatements/for-of23.ts @@ -1,8 +1,4 @@ //@target: ES6 -for (const v of new FooIterator) { - const v = 0; // new scope -} - class Foo { } class FooIterator { next() { @@ -14,4 +10,8 @@ class FooIterator { [Symbol.iterator]() { return this; } +} + +for (const v of new FooIterator) { + const v = 0; // new scope } \ No newline at end of file diff --git a/tests/cases/conformance/es6/for-ofStatements/for-of25.ts b/tests/cases/conformance/es6/for-ofStatements/for-of25.ts index a1698bd282..61e6a58ce3 100644 --- a/tests/cases/conformance/es6/for-ofStatements/for-of25.ts +++ b/tests/cases/conformance/es6/for-ofStatements/for-of25.ts @@ -1,9 +1,9 @@ //@target: ES6 -var x: any; -for (var v of new StringIterator) { } - class StringIterator { [Symbol.iterator]() { return x; } -} \ No newline at end of file +} + +var x: any; +for (var v of new StringIterator) { } \ No newline at end of file diff --git a/tests/cases/conformance/es6/for-ofStatements/for-of26.ts b/tests/cases/conformance/es6/for-ofStatements/for-of26.ts index 0ab564a4f5..4414fdc159 100644 --- a/tests/cases/conformance/es6/for-ofStatements/for-of26.ts +++ b/tests/cases/conformance/es6/for-ofStatements/for-of26.ts @@ -1,7 +1,4 @@ //@target: ES6 -var x: any; -for (var v of new StringIterator) { } - class StringIterator { next() { return x; @@ -9,4 +6,7 @@ class StringIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +var x: any; +for (var v of new StringIterator) { } \ No newline at end of file diff --git a/tests/cases/conformance/es6/for-ofStatements/for-of27.ts b/tests/cases/conformance/es6/for-ofStatements/for-of27.ts index 8f2b84cbe1..f7244eed34 100644 --- a/tests/cases/conformance/es6/for-ofStatements/for-of27.ts +++ b/tests/cases/conformance/es6/for-ofStatements/for-of27.ts @@ -1,6 +1,6 @@ //@target: ES6 -for (var v of new StringIterator) { } - class StringIterator { [Symbol.iterator]: any; -} \ No newline at end of file +} + +for (var v of new StringIterator) { } \ No newline at end of file diff --git a/tests/cases/conformance/es6/for-ofStatements/for-of28.ts b/tests/cases/conformance/es6/for-ofStatements/for-of28.ts index 8c693193b0..e1b86f6135 100644 --- a/tests/cases/conformance/es6/for-ofStatements/for-of28.ts +++ b/tests/cases/conformance/es6/for-ofStatements/for-of28.ts @@ -1,9 +1,9 @@ //@target: ES6 -for (var v of new StringIterator) { } - class StringIterator { next: any; [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +for (var v of new StringIterator) { } \ No newline at end of file diff --git a/tests/cases/conformance/es6/for-ofStatements/for-of30.ts b/tests/cases/conformance/es6/for-ofStatements/for-of30.ts index 03b97c2313..67e1e3da70 100644 --- a/tests/cases/conformance/es6/for-ofStatements/for-of30.ts +++ b/tests/cases/conformance/es6/for-ofStatements/for-of30.ts @@ -1,6 +1,4 @@ //@target: ES6 -for (var v of new StringIterator) { } - class StringIterator { next() { return { @@ -14,4 +12,6 @@ class StringIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +for (var v of new StringIterator) { } \ No newline at end of file diff --git a/tests/cases/conformance/es6/for-ofStatements/for-of31.ts b/tests/cases/conformance/es6/for-ofStatements/for-of31.ts index 307f9b7cd4..701fcb50ed 100644 --- a/tests/cases/conformance/es6/for-ofStatements/for-of31.ts +++ b/tests/cases/conformance/es6/for-ofStatements/for-of31.ts @@ -1,6 +1,4 @@ //@target: ES6 -for (var v of new StringIterator) { } - class StringIterator { next() { return { @@ -12,4 +10,6 @@ class StringIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +for (var v of new StringIterator) { } \ No newline at end of file diff --git a/tests/cases/conformance/es6/for-ofStatements/for-of33.ts b/tests/cases/conformance/es6/for-ofStatements/for-of33.ts index b73d2daee8..f0af5c4a40 100644 --- a/tests/cases/conformance/es6/for-ofStatements/for-of33.ts +++ b/tests/cases/conformance/es6/for-ofStatements/for-of33.ts @@ -1,9 +1,9 @@ //@target: ES6 //@noImplicitAny: true -for (var v of new StringIterator) { } - class StringIterator { [Symbol.iterator]() { return v; } -} \ No newline at end of file +} + +for (var v of new StringIterator) { } \ No newline at end of file diff --git a/tests/cases/conformance/es6/for-ofStatements/for-of34.ts b/tests/cases/conformance/es6/for-ofStatements/for-of34.ts index d00f5ccde2..63b8822399 100644 --- a/tests/cases/conformance/es6/for-ofStatements/for-of34.ts +++ b/tests/cases/conformance/es6/for-ofStatements/for-of34.ts @@ -1,7 +1,5 @@ //@target: ES6 //@noImplicitAny: true -for (var v of new StringIterator) { } - class StringIterator { next() { return v; @@ -10,4 +8,6 @@ class StringIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +for (var v of new StringIterator) { } \ No newline at end of file diff --git a/tests/cases/conformance/es6/for-ofStatements/for-of35.ts b/tests/cases/conformance/es6/for-ofStatements/for-of35.ts index 0d66ce39ed..ab6e26d6d6 100644 --- a/tests/cases/conformance/es6/for-ofStatements/for-of35.ts +++ b/tests/cases/conformance/es6/for-ofStatements/for-of35.ts @@ -1,7 +1,5 @@ //@target: ES6 //@noImplicitAny: true -for (var v of new StringIterator) { } - class StringIterator { next() { return { @@ -13,4 +11,6 @@ class StringIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +for (var v of new StringIterator) { } \ No newline at end of file diff --git a/tests/cases/conformance/es6/spread/iteratorSpreadInArray.ts b/tests/cases/conformance/es6/spread/iteratorSpreadInArray.ts index 4b4f3e8cc1..88a85a4b88 100644 --- a/tests/cases/conformance/es6/spread/iteratorSpreadInArray.ts +++ b/tests/cases/conformance/es6/spread/iteratorSpreadInArray.ts @@ -1,6 +1,4 @@ //@target: ES6 -var array = [...new SymbolIterator]; - class SymbolIterator { next() { return { @@ -12,4 +10,6 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +var array = [...new SymbolIterator]; diff --git a/tests/cases/conformance/es6/spread/iteratorSpreadInArray10.ts b/tests/cases/conformance/es6/spread/iteratorSpreadInArray10.ts index f8549b82b7..56ff08e79f 100644 --- a/tests/cases/conformance/es6/spread/iteratorSpreadInArray10.ts +++ b/tests/cases/conformance/es6/spread/iteratorSpreadInArray10.ts @@ -1,8 +1,8 @@ //@target: ES6 -var array = [...new SymbolIterator]; - class SymbolIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +var array = [...new SymbolIterator]; \ No newline at end of file diff --git a/tests/cases/conformance/es6/spread/iteratorSpreadInArray2.ts b/tests/cases/conformance/es6/spread/iteratorSpreadInArray2.ts index 9db5d01087..e267386a50 100644 --- a/tests/cases/conformance/es6/spread/iteratorSpreadInArray2.ts +++ b/tests/cases/conformance/es6/spread/iteratorSpreadInArray2.ts @@ -1,6 +1,4 @@ //@target: ES6 -var array = [...new NumberIterator, ...new SymbolIterator]; - class SymbolIterator { next() { return { @@ -25,4 +23,6 @@ class NumberIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +var array = [...new NumberIterator, ...new SymbolIterator]; diff --git a/tests/cases/conformance/es6/spread/iteratorSpreadInArray3.ts b/tests/cases/conformance/es6/spread/iteratorSpreadInArray3.ts index 174c97de7c..8ef12250ce 100644 --- a/tests/cases/conformance/es6/spread/iteratorSpreadInArray3.ts +++ b/tests/cases/conformance/es6/spread/iteratorSpreadInArray3.ts @@ -1,6 +1,4 @@ //@target: ES6 -var array = [...[0, 1], ...new SymbolIterator]; - class SymbolIterator { next() { return { @@ -12,4 +10,6 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +var array = [...[0, 1], ...new SymbolIterator]; \ No newline at end of file diff --git a/tests/cases/conformance/es6/spread/iteratorSpreadInArray4.ts b/tests/cases/conformance/es6/spread/iteratorSpreadInArray4.ts index 47c2e63370..ec9faa78fe 100644 --- a/tests/cases/conformance/es6/spread/iteratorSpreadInArray4.ts +++ b/tests/cases/conformance/es6/spread/iteratorSpreadInArray4.ts @@ -1,6 +1,4 @@ //@target: ES6 -var array = [0, 1, ...new SymbolIterator]; - class SymbolIterator { next() { return { @@ -12,4 +10,6 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +var array = [0, 1, ...new SymbolIterator]; \ No newline at end of file diff --git a/tests/cases/conformance/es6/spread/iteratorSpreadInArray5.ts b/tests/cases/conformance/es6/spread/iteratorSpreadInArray5.ts index e6a8041a96..d4df51739c 100644 --- a/tests/cases/conformance/es6/spread/iteratorSpreadInArray5.ts +++ b/tests/cases/conformance/es6/spread/iteratorSpreadInArray5.ts @@ -1,6 +1,4 @@ //@target: ES6 -var array: number[] = [0, 1, ...new SymbolIterator]; - class SymbolIterator { next() { return { @@ -12,4 +10,6 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +var array: number[] = [0, 1, ...new SymbolIterator]; \ No newline at end of file diff --git a/tests/cases/conformance/es6/spread/iteratorSpreadInArray6.ts b/tests/cases/conformance/es6/spread/iteratorSpreadInArray6.ts index 7495ca6aac..1d021ca612 100644 --- a/tests/cases/conformance/es6/spread/iteratorSpreadInArray6.ts +++ b/tests/cases/conformance/es6/spread/iteratorSpreadInArray6.ts @@ -1,7 +1,4 @@ //@target: ES6 -var array: number[] = [0, 1]; -array.concat([...new SymbolIterator]); - class SymbolIterator { next() { return { @@ -13,4 +10,7 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +var array: number[] = [0, 1]; +array.concat([...new SymbolIterator]); \ No newline at end of file diff --git a/tests/cases/conformance/es6/spread/iteratorSpreadInArray7.ts b/tests/cases/conformance/es6/spread/iteratorSpreadInArray7.ts index 12ca478c73..2f96507c09 100644 --- a/tests/cases/conformance/es6/spread/iteratorSpreadInArray7.ts +++ b/tests/cases/conformance/es6/spread/iteratorSpreadInArray7.ts @@ -1,7 +1,4 @@ //@target: ES6 -var array: symbol[]; -array.concat([...new SymbolIterator]); - class SymbolIterator { next() { return { @@ -13,4 +10,7 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +var array: symbol[]; +array.concat([...new SymbolIterator]); \ No newline at end of file diff --git a/tests/cases/conformance/es6/spread/iteratorSpreadInArray8.ts b/tests/cases/conformance/es6/spread/iteratorSpreadInArray8.ts index 0e2258aa5e..8cc56068f8 100644 --- a/tests/cases/conformance/es6/spread/iteratorSpreadInArray8.ts +++ b/tests/cases/conformance/es6/spread/iteratorSpreadInArray8.ts @@ -1,6 +1,4 @@ //@target: ES6 -var array = [...new SymbolIterator]; - class SymbolIterator { next() { return { @@ -8,4 +6,6 @@ class SymbolIterator { done: false }; } -} \ No newline at end of file +} + +var array = [...new SymbolIterator]; \ No newline at end of file diff --git a/tests/cases/conformance/es6/spread/iteratorSpreadInArray9.ts b/tests/cases/conformance/es6/spread/iteratorSpreadInArray9.ts index 2b8d93c9cc..5bb80fd0c7 100644 --- a/tests/cases/conformance/es6/spread/iteratorSpreadInArray9.ts +++ b/tests/cases/conformance/es6/spread/iteratorSpreadInArray9.ts @@ -1,6 +1,4 @@ //@target: ES6 -var array = [...new SymbolIterator]; - class SymbolIterator { next() { return { @@ -11,4 +9,6 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +var array = [...new SymbolIterator]; \ No newline at end of file diff --git a/tests/cases/conformance/es6/spread/iteratorSpreadInCall.ts b/tests/cases/conformance/es6/spread/iteratorSpreadInCall.ts index 85d07e5699..34f6a7eb8f 100644 --- a/tests/cases/conformance/es6/spread/iteratorSpreadInCall.ts +++ b/tests/cases/conformance/es6/spread/iteratorSpreadInCall.ts @@ -1,6 +1,4 @@ //@target: ES6 -foo(...new SymbolIterator); - function foo(s: symbol) { } class SymbolIterator { next() { @@ -13,4 +11,6 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +foo(...new SymbolIterator); \ No newline at end of file diff --git a/tests/cases/conformance/es6/spread/iteratorSpreadInCall10.ts b/tests/cases/conformance/es6/spread/iteratorSpreadInCall10.ts index bf8ad336fb..aeb9aabde5 100644 --- a/tests/cases/conformance/es6/spread/iteratorSpreadInCall10.ts +++ b/tests/cases/conformance/es6/spread/iteratorSpreadInCall10.ts @@ -1,8 +1,5 @@ //@target: ES6 -foo(...new SymbolIterator); - function foo(s: T[]) { return s[0] } - class SymbolIterator { next() { return { @@ -14,4 +11,6 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +foo(...new SymbolIterator); \ No newline at end of file diff --git a/tests/cases/conformance/es6/spread/iteratorSpreadInCall11.ts b/tests/cases/conformance/es6/spread/iteratorSpreadInCall11.ts index 182e454cfc..795e9603be 100644 --- a/tests/cases/conformance/es6/spread/iteratorSpreadInCall11.ts +++ b/tests/cases/conformance/es6/spread/iteratorSpreadInCall11.ts @@ -1,8 +1,5 @@ //@target: ES6 -foo(...new SymbolIterator); - function foo(...s: T[]) { return s[0] } - class SymbolIterator { next() { return { @@ -14,4 +11,6 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +foo(...new SymbolIterator); \ No newline at end of file diff --git a/tests/cases/conformance/es6/spread/iteratorSpreadInCall12.ts b/tests/cases/conformance/es6/spread/iteratorSpreadInCall12.ts index a0bd1ede19..06bceec84f 100644 --- a/tests/cases/conformance/es6/spread/iteratorSpreadInCall12.ts +++ b/tests/cases/conformance/es6/spread/iteratorSpreadInCall12.ts @@ -1,6 +1,4 @@ //@target: ES6 -new Foo(...[...new SymbolIterator, ...[...new StringIterator]]); - class Foo { constructor(...s: T[]) { } } @@ -29,4 +27,6 @@ class StringIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +new Foo(...[...new SymbolIterator, ...[...new StringIterator]]); \ No newline at end of file diff --git a/tests/cases/conformance/es6/spread/iteratorSpreadInCall2.ts b/tests/cases/conformance/es6/spread/iteratorSpreadInCall2.ts index 4a8fd9ff38..e6d7277594 100644 --- a/tests/cases/conformance/es6/spread/iteratorSpreadInCall2.ts +++ b/tests/cases/conformance/es6/spread/iteratorSpreadInCall2.ts @@ -1,6 +1,4 @@ //@target: ES6 -foo(...new SymbolIterator); - function foo(s: symbol[]) { } class SymbolIterator { next() { @@ -13,4 +11,6 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +foo(...new SymbolIterator); \ No newline at end of file diff --git a/tests/cases/conformance/es6/spread/iteratorSpreadInCall3.ts b/tests/cases/conformance/es6/spread/iteratorSpreadInCall3.ts index b6e8fe0c86..0391dfdad0 100644 --- a/tests/cases/conformance/es6/spread/iteratorSpreadInCall3.ts +++ b/tests/cases/conformance/es6/spread/iteratorSpreadInCall3.ts @@ -1,6 +1,4 @@ //@target: ES6 -foo(...new SymbolIterator); - function foo(...s: symbol[]) { } class SymbolIterator { next() { @@ -13,4 +11,6 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +foo(...new SymbolIterator); \ No newline at end of file diff --git a/tests/cases/conformance/es6/spread/iteratorSpreadInCall4.ts b/tests/cases/conformance/es6/spread/iteratorSpreadInCall4.ts index 2a73fd6f3c..f3747f2586 100644 --- a/tests/cases/conformance/es6/spread/iteratorSpreadInCall4.ts +++ b/tests/cases/conformance/es6/spread/iteratorSpreadInCall4.ts @@ -1,6 +1,4 @@ //@target: ES6 -foo(...new SymbolIterator); - function foo(s1: symbol, ...s: symbol[]) { } class SymbolIterator { next() { @@ -13,4 +11,6 @@ class SymbolIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +foo(...new SymbolIterator); \ No newline at end of file diff --git a/tests/cases/conformance/es6/spread/iteratorSpreadInCall5.ts b/tests/cases/conformance/es6/spread/iteratorSpreadInCall5.ts index c17c4156e6..53b0e66037 100644 --- a/tests/cases/conformance/es6/spread/iteratorSpreadInCall5.ts +++ b/tests/cases/conformance/es6/spread/iteratorSpreadInCall5.ts @@ -1,6 +1,4 @@ //@target: ES6 -foo(...new SymbolIterator, ...new StringIterator); - function foo(...s: (symbol | string)[]) { } class SymbolIterator { next() { @@ -26,4 +24,6 @@ class StringIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +foo(...new SymbolIterator, ...new StringIterator); \ No newline at end of file diff --git a/tests/cases/conformance/es6/spread/iteratorSpreadInCall6.ts b/tests/cases/conformance/es6/spread/iteratorSpreadInCall6.ts index 2c6150f804..c48260e97e 100644 --- a/tests/cases/conformance/es6/spread/iteratorSpreadInCall6.ts +++ b/tests/cases/conformance/es6/spread/iteratorSpreadInCall6.ts @@ -1,6 +1,4 @@ //@target: ES6 -foo(...new SymbolIterator, ...new StringIterator); - function foo(...s: (symbol | number)[]) { } class SymbolIterator { next() { @@ -26,4 +24,6 @@ class StringIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +foo(...new SymbolIterator, ...new StringIterator); \ No newline at end of file diff --git a/tests/cases/conformance/es6/spread/iteratorSpreadInCall7.ts b/tests/cases/conformance/es6/spread/iteratorSpreadInCall7.ts index 56fb7936eb..6893cd9d8a 100644 --- a/tests/cases/conformance/es6/spread/iteratorSpreadInCall7.ts +++ b/tests/cases/conformance/es6/spread/iteratorSpreadInCall7.ts @@ -1,6 +1,4 @@ //@target: ES6 -foo(...new SymbolIterator, ...new StringIterator); - function foo(...s: T[]) { return s[0]; } class SymbolIterator { next() { @@ -26,4 +24,6 @@ class StringIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +foo(...new SymbolIterator, ...new StringIterator); \ No newline at end of file diff --git a/tests/cases/conformance/es6/spread/iteratorSpreadInCall8.ts b/tests/cases/conformance/es6/spread/iteratorSpreadInCall8.ts index e5b969456b..c81a475d7d 100644 --- a/tests/cases/conformance/es6/spread/iteratorSpreadInCall8.ts +++ b/tests/cases/conformance/es6/spread/iteratorSpreadInCall8.ts @@ -1,6 +1,4 @@ //@target: ES6 -new Foo(...new SymbolIterator, ...new StringIterator); - class Foo { constructor(...s: T[]) { } } @@ -29,4 +27,6 @@ class StringIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +new Foo(...new SymbolIterator, ...new StringIterator); \ No newline at end of file diff --git a/tests/cases/conformance/es6/spread/iteratorSpreadInCall9.ts b/tests/cases/conformance/es6/spread/iteratorSpreadInCall9.ts index 470f99844b..41ee21a564 100644 --- a/tests/cases/conformance/es6/spread/iteratorSpreadInCall9.ts +++ b/tests/cases/conformance/es6/spread/iteratorSpreadInCall9.ts @@ -1,6 +1,4 @@ //@target: ES6 -new Foo(...new SymbolIterator, ...[...new StringIterator]); - class Foo { constructor(...s: T[]) { } } @@ -29,4 +27,6 @@ class StringIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +new Foo(...new SymbolIterator, ...[...new StringIterator]); diff --git a/tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts b/tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts index 185641d080..b832d57855 100644 --- a/tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts +++ b/tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts @@ -1,5 +1,4 @@ //@target: ES5 -for (var v of new StringIterator) { } // In ES3/5, you cannot for...of over an arbitrary iterable. class StringIterator { @@ -12,4 +11,6 @@ class StringIterator { [Symbol.iterator]() { return this; } -} \ No newline at end of file +} + +for (var v of new StringIterator) { } \ No newline at end of file diff --git a/tests/cases/conformance/types/typeAliases/classDoesNotDependOnBaseTypes.ts b/tests/cases/conformance/types/typeAliases/classDoesNotDependOnBaseTypes.ts index 98f94718f3..4cc3a72395 100644 --- a/tests/cases/conformance/types/typeAliases/classDoesNotDependOnBaseTypes.ts +++ b/tests/cases/conformance/types/typeAliases/classDoesNotDependOnBaseTypes.ts @@ -1,12 +1,12 @@ -var x: StringTree; -if (typeof x !== "string") { - x[0] = ""; - x[0] = new StringTreeCollection; -} - type StringTree = string | StringTreeCollection; class StringTreeCollectionBase { [n: number]: StringTree; } -class StringTreeCollection extends StringTreeCollectionBase { } \ No newline at end of file +class StringTreeCollection extends StringTreeCollectionBase { } + +var x: StringTree; +if (typeof x !== "string") { + x[0] = ""; + x[0] = new StringTreeCollection; +} \ No newline at end of file From f7df4e00cc515e326dfdd9afdab518a80524a7cd Mon Sep 17 00:00:00 2001 From: Yui T Date: Sat, 25 Feb 2017 22:40:47 -0800 Subject: [PATCH 031/164] Update baselines --- .../reference/exportImport.errors.txt | 22 +++++++++++++++++++ ...eExportAssignmentOfGenericClass.errors.txt | 20 +++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 tests/baselines/reference/exportImport.errors.txt create mode 100644 tests/baselines/reference/privacyCheckExternalModuleExportAssignmentOfGenericClass.errors.txt diff --git a/tests/baselines/reference/exportImport.errors.txt b/tests/baselines/reference/exportImport.errors.txt new file mode 100644 index 0000000000..fb5a41fe1e --- /dev/null +++ b/tests/baselines/reference/exportImport.errors.txt @@ -0,0 +1,22 @@ +tests/cases/compiler/w1.ts(2,1): error TS2449: Class 'Widget1' used before its declaration. +tests/cases/compiler/w1.ts(2,10): error TS2449: Class 'Widget1' used before its declaration. + + +==== tests/cases/compiler/consumer.ts (0 errors) ==== + import e = require('./exporter'); + + export function w(): e.w { // Should be OK + return new e.w(); + } +==== tests/cases/compiler/w1.ts (2 errors) ==== + + export = Widget1 + ~~~~~~~~~~~~~~~~ +!!! error TS2449: Class 'Widget1' used before its declaration. + ~~~~~~~ +!!! error TS2449: Class 'Widget1' used before its declaration. + class Widget1 { name = 'one'; } + +==== tests/cases/compiler/exporter.ts (0 errors) ==== + export import w = require('./w1'); + \ No newline at end of file diff --git a/tests/baselines/reference/privacyCheckExternalModuleExportAssignmentOfGenericClass.errors.txt b/tests/baselines/reference/privacyCheckExternalModuleExportAssignmentOfGenericClass.errors.txt new file mode 100644 index 0000000000..2945950068 --- /dev/null +++ b/tests/baselines/reference/privacyCheckExternalModuleExportAssignmentOfGenericClass.errors.txt @@ -0,0 +1,20 @@ +tests/cases/compiler/privacyCheckExternalModuleExportAssignmentOfGenericClass_0.ts(1,1): error TS2449: Class 'Foo' used before its declaration. +tests/cases/compiler/privacyCheckExternalModuleExportAssignmentOfGenericClass_0.ts(1,10): error TS2449: Class 'Foo' used before its declaration. + + +==== tests/cases/compiler/privacyCheckExternalModuleExportAssignmentOfGenericClass_1.ts (0 errors) ==== + import Foo = require("./privacyCheckExternalModuleExportAssignmentOfGenericClass_0"); + export = Bar; + interface Bar { + foo: Foo; + } +==== tests/cases/compiler/privacyCheckExternalModuleExportAssignmentOfGenericClass_0.ts (2 errors) ==== + export = Foo; + ~~~~~~~~~~~~~ +!!! error TS2449: Class 'Foo' used before its declaration. + ~~~ +!!! error TS2449: Class 'Foo' used before its declaration. + class Foo { + constructor(public a: A) { } + } + \ No newline at end of file From 5d46d434e0fc21b4533f1cd9f3c64648204d85b2 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Mon, 27 Feb 2017 11:21:12 -0800 Subject: [PATCH 032/164] Error when used enum before declaration --- src/compiler/checker.ts | 16 ++++++++++------ src/compiler/diagnosticMessages.json | 4 ++++ .../enumUsedBeforeDeclaration.errors.txt | 15 +++++++++++++++ .../reference/enumUsedBeforeDeclaration.js | 17 +++++++++++++++++ .../cases/compiler/enumUsedBeforeDeclaration.ts | 5 +++++ 5 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 tests/baselines/reference/enumUsedBeforeDeclaration.errors.txt create mode 100644 tests/baselines/reference/enumUsedBeforeDeclaration.js create mode 100644 tests/cases/compiler/enumUsedBeforeDeclaration.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 57905315d7..ca1ff70541 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1056,9 +1056,10 @@ namespace ts { // block-scoped variable and namespace module. However, only when we // try to resolve name in /*1*/ which is used in variable position, // we want to check for block-scoped - if (meaning & SymbolFlags.BlockScopedVariable || (meaning & SymbolFlags.Class && (meaning & SymbolFlags.Value) === SymbolFlags.Value)) { + if (meaning & SymbolFlags.BlockScopedVariable || + ((meaning & SymbolFlags.Class || meaning & SymbolFlags.Enum) && (meaning & SymbolFlags.Value) === SymbolFlags.Value)) { const exportOrLocalSymbol = getExportSymbolOfValueSymbolIfExported(result); - if (exportOrLocalSymbol.flags & SymbolFlags.BlockScopedVariable || exportOrLocalSymbol.flags & SymbolFlags.Class) { + if (exportOrLocalSymbol.flags & SymbolFlags.BlockScopedVariable || exportOrLocalSymbol.flags & SymbolFlags.Class || exportOrLocalSymbol.flags & SymbolFlags.Enum) { checkResolvedBlockScopedVariable(exportOrLocalSymbol, errorLocation); } } @@ -1171,19 +1172,22 @@ namespace ts { } function checkResolvedBlockScopedVariable(result: Symbol, errorLocation: Node): void { - Debug.assert(!!(result.flags & SymbolFlags.BlockScopedVariable || result.flags & SymbolFlags.Class)); + Debug.assert(!!(result.flags & SymbolFlags.BlockScopedVariable || result.flags & SymbolFlags.Class || result.flags & SymbolFlags.Enum)); // Block-scoped variables cannot be used before their definition - const declaration = forEach(result.declarations, d => isBlockOrCatchScoped(d) || isClassLike(d) ? d : undefined); + const declaration = forEach(result.declarations, d => isBlockOrCatchScoped(d) || isClassLike(d) || (d.kind === SyntaxKind.EnumDeclaration) ? d : undefined); - Debug.assert(declaration !== undefined, "Block-scoped variable declaration is undefined"); + Debug.assert(declaration !== undefined, "Declaration to checkResolvedBlockScopedVariable is undefined"); if (!isInAmbientContext(declaration) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) { if (result.flags & SymbolFlags.BlockScopedVariable) { error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, declarationNameToString(declaration.name)); } - else { + else if (result.flags & SymbolFlags.Class) { error(errorLocation, Diagnostics.Class_0_used_before_its_declaration, declarationNameToString(declaration.name)); } + else if (result.flags & SymbolFlags.Enum) { + error(errorLocation, Diagnostics.Enum_0_used_before_its_declaration, declarationNameToString(declaration.name)); + } } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 691f8e8d31..24cd0c9e67 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1439,6 +1439,10 @@ "category": "Error", "code": 2449 }, + "Enum '{0}' used before its declaration.": { + "category": "Error", + "code": 2450 + }, "Cannot redeclare block-scoped variable '{0}'.": { "category": "Error", "code": 2451 diff --git a/tests/baselines/reference/enumUsedBeforeDeclaration.errors.txt b/tests/baselines/reference/enumUsedBeforeDeclaration.errors.txt new file mode 100644 index 0000000000..aea5366389 --- /dev/null +++ b/tests/baselines/reference/enumUsedBeforeDeclaration.errors.txt @@ -0,0 +1,15 @@ +tests/cases/compiler/enumUsedBeforeDeclaration.ts(1,18): error TS2450: Enum 'Color' used before its declaration. +tests/cases/compiler/enumUsedBeforeDeclaration.ts(2,24): error TS2450: Enum 'ConstColor' used before its declaration. + + +==== tests/cases/compiler/enumUsedBeforeDeclaration.ts (2 errors) ==== + const v: Color = Color.Green; + ~~~~~ +!!! error TS2450: Enum 'Color' used before its declaration. + const v2: ConstColor = ConstColor.Green; + ~~~~~~~~~~ +!!! error TS2450: Enum 'ConstColor' used before its declaration. + enum Color { Red, Green, Blue } + const enum ConstColor { Red, Green, Blue } + + \ No newline at end of file diff --git a/tests/baselines/reference/enumUsedBeforeDeclaration.js b/tests/baselines/reference/enumUsedBeforeDeclaration.js new file mode 100644 index 0000000000..63fc38471b --- /dev/null +++ b/tests/baselines/reference/enumUsedBeforeDeclaration.js @@ -0,0 +1,17 @@ +//// [enumUsedBeforeDeclaration.ts] +const v: Color = Color.Green; +const v2: ConstColor = ConstColor.Green; +enum Color { Red, Green, Blue } +const enum ConstColor { Red, Green, Blue } + + + +//// [enumUsedBeforeDeclaration.js] +var v = Color.Green; +var v2 = 1 /* Green */; +var Color; +(function (Color) { + Color[Color["Red"] = 0] = "Red"; + Color[Color["Green"] = 1] = "Green"; + Color[Color["Blue"] = 2] = "Blue"; +})(Color || (Color = {})); diff --git a/tests/cases/compiler/enumUsedBeforeDeclaration.ts b/tests/cases/compiler/enumUsedBeforeDeclaration.ts new file mode 100644 index 0000000000..98f5fca86f --- /dev/null +++ b/tests/cases/compiler/enumUsedBeforeDeclaration.ts @@ -0,0 +1,5 @@ +const v: Color = Color.Green; +const v2: ConstColor = ConstColor.Green; +enum Color { Red, Green, Blue } +const enum ConstColor { Red, Green, Blue } + From d7e62bb9f7d08907ef8abfd807b018faf9a2b069 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Fri, 3 Mar 2017 13:50:58 -0800 Subject: [PATCH 033/164] initial revision of infrastructure to produce text changes that uses existing node factory, formatter and printer --- Jakefile.js | 5 +- src/compiler/emitter.ts | 33 +- src/compiler/factory.ts | 4 + src/compiler/scanner.ts | 2 +- src/compiler/types.ts | 12 + src/compiler/utilities.ts | 14 +- src/compiler/visitor.ts | 150 ++--- src/harness/fourslash.ts | 11 +- src/harness/tsconfig.json | 3 +- src/harness/unittests/textChanges.ts | 520 ++++++++++++++++++ src/server/session.ts | 3 +- src/services/codeFixProvider.ts | 1 + .../fixClassSuperMustPrecedeThisAccess.ts | 17 +- .../fixConstructorForDerivedNeedSuperCall.ts | 7 +- .../fixExtendsInterfaceBecomesImplements.ts | 14 +- .../fixForgottenThisPropertyAccess.ts | 8 +- .../codefixes/unusedIdentifierFixes.ts | 133 ++--- src/services/formatting/formatting.ts | 50 +- src/services/formatting/formattingContext.ts | 2 +- src/services/formatting/formattingScanner.ts | 6 +- src/services/formatting/rulesProvider.ts | 4 + src/services/formatting/smartIndenter.ts | 87 +-- src/services/services.ts | 14 +- src/services/textChanges.ts | 475 ++++++++++++++++ src/services/tsconfig.json | 1 + src/services/types.ts | 10 +- src/services/utilities.ts | 14 +- .../reference/textChanges/deleteNode1.js | 13 + .../reference/textChanges/deleteNode2.js | 12 + .../reference/textChanges/deleteNode3.js | 14 + .../reference/textChanges/deleteNode4.js | 13 + .../reference/textChanges/deleteNode5.js | 16 + .../textChanges/deleteNodeInList1.js | 4 + .../textChanges/deleteNodeInList10.js | 10 + .../textChanges/deleteNodeInList11.js | 10 + .../textChanges/deleteNodeInList12.js | 10 + .../textChanges/deleteNodeInList13.js | 15 + .../textChanges/deleteNodeInList14.js | 15 + .../textChanges/deleteNodeInList15.js | 15 + .../textChanges/deleteNodeInList1_1.js | 4 + .../textChanges/deleteNodeInList2.js | 4 + .../textChanges/deleteNodeInList2_1.js | 4 + .../textChanges/deleteNodeInList3.js | 4 + .../textChanges/deleteNodeInList3_1.js | 4 + .../textChanges/deleteNodeInList4.js | 13 + .../textChanges/deleteNodeInList4_1.js | 17 + .../textChanges/deleteNodeInList5.js | 13 + .../textChanges/deleteNodeInList5_1.js | 16 + .../textChanges/deleteNodeInList6.js | 13 + .../textChanges/deleteNodeInList6_1.js | 16 + .../textChanges/deleteNodeInList7.js | 10 + .../textChanges/deleteNodeInList8.js | 10 + .../textChanges/deleteNodeInList9.js | 10 + .../reference/textChanges/deleteNodeRange1.js | 16 + .../reference/textChanges/deleteNodeRange2.js | 15 + .../reference/textChanges/deleteNodeRange3.js | 17 + .../reference/textChanges/deleteNodeRange4.js | 16 + .../reference/textChanges/deleteRange1.js | 15 + .../textChanges/extractMethodLike.js | 49 ++ .../reference/textChanges/insertNodeAfter1.js | 26 + .../reference/textChanges/insertNodeAfter2.js | 26 + .../insertNodeAfter3-block with newline.js | 16 + .../reference/textChanges/insertNodeAfter3.js | 14 + .../reference/textChanges/insertNodeAfter4.js | 16 + .../reference/textChanges/insertNodeAt1.js | 22 + .../reference/textChanges/insertNodeAt2.js | 20 + .../textChanges/insertNodeBefore1.js | 26 + .../textChanges/insertNodeBefore2.js | 26 + .../reference/textChanges/replaceNode1.js | 20 + .../replaceNode1NoLineBreakBefore.js | 13 + .../reference/textChanges/replaceNode2.js | 20 + .../reference/textChanges/replaceNode3.js | 21 + .../reference/textChanges/replaceNode4.js | 19 + .../reference/textChanges/replaceNode5.js | 19 + .../textChanges/replaceNodeRange1.js | 19 + .../textChanges/replaceNodeRange2.js | 19 + .../textChanges/replaceNodeRange3.js | 20 + .../textChanges/replaceNodeRange4.js | 18 + .../reference/textChanges/replaceRange.js | 19 + .../replaceRangeNoLineBreakBefore.js | 6 + .../replaceRangeWithForcedIndentation.js | 19 + .../fourslash/codeFixAddForgottenThis01.ts | 10 +- .../cases/fourslash/codeFixSuperAfterThis.ts | 10 +- tests/cases/fourslash/codeFixSuperCall.ts | 11 +- .../fourslash/unusedFunctionInNamespace1.ts | 1 - .../fourslash/unusedVariableInForLoop7FS.ts | 18 +- 86 files changed, 2208 insertions(+), 279 deletions(-) create mode 100644 src/harness/unittests/textChanges.ts create mode 100644 src/services/textChanges.ts create mode 100644 tests/baselines/reference/textChanges/deleteNode1.js create mode 100644 tests/baselines/reference/textChanges/deleteNode2.js create mode 100644 tests/baselines/reference/textChanges/deleteNode3.js create mode 100644 tests/baselines/reference/textChanges/deleteNode4.js create mode 100644 tests/baselines/reference/textChanges/deleteNode5.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeInList1.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeInList10.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeInList11.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeInList12.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeInList13.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeInList14.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeInList15.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeInList1_1.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeInList2.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeInList2_1.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeInList3.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeInList3_1.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeInList4.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeInList4_1.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeInList5.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeInList5_1.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeInList6.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeInList6_1.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeInList7.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeInList8.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeInList9.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeRange1.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeRange2.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeRange3.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeRange4.js create mode 100644 tests/baselines/reference/textChanges/deleteRange1.js create mode 100644 tests/baselines/reference/textChanges/extractMethodLike.js create mode 100644 tests/baselines/reference/textChanges/insertNodeAfter1.js create mode 100644 tests/baselines/reference/textChanges/insertNodeAfter2.js create mode 100644 tests/baselines/reference/textChanges/insertNodeAfter3-block with newline.js create mode 100644 tests/baselines/reference/textChanges/insertNodeAfter3.js create mode 100644 tests/baselines/reference/textChanges/insertNodeAfter4.js create mode 100644 tests/baselines/reference/textChanges/insertNodeAt1.js create mode 100644 tests/baselines/reference/textChanges/insertNodeAt2.js create mode 100644 tests/baselines/reference/textChanges/insertNodeBefore1.js create mode 100644 tests/baselines/reference/textChanges/insertNodeBefore2.js create mode 100644 tests/baselines/reference/textChanges/replaceNode1.js create mode 100644 tests/baselines/reference/textChanges/replaceNode1NoLineBreakBefore.js create mode 100644 tests/baselines/reference/textChanges/replaceNode2.js create mode 100644 tests/baselines/reference/textChanges/replaceNode3.js create mode 100644 tests/baselines/reference/textChanges/replaceNode4.js create mode 100644 tests/baselines/reference/textChanges/replaceNode5.js create mode 100644 tests/baselines/reference/textChanges/replaceNodeRange1.js create mode 100644 tests/baselines/reference/textChanges/replaceNodeRange2.js create mode 100644 tests/baselines/reference/textChanges/replaceNodeRange3.js create mode 100644 tests/baselines/reference/textChanges/replaceNodeRange4.js create mode 100644 tests/baselines/reference/textChanges/replaceRange.js create mode 100644 tests/baselines/reference/textChanges/replaceRangeNoLineBreakBefore.js create mode 100644 tests/baselines/reference/textChanges/replaceRangeWithForcedIndentation.js diff --git a/Jakefile.js b/Jakefile.js index f8be7c2b67..489bf62bd9 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -11,11 +11,7 @@ var ts = require("./lib/typescript"); // Variables var compilerDirectory = "src/compiler/"; -var servicesDirectory = "src/services/"; var serverDirectory = "src/server/"; -var typingsInstallerDirectory = "src/server/typingsInstaller"; -var cancellationTokenDirectory = "src/server/cancellationToken"; -var watchGuardDirectory = "src/server/watchGuard"; var harnessDirectory = "src/harness/"; var libraryDirectory = "src/lib/"; var scriptsDirectory = "scripts/"; @@ -131,6 +127,7 @@ var harnessSources = harnessCoreSources.concat([ "matchFiles.ts", "initializeTSConfig.ts", "printer.ts", + "textChanges.ts", "transform.ts", "customTransforms.ts", ].map(function (f) { diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index ee224befd4..c286eb9df1 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -199,6 +199,8 @@ namespace ts { onEmitHelpers, onSetSourceFile, substituteNode, + onBeforeEmitNodeArray, + onAfterEmitNodeArray } = handlers; const newLine = getNewLineCharacter(printerOptions); @@ -631,6 +633,11 @@ namespace ts { if (isExpression(node)) { return pipelineEmitExpression(trySubstituteNode(EmitHint.Expression, node)); } + + if (isToken(node)) { + writeTokenText(kind); + return; + } } function pipelineEmitExpression(node: Node): void { @@ -1553,6 +1560,10 @@ namespace ts { emitSignatureAndBody(node, emitSignatureHead); } + function emitBlockCallback(_hint: EmitHint, body: Node): void { + emitBlockFunctionBody(body); + } + function emitSignatureAndBody(node: FunctionLikeDeclaration, emitSignatureHead: (node: SignatureDeclaration) => void) { const body = node.body; if (body) { @@ -1564,12 +1575,22 @@ namespace ts { if (getEmitFlags(node) & EmitFlags.ReuseTempVariableScope) { emitSignatureHead(node); - emitBlockFunctionBody(body); + if (onEmitNode) { + onEmitNode(EmitHint.Unspecified, body, emitBlockCallback); + } + else { + emitBlockFunctionBody(body); + } } else { pushNameGenerationScope(); emitSignatureHead(node); - emitBlockFunctionBody(body); + if (onEmitNode) { + onEmitNode(EmitHint.Unspecified, body, emitBlockCallback); + } + else { + emitBlockFunctionBody(body); + } popNameGenerationScope(); } @@ -2200,6 +2221,10 @@ namespace ts { write(getOpeningBracket(format)); } + if (onBeforeEmitNodeArray) { + onBeforeEmitNodeArray(children); + } + if (isEmpty) { // Write a line terminator if the parent node was multi-line if (format & ListFormat.MultiLine) { @@ -2315,6 +2340,10 @@ namespace ts { } } + if (onAfterEmitNodeArray) { + onAfterEmitNodeArray(children); + } + if (format & ListFormat.BracketsMask) { write(getClosingBracket(format)); } diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index cfafaabebf..530b0a240c 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1099,6 +1099,10 @@ namespace ts { : node; } + export function createKeywordTypeNode(kind: KeywordTypeNode["kind"]): KeywordTypeNode { + return createSynthesizedNode(kind); + } + export function createFunctionDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) { const node = createSynthesizedNode(SyntaxKind.FunctionDeclaration); node.decorators = asNodeArray(decorators); diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index fb91b0ff5b..b7a3f35d72 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -333,7 +333,7 @@ namespace ts { } /* @internal */ - export function getLineStarts(sourceFile: SourceFile): number[] { + export function getLineStarts(sourceFile: SourceFileLike): number[] { return sourceFile.lineMap || (sourceFile.lineMap = computeLineStarts(sourceFile.text)); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 53d8411860..90b1d2cec8 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2204,6 +2204,16 @@ name: string; } + /* @internal */ + /** + * Subset of properties from SourceFile that are used in multiple utility functions + */ + export interface SourceFileLike { + readonly text: string; + lineMap: number[]; + } + + // Source files are declarations when they are external modules. export interface SourceFile extends Declaration { kind: SyntaxKind.SourceFile; @@ -4129,6 +4139,8 @@ /*@internal*/ onEmitSourceMapOfPosition?: (pos: number) => void; /*@internal*/ onEmitHelpers?: (node: Node, writeLines: (text: string) => void) => void; /*@internal*/ onSetSourceFile?: (node: SourceFile) => void; + /*@internal*/ onBeforeEmitNodeArray?: (nodes: NodeArray) => void; + /*@internal*/ onAfterEmitNodeArray?: (nodes: NodeArray) => void; } export interface PrinterOptions { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index e107c4b669..f37048a55d 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -184,7 +184,7 @@ namespace ts { return false; } - export function getStartPositionOfLine(line: number, sourceFile: SourceFile): number { + export function getStartPositionOfLine(line: number, sourceFile: SourceFileLike): number { Debug.assert(line >= 0); return getLineStarts(sourceFile)[line]; } @@ -204,7 +204,7 @@ namespace ts { return value !== undefined; } - export function getEndLinePosition(line: number, sourceFile: SourceFile): number { + export function getEndLinePosition(line: number, sourceFile: SourceFileLike): number { Debug.assert(line >= 0); const lineStarts = getLineStarts(sourceFile); @@ -255,7 +255,11 @@ namespace ts { return !nodeIsMissing(node); } - export function getTokenPosOfNode(node: Node, sourceFile?: SourceFile, includeJsDoc?: boolean): number { + export function isToken(n: Node): boolean { + return n.kind >= SyntaxKind.FirstToken && n.kind <= SyntaxKind.LastToken; + } + + export function getTokenPosOfNode(node: Node, sourceFile?: SourceFileLike, includeJsDoc?: boolean): number { // With nodes that have no width (i.e. 'Missing' nodes), we actually *don't* // want to skip trivia because this will launch us forward to the next token. if (nodeIsMissing(node)) { @@ -289,7 +293,7 @@ namespace ts { return node.kind >= SyntaxKind.FirstJSDocTagNode && node.kind <= SyntaxKind.LastJSDocTagNode; } - export function getNonDecoratorTokenPosOfNode(node: Node, sourceFile?: SourceFile): number { + export function getNonDecoratorTokenPosOfNode(node: Node, sourceFile?: SourceFileLike): number { if (nodeIsMissing(node) || !node.decorators) { return getTokenPosOfNode(node, sourceFile); } @@ -2476,7 +2480,7 @@ namespace ts { return indentStrings[1].length; } - export function createTextWriter(newLine: String): EmitTextWriter { + export function createTextWriter(newLine: string): EmitTextWriter { let output: string; let indent: number; let lineStart: boolean; diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 2d75d64612..db504847e2 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -154,9 +154,9 @@ namespace ts { * Starts a new lexical environment and visits a parameter list, suspending the lexical * environment upon completion. */ - export function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext) { + export function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes) { context.startLexicalEnvironment(); - const updated = visitNodes(nodes, visitor, isParameterDeclaration); + const updated = nodesVisitor(nodes, visitor, isParameterDeclaration); context.suspendLexicalEnvironment(); return updated; } @@ -204,9 +204,9 @@ namespace ts { * @param visitor The callback used to visit each child. * @param context A lexical environment context for the visitor. */ - export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext): T | undefined; + export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes): T | undefined; - export function visitEachChild(node: Node, visitor: Visitor, context: TransformationContext): Node { + export function visitEachChild(node: Node, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes): Node { if (node === undefined) { return undefined; } @@ -243,8 +243,8 @@ namespace ts { // Signature elements case SyntaxKind.Parameter: return updateParameter(node, - visitNodes((node).decorators, visitor, isDecorator), - visitNodes((node).modifiers, visitor, isModifier), + nodesVisitor((node).decorators, visitor, isDecorator), + nodesVisitor((node).modifiers, visitor, isModifier), (node).dotDotDotToken, visitNode((node).name, visitor, isBindingName), visitNode((node).type, visitor, isTypeNode), @@ -257,55 +257,55 @@ namespace ts { // Type member case SyntaxKind.PropertyDeclaration: return updateProperty(node, - visitNodes((node).decorators, visitor, isDecorator), - visitNodes((node).modifiers, visitor, isModifier), + nodesVisitor((node).decorators, visitor, isDecorator), + nodesVisitor((node).modifiers, visitor, isModifier), visitNode((node).name, visitor, isPropertyName), visitNode((node).type, visitor, isTypeNode), visitNode((node).initializer, visitor, isExpression)); case SyntaxKind.MethodDeclaration: return updateMethod(node, - visitNodes((node).decorators, visitor, isDecorator), - visitNodes((node).modifiers, visitor, isModifier), + nodesVisitor((node).decorators, visitor, isDecorator), + nodesVisitor((node).modifiers, visitor, isModifier), (node).asteriskToken, visitNode((node).name, visitor, isPropertyName), - visitNodes((node).typeParameters, visitor, isTypeParameter), - visitParameterList((node).parameters, visitor, context), + nodesVisitor((node).typeParameters, visitor, isTypeParameter), + visitParameterList((node).parameters, visitor, context, nodesVisitor), visitNode((node).type, visitor, isTypeNode), visitFunctionBody((node).body, visitor, context)); case SyntaxKind.Constructor: return updateConstructor(node, - visitNodes((node).decorators, visitor, isDecorator), - visitNodes((node).modifiers, visitor, isModifier), - visitParameterList((node).parameters, visitor, context), + nodesVisitor((node).decorators, visitor, isDecorator), + nodesVisitor((node).modifiers, visitor, isModifier), + visitParameterList((node).parameters, visitor, context, nodesVisitor), visitFunctionBody((node).body, visitor, context)); case SyntaxKind.GetAccessor: return updateGetAccessor(node, - visitNodes((node).decorators, visitor, isDecorator), - visitNodes((node).modifiers, visitor, isModifier), + nodesVisitor((node).decorators, visitor, isDecorator), + nodesVisitor((node).modifiers, visitor, isModifier), visitNode((node).name, visitor, isPropertyName), - visitParameterList((node).parameters, visitor, context), + visitParameterList((node).parameters, visitor, context, nodesVisitor), visitNode((node).type, visitor, isTypeNode), visitFunctionBody((node).body, visitor, context)); case SyntaxKind.SetAccessor: return updateSetAccessor(node, - visitNodes((node).decorators, visitor, isDecorator), - visitNodes((node).modifiers, visitor, isModifier), + nodesVisitor((node).decorators, visitor, isDecorator), + nodesVisitor((node).modifiers, visitor, isModifier), visitNode((node).name, visitor, isPropertyName), - visitParameterList((node).parameters, visitor, context), + visitParameterList((node).parameters, visitor, context, nodesVisitor), visitFunctionBody((node).body, visitor, context)); // Binding patterns case SyntaxKind.ObjectBindingPattern: return updateObjectBindingPattern(node, - visitNodes((node).elements, visitor, isBindingElement)); + nodesVisitor((node).elements, visitor, isBindingElement)); case SyntaxKind.ArrayBindingPattern: return updateArrayBindingPattern(node, - visitNodes((node).elements, visitor, isArrayBindingElement)); + nodesVisitor((node).elements, visitor, isArrayBindingElement)); case SyntaxKind.BindingElement: return updateBindingElement(node, @@ -317,11 +317,11 @@ namespace ts { // Expression case SyntaxKind.ArrayLiteralExpression: return updateArrayLiteral(node, - visitNodes((node).elements, visitor, isExpression)); + nodesVisitor((node).elements, visitor, isExpression)); case SyntaxKind.ObjectLiteralExpression: return updateObjectLiteral(node, - visitNodes((node).properties, visitor, isObjectLiteralElementLike)); + nodesVisitor((node).properties, visitor, isObjectLiteralElementLike)); case SyntaxKind.PropertyAccessExpression: return updatePropertyAccess(node, @@ -336,14 +336,14 @@ namespace ts { case SyntaxKind.CallExpression: return updateCall(node, visitNode((node).expression, visitor, isExpression), - visitNodes((node).typeArguments, visitor, isTypeNode), - visitNodes((node).arguments, visitor, isExpression)); + nodesVisitor((node).typeArguments, visitor, isTypeNode), + nodesVisitor((node).arguments, visitor, isExpression)); case SyntaxKind.NewExpression: return updateNew(node, visitNode((node).expression, visitor, isExpression), - visitNodes((node).typeArguments, visitor, isTypeNode), - visitNodes((node).arguments, visitor, isExpression)); + nodesVisitor((node).typeArguments, visitor, isTypeNode), + nodesVisitor((node).arguments, visitor, isExpression)); case SyntaxKind.TaggedTemplateExpression: return updateTaggedTemplate(node, @@ -361,19 +361,19 @@ namespace ts { case SyntaxKind.FunctionExpression: return updateFunctionExpression(node, - visitNodes((node).modifiers, visitor, isModifier), + nodesVisitor((node).modifiers, visitor, isModifier), (node).asteriskToken, visitNode((node).name, visitor, isIdentifier), - visitNodes((node).typeParameters, visitor, isTypeParameter), - visitParameterList((node).parameters, visitor, context), + nodesVisitor((node).typeParameters, visitor, isTypeParameter), + visitParameterList((node).parameters, visitor, context, nodesVisitor), visitNode((node).type, visitor, isTypeNode), visitFunctionBody((node).body, visitor, context)); case SyntaxKind.ArrowFunction: return updateArrowFunction(node, - visitNodes((node).modifiers, visitor, isModifier), - visitNodes((node).typeParameters, visitor, isTypeParameter), - visitParameterList((node).parameters, visitor, context), + nodesVisitor((node).modifiers, visitor, isModifier), + nodesVisitor((node).typeParameters, visitor, isTypeParameter), + visitParameterList((node).parameters, visitor, context, nodesVisitor), visitNode((node).type, visitor, isTypeNode), visitFunctionBody((node).body, visitor, context)); @@ -415,7 +415,7 @@ namespace ts { case SyntaxKind.TemplateExpression: return updateTemplateExpression(node, visitNode((node).head, visitor, isTemplateHead), - visitNodes((node).templateSpans, visitor, isTemplateSpan)); + nodesVisitor((node).templateSpans, visitor, isTemplateSpan)); case SyntaxKind.YieldExpression: return updateYield(node, @@ -428,15 +428,15 @@ namespace ts { case SyntaxKind.ClassExpression: return updateClassExpression(node, - visitNodes((node).modifiers, visitor, isModifier), + nodesVisitor((node).modifiers, visitor, isModifier), visitNode((node).name, visitor, isIdentifier), - visitNodes((node).typeParameters, visitor, isTypeParameter), - visitNodes((node).heritageClauses, visitor, isHeritageClause), - visitNodes((node).members, visitor, isClassElement)); + nodesVisitor((node).typeParameters, visitor, isTypeParameter), + nodesVisitor((node).heritageClauses, visitor, isHeritageClause), + nodesVisitor((node).members, visitor, isClassElement)); case SyntaxKind.ExpressionWithTypeArguments: return updateExpressionWithTypeArguments(node, - visitNodes((node).typeArguments, visitor, isTypeNode), + nodesVisitor((node).typeArguments, visitor, isTypeNode), visitNode((node).expression, visitor, isExpression)); case SyntaxKind.AsExpression: @@ -457,11 +457,11 @@ namespace ts { // Element case SyntaxKind.Block: return updateBlock(node, - visitNodes((node).statements, visitor, isStatement)); + nodesVisitor((node).statements, visitor, isStatement)); case SyntaxKind.VariableStatement: return updateVariableStatement(node, - visitNodes((node).modifiers, visitor, isModifier), + nodesVisitor((node).modifiers, visitor, isModifier), visitNode((node).declarationList, visitor, isVariableDeclarationList)); case SyntaxKind.ExpressionStatement: @@ -549,61 +549,61 @@ namespace ts { case SyntaxKind.VariableDeclarationList: return updateVariableDeclarationList(node, - visitNodes((node).declarations, visitor, isVariableDeclaration)); + nodesVisitor((node).declarations, visitor, isVariableDeclaration)); case SyntaxKind.FunctionDeclaration: return updateFunctionDeclaration(node, - visitNodes((node).decorators, visitor, isDecorator), - visitNodes((node).modifiers, visitor, isModifier), + nodesVisitor((node).decorators, visitor, isDecorator), + nodesVisitor((node).modifiers, visitor, isModifier), (node).asteriskToken, visitNode((node).name, visitor, isIdentifier), - visitNodes((node).typeParameters, visitor, isTypeParameter), - visitParameterList((node).parameters, visitor, context), + nodesVisitor((node).typeParameters, visitor, isTypeParameter), + visitParameterList((node).parameters, visitor, context, nodesVisitor), visitNode((node).type, visitor, isTypeNode), visitFunctionBody((node).body, visitor, context)); case SyntaxKind.ClassDeclaration: return updateClassDeclaration(node, - visitNodes((node).decorators, visitor, isDecorator), - visitNodes((node).modifiers, visitor, isModifier), + nodesVisitor((node).decorators, visitor, isDecorator), + nodesVisitor((node).modifiers, visitor, isModifier), visitNode((node).name, visitor, isIdentifier), - visitNodes((node).typeParameters, visitor, isTypeParameter), - visitNodes((node).heritageClauses, visitor, isHeritageClause), - visitNodes((node).members, visitor, isClassElement)); + nodesVisitor((node).typeParameters, visitor, isTypeParameter), + nodesVisitor((node).heritageClauses, visitor, isHeritageClause), + nodesVisitor((node).members, visitor, isClassElement)); case SyntaxKind.EnumDeclaration: return updateEnumDeclaration(node, - visitNodes((node).decorators, visitor, isDecorator), - visitNodes((node).modifiers, visitor, isModifier), + nodesVisitor((node).decorators, visitor, isDecorator), + nodesVisitor((node).modifiers, visitor, isModifier), visitNode((node).name, visitor, isIdentifier), - visitNodes((node).members, visitor, isEnumMember)); + nodesVisitor((node).members, visitor, isEnumMember)); case SyntaxKind.ModuleDeclaration: return updateModuleDeclaration(node, - visitNodes((node).decorators, visitor, isDecorator), - visitNodes((node).modifiers, visitor, isModifier), + nodesVisitor((node).decorators, visitor, isDecorator), + nodesVisitor((node).modifiers, visitor, isModifier), visitNode((node).name, visitor, isIdentifier), visitNode((node).body, visitor, isModuleBody)); case SyntaxKind.ModuleBlock: return updateModuleBlock(node, - visitNodes((node).statements, visitor, isStatement)); + nodesVisitor((node).statements, visitor, isStatement)); case SyntaxKind.CaseBlock: return updateCaseBlock(node, - visitNodes((node).clauses, visitor, isCaseOrDefaultClause)); + nodesVisitor((node).clauses, visitor, isCaseOrDefaultClause)); case SyntaxKind.ImportEqualsDeclaration: return updateImportEqualsDeclaration(node, - visitNodes((node).decorators, visitor, isDecorator), - visitNodes((node).modifiers, visitor, isModifier), + nodesVisitor((node).decorators, visitor, isDecorator), + nodesVisitor((node).modifiers, visitor, isModifier), visitNode((node).name, visitor, isIdentifier), visitNode((node).moduleReference, visitor, isModuleReference)); case SyntaxKind.ImportDeclaration: return updateImportDeclaration(node, - visitNodes((node).decorators, visitor, isDecorator), - visitNodes((node).modifiers, visitor, isModifier), + nodesVisitor((node).decorators, visitor, isDecorator), + nodesVisitor((node).modifiers, visitor, isModifier), visitNode((node).importClause, visitor, isImportClause), visitNode((node).moduleSpecifier, visitor, isExpression)); @@ -618,7 +618,7 @@ namespace ts { case SyntaxKind.NamedImports: return updateNamedImports(node, - visitNodes((node).elements, visitor, isImportSpecifier)); + nodesVisitor((node).elements, visitor, isImportSpecifier)); case SyntaxKind.ImportSpecifier: return updateImportSpecifier(node, @@ -627,20 +627,20 @@ namespace ts { case SyntaxKind.ExportAssignment: return updateExportAssignment(node, - visitNodes((node).decorators, visitor, isDecorator), - visitNodes((node).modifiers, visitor, isModifier), + nodesVisitor((node).decorators, visitor, isDecorator), + nodesVisitor((node).modifiers, visitor, isModifier), visitNode((node).expression, visitor, isExpression)); case SyntaxKind.ExportDeclaration: return updateExportDeclaration(node, - visitNodes((node).decorators, visitor, isDecorator), - visitNodes((node).modifiers, visitor, isModifier), + nodesVisitor((node).decorators, visitor, isDecorator), + nodesVisitor((node).modifiers, visitor, isModifier), visitNode((node).exportClause, visitor, isNamedExports), visitNode((node).moduleSpecifier, visitor, isExpression)); case SyntaxKind.NamedExports: return updateNamedExports(node, - visitNodes((node).elements, visitor, isExportSpecifier)); + nodesVisitor((node).elements, visitor, isExportSpecifier)); case SyntaxKind.ExportSpecifier: return updateExportSpecifier(node, @@ -656,12 +656,12 @@ namespace ts { case SyntaxKind.JsxElement: return updateJsxElement(node, visitNode((node).openingElement, visitor, isJsxOpeningElement), - visitNodes((node).children, visitor, isJsxChild), + nodesVisitor((node).children, visitor, isJsxChild), visitNode((node).closingElement, visitor, isJsxClosingElement)); case SyntaxKind.JsxAttributes: return updateJsxAttributes(node, - visitNodes((node).properties, visitor, isJsxAttributeLike)); + nodesVisitor((node).properties, visitor, isJsxAttributeLike)); case SyntaxKind.JsxSelfClosingElement: return updateJsxSelfClosingElement(node, @@ -694,15 +694,15 @@ namespace ts { case SyntaxKind.CaseClause: return updateCaseClause(node, visitNode((node).expression, visitor, isExpression), - visitNodes((node).statements, visitor, isStatement)); + nodesVisitor((node).statements, visitor, isStatement)); case SyntaxKind.DefaultClause: return updateDefaultClause(node, - visitNodes((node).statements, visitor, isStatement)); + nodesVisitor((node).statements, visitor, isStatement)); case SyntaxKind.HeritageClause: return updateHeritageClause(node, - visitNodes((node).types, visitor, isExpressionWithTypeArguments)); + nodesVisitor((node).types, visitor, isExpressionWithTypeArguments)); case SyntaxKind.CatchClause: return updateCatchClause(node, diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 2532a1875d..9f94904186 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -22,6 +22,10 @@ namespace FourSlash { ts.disableIncrementalParsing = false; + function normalizeNewLines(s: string) { + return s.replace(/\r\n/g, "\n"); + } + // Represents a parsed source file with metadata export interface FourSlashFile { // The contents of the file (with markers, etc stripped out) @@ -1958,8 +1962,7 @@ namespace FourSlash { public verifyCurrentFileContent(text: string) { const actual = this.getFileContent(this.activeFile.fileName); - const replaceNewlines = (str: string) => str.replace(/\r\n/g, "\n"); - if (replaceNewlines(actual) !== replaceNewlines(text)) { + if (normalizeNewLines(actual) !== normalizeNewLines(text)) { throw new Error("verifyCurrentFileContent\n" + "\tExpected: \"" + text + "\"\n" + "\t Actual: \"" + actual + "\""); @@ -2135,7 +2138,7 @@ namespace FourSlash { const actualText = this.rangeText(ranges[0]); const result = includeWhiteSpace - ? actualText === expectedText + ? normalizeNewLines(actualText) === normalizeNewLines(expectedText) : this.removeWhitespace(actualText) === this.removeWhitespace(expectedText); if (!result) { @@ -2185,7 +2188,7 @@ namespace FourSlash { continue; } - const newActions = this.languageService.getCodeFixesAtPosition(fileName, diagnostic.start, diagnostic.length, [diagnostic.code]); + const newActions = this.languageService.getCodeFixesAtPosition(fileName, diagnostic.start, diagnostic.length, [diagnostic.code], this.formatCodeSettings); if (newActions && newActions.length) { actions = actions ? actions.concat(newActions) : newActions; } diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json index 32af0eb260..ce98261a0c 100644 --- a/src/harness/tsconfig.json +++ b/src/harness/tsconfig.json @@ -121,6 +121,7 @@ "./unittests/projectErrors.ts", "./unittests/printer.ts", "./unittests/transform.ts", - "./unittests/customTransforms.ts" + "./unittests/customTransforms.ts", + "./unittests/textChanges.ts" ] } diff --git a/src/harness/unittests/textChanges.ts b/src/harness/unittests/textChanges.ts new file mode 100644 index 0000000000..b8c9a8e873 --- /dev/null +++ b/src/harness/unittests/textChanges.ts @@ -0,0 +1,520 @@ +/// +/// +/// + +namespace ts { + describe("textChanges", () => { + function findChild(name: string, n: Node) { + return find(n); + + function find(node: Node): Node { + if (isDeclaration(node) && node.name && isIdentifier(node.name) && node.name.text === name) { + return node; + } + else { + return forEachChild(node, find); + } + } + } + + const printerOptions = { newLine: NewLineKind.LineFeed }; + const newLineCharacter = getNewLineCharacter(printerOptions); + + function getRuleProvider(action?: (opts: FormatCodeSettings) => void) { + const options = { + indentSize: 4, + tabSize: 4, + newLineCharacter, + convertTabsToSpaces: true, + indentStyle: ts.IndentStyle.Smart, + insertSpaceAfterConstructor: false, + insertSpaceAfterCommaDelimiter: true, + insertSpaceAfterSemicolonInForStatements: true, + insertSpaceBeforeAndAfterBinaryOperators: true, + insertSpaceAfterKeywordsInControlFlowStatements: true, + insertSpaceAfterFunctionKeywordForAnonymousFunctions: false, + insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, + insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, + insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true, + insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, + insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false, + insertSpaceBeforeFunctionParenthesis: false, + placeOpenBraceOnNewLineForFunctions: false, + placeOpenBraceOnNewLineForControlBlocks: false, + }; + if (action) { + action(options); + } + const rulesProvider = new formatting.RulesProvider(); + rulesProvider.ensureUpToDate(options); + return rulesProvider; + } + + // validate that positions that were recovered from the printed text actually match positions that will be created if the same text is parsed. + function verifyPositions({ text, node }: textChanges.NonFormattedText): void { + const nodeList = flattenNodes(node); + const sourceFile = createSourceFile("f.ts", text, ScriptTarget.ES2015); + const parsedNodeList = flattenNodes(sourceFile.statements[0]); + Debug.assert(nodeList.length === parsedNodeList.length); + for (let i = 0; i < nodeList.length; i++) { + const left = nodeList[i]; + const right = parsedNodeList[i]; + Debug.assert(left.pos === right.pos); + Debug.assert(left.end === right.end); + } + + function flattenNodes(n: Node) { + const data: (Node | NodeArray)[] = []; + walk(n); + return data; + + function walk(n: Node | Node[]): void { + data.push(n); + return isArray(n) ? forEach(n, walk) : forEachChild(n, walk, walk); + } + } + } + + function runSingleFileTest(caption: string, setupFormatOptions: (opts: FormatCodeSettings) => void, 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(setupFormatOptions); + const changeTracker = new textChanges.ChangeTracker(printerOptions.newLine, rulesProvider, validateNodes ? verifyPositions : undefined); + testBlock(sourceFile, changeTracker); + const changes = changeTracker.getChanges(); + 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}`; + }); + }); + } + + function setNewLineForOpenBraceInFunctions(opts: FormatCodeSettings) { + opts.placeOpenBraceOnNewLineForFunctions = true; + } + + { + const text = ` +namespace M +{ + namespace M2 + { + function foo() { + // comment 1 + const x = 1; + + /** + * comment 2 line 1 + * comment 2 line 2 + */ + function f() { + return 100; + } + const y = 2; // comment 3 + return 1; + } + } +}`; + runSingleFileTest("extractMethodLike", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { + const statements = ((findChild("foo", sourceFile)).body).statements.slice(1); + const newFunction = createFunctionDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*asteriskToken*/ undefined, + /*name*/ "bar", + /*typeParameters*/ undefined, + /*parameters*/ emptyArray, + /*type*/ createKeywordTypeNode(SyntaxKind.AnyKeyword), + /*body */ createBlock(statements) + ); + + changeTracker.insertNodeBefore(sourceFile, /*before*/findChild("M2", sourceFile), newFunction, { insertTrailingNewLine: true }); + + // replace statements with return statement + const newStatement = createReturn( + createCall( + /*expression*/ newFunction.name, + /*typeArguments*/ undefined, + /*argumentsArray*/ emptyArray + )); + changeTracker.replaceNodeRange(sourceFile, statements[0], lastOrUndefined(statements), newStatement, { insertTrailingNewLine: true }); + }); + } + { + const text = ` +function foo() { + return 1; +} + +function bar() { + return 2; +} +`; + runSingleFileTest("deleteRange1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteRange(sourceFile, { pos: text.indexOf("function foo"), end: text.indexOf("function bar") }); + }); + } + function findVariableStatementContaining(name: string, sourceFile: SourceFile) { + const varDecl = findChild(name, sourceFile); + assert.equal(varDecl.kind, SyntaxKind.VariableDeclaration); + const varStatement = varDecl.parent.parent; + assert.equal(varStatement.kind, SyntaxKind.VariableStatement); + return varStatement; + } + { + const text = ` +var x = 1; // some comment - 1 +/** + * comment 2 + */ +var y = 2; // comment 3 +var z = 3; // comment 4 +`; + runSingleFileTest("deleteNode1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNode(sourceFile, findVariableStatementContaining("y", sourceFile)); + }); + runSingleFileTest("deleteNode2", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNode(sourceFile, findVariableStatementContaining("y", sourceFile), { useNonAdjustedStartPosition: true }); + }); + runSingleFileTest("deleteNode3", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNode(sourceFile, findVariableStatementContaining("y", sourceFile), { useNonAdjustedEndPosition: true }); + }); + runSingleFileTest("deleteNode4", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNode(sourceFile, findVariableStatementContaining("y", sourceFile), { useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: true }); + }); + runSingleFileTest("deleteNode5", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNode(sourceFile, findVariableStatementContaining("x", sourceFile)); + }); + } + { + const text = ` +// comment 1 +var x = 1; // comment 2 +// comment 3 +var y = 2; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 +`; + runSingleFileTest("deleteNodeRange1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile)); + }); + runSingleFileTest("deleteNodeRange2", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), + { useNonAdjustedStartPosition: true }); + }); + runSingleFileTest("deleteNodeRange3", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), + { useNonAdjustedEndPosition: true }); + }); + runSingleFileTest("deleteNodeRange4", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), + { useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: true }); + }); + } + function createTestVariableDeclaration(name: string) { + return createVariableDeclaration(name, /*type*/ undefined, createObjectLiteral([createPropertyAssignment("p1", createLiteral(1))], /*multiline*/ true)); + } + function createTestClass() { + return createClassDeclaration( + /*decorators*/ undefined, + [ + createToken(SyntaxKind.PublicKeyword) + ], + "class1", + /*typeParameters*/ undefined, + [ + createHeritageClause( + SyntaxKind.ImplementsKeyword, + [ + createExpressionWithTypeArguments(/*typeArguments*/ undefined, createIdentifier("interface1")) + ] + ) + ], + [ + createProperty( + /*decorators*/ undefined, + /*modifiers*/ undefined, + "property1", + /*questionToken*/ undefined, + createKeywordTypeNode(SyntaxKind.BooleanKeyword), + /*initializer*/ undefined + ) + ] + ); + } + { + const text = ` +// comment 1 +var x = 1; // comment 2 +// comment 3 +var y = 2; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7`; + runSingleFileTest("replaceRange", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { + changeTracker.replaceRange(sourceFile, { pos: text.indexOf("var y"), end: text.indexOf("var a") }, createTestClass(), { insertTrailingNewLine: true }); + }); + runSingleFileTest("replaceRangeWithForcedIndentation", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { + changeTracker.replaceRange(sourceFile, { pos: text.indexOf("var y"), end: text.indexOf("var a") }, createTestClass(), { insertTrailingNewLine: true, indentation: 8, delta: 0 }); + }); + + runSingleFileTest("replaceRangeNoLineBreakBefore", setNewLineForOpenBraceInFunctions, `const x = 1, y = "2";`, /*validateNodes*/ false, (sourceFile, changeTracker) => { + const newNode = createTestVariableDeclaration("z1"); + changeTracker.replaceRange(sourceFile, { pos: sourceFile.text.indexOf("y"), end: sourceFile.text.indexOf(";") }, newNode); + }); + } + { + const text = ` +namespace A { + const x = 1, y = "2"; +} +`; + runSingleFileTest("replaceNode1NoLineBreakBefore", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + const newNode = createTestVariableDeclaration("z1"); + changeTracker.replaceNode(sourceFile, findChild("y", sourceFile), newNode); + }); + } + { + const text = ` +// comment 1 +var x = 1; // comment 2 +// comment 3 +var y = 2; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7`; + runSingleFileTest("replaceNode1", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { + changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { insertTrailingNewLine: true }); + }); + runSingleFileTest("replaceNode2", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { + changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, insertTrailingNewLine: true, insertLeadingNewLine: true }); + }); + runSingleFileTest("replaceNode3", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { + changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { useNonAdjustedEndPosition: true, insertTrailingNewLine: true }); + }); + runSingleFileTest("replaceNode4", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { + changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: true }); + }); + runSingleFileTest("replaceNode5", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { + changeTracker.replaceNode(sourceFile, findVariableStatementContaining("x", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: true }); + }); + } + { + const text = ` +// comment 1 +var x = 1; // comment 2 +// comment 3 +var y = 2; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7`; + runSingleFileTest("replaceNodeRange1", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { + changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { insertTrailingNewLine: true }); + }); + runSingleFileTest("replaceNodeRange2", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { + changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, insertTrailingNewLine: true, insertLeadingNewLine: true }); + }); + runSingleFileTest("replaceNodeRange3", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { + changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { useNonAdjustedEndPosition: true, insertTrailingNewLine: true }); + }); + runSingleFileTest("replaceNodeRange4", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { + changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: true }); + }); + } + { + const text = ` +// comment 1 +var x = 1; // comment 2 +// comment 3 +var y; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7`; + runSingleFileTest("insertNodeAt1", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { + changeTracker.insertNodeAt(sourceFile, text.indexOf("var y"), createTestClass(), { insertTrailingNewLine: true }); + }); + runSingleFileTest("insertNodeAt2", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeAt(sourceFile, text.indexOf("; // comment 4"), createTestVariableDeclaration("z1")); + }); + } + { + const text = ` +namespace M { + // comment 1 + var x = 1; // comment 2 + // comment 3 + var y; // comment 4 + var z = 3; // comment 5 + // comment 6 + var a = 4; // comment 7 +}`; + runSingleFileTest("insertNodeBefore1", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { + changeTracker.insertNodeBefore(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { insertTrailingNewLine: true }); + }); + runSingleFileTest("insertNodeBefore2", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { + changeTracker.insertNodeBefore(sourceFile, findChild("M", sourceFile), createTestClass(), { insertTrailingNewLine: true }); + }); + runSingleFileTest("insertNodeAfter1", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { + changeTracker.insertNodeAfter(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { insertTrailingNewLine: true }); + }); + runSingleFileTest("insertNodeAfter2", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { + changeTracker.insertNodeAfter(sourceFile, findChild("M", sourceFile), createTestClass(), { insertLeadingNewLine: true }); + }); + } + { + function findOpenBraceForConstructor(sourceFile: SourceFile) { + const classDecl = sourceFile.statements[0]; + const constructorDecl = forEach(classDecl.members, m => m.kind === SyntaxKind.Constructor && (m).body && m); + return constructorDecl.body.getFirstToken(); + } + function createTestSuperCall() { + const superCall = createCall( + createSuper(), + /*typeArguments*/ undefined, + /*argumentsArray*/ emptyArray + ); + return createStatement(superCall); + } + const text1 = ` +class A { + constructor() { + } +} +`; + runSingleFileTest("insertNodeAfter3", noop, text1, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeAfter(sourceFile, findOpenBraceForConstructor(sourceFile), createTestSuperCall(), { insertTrailingNewLine: true }); + }); + const text2 = ` +class A { + constructor() { + var x = 1; + } +} +`; + runSingleFileTest("insertNodeAfter4", noop, text2, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeAfter(sourceFile, findVariableStatementContaining("x", sourceFile), createTestSuperCall(), { insertTrailingNewLine: true }); + }); + const text3 = ` +class A { + constructor() { + + } +} +`; + runSingleFileTest("insertNodeAfter3-block with newline", noop, text3, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeAfter(sourceFile, findOpenBraceForConstructor(sourceFile), createTestSuperCall(), { insertTrailingNewLine: true }); + }); + } + { + const text = `var a = 1, b = 2, c = 3;`; + runSingleFileTest("deleteNodeInList1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeInList(sourceFile, findChild("a", sourceFile)); + }); + runSingleFileTest("deleteNodeInList2", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeInList(sourceFile, findChild("b", sourceFile)); + }); + runSingleFileTest("deleteNodeInList3", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile)); + }); + } + { + const text = `var a = 1,b = 2,c = 3;`; + runSingleFileTest("deleteNodeInList1_1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeInList(sourceFile, findChild("a", sourceFile)); + }); + runSingleFileTest("deleteNodeInList2_1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeInList(sourceFile, findChild("b", sourceFile)); + }); + runSingleFileTest("deleteNodeInList3_1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile)); + }); + } + { + const text = ` +namespace M { + var a = 1, + b = 2, + c = 3; +}`; + runSingleFileTest("deleteNodeInList4", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeInList(sourceFile, findChild("a", sourceFile)); + }); + runSingleFileTest("deleteNodeInList5", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeInList(sourceFile, findChild("b", sourceFile)); + }); + runSingleFileTest("deleteNodeInList6", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile)); + }); + } + { + const text = ` +namespace M { + var a = 1, // comment 1 + // comment 2 + b = 2, // comment 3 + // comment 4 + c = 3; // comment 5 +}`; + runSingleFileTest("deleteNodeInList4_1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeInList(sourceFile, findChild("a", sourceFile)); + }); + runSingleFileTest("deleteNodeInList5_1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeInList(sourceFile, findChild("b", sourceFile)); + }); + runSingleFileTest("deleteNodeInList6_1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile)); + }); + } + { + const text = ` +function foo(a: number, b: string, c = true) { + return 1; +}`; + runSingleFileTest("deleteNodeInList7", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeInList(sourceFile, findChild("a", sourceFile)); + }); + runSingleFileTest("deleteNodeInList8", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeInList(sourceFile, findChild("b", sourceFile)); + }); + runSingleFileTest("deleteNodeInList9", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile)); + }); + } + { + const text = ` +function foo(a: number,b: string,c = true) { + return 1; +}`; + runSingleFileTest("deleteNodeInList10", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeInList(sourceFile, findChild("a", sourceFile)); + }); + runSingleFileTest("deleteNodeInList11", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeInList(sourceFile, findChild("b", sourceFile)); + }); + runSingleFileTest("deleteNodeInList12", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile)); + }); + } +{ + const text = ` +function foo( + a: number, + b: string, + c = true) { + return 1; +}`; + runSingleFileTest("deleteNodeInList13", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeInList(sourceFile, findChild("a", sourceFile)); + }); + runSingleFileTest("deleteNodeInList14", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeInList(sourceFile, findChild("b", sourceFile)); + }); + runSingleFileTest("deleteNodeInList15", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile)); + }); + } + }); +} \ No newline at end of file diff --git a/src/server/session.ts b/src/server/session.ts index b5e7e44970..64fce61a09 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1420,8 +1420,9 @@ namespace ts.server { const scriptInfo = project.getScriptInfoForNormalizedPath(file); const startPosition = getStartPosition(); const endPosition = getEndPosition(); + const formatOptions = this.projectService.getFormatCodeOptions(file); - const codeActions = project.getLanguageService().getCodeFixesAtPosition(file, startPosition, endPosition, args.errorCodes); + const codeActions = project.getLanguageService().getCodeFixesAtPosition(file, startPosition, endPosition, args.errorCodes, formatOptions); if (!codeActions) { return undefined; } diff --git a/src/services/codeFixProvider.ts b/src/services/codeFixProvider.ts index 10d0b8eef3..c48c5a2460 100644 --- a/src/services/codeFixProvider.ts +++ b/src/services/codeFixProvider.ts @@ -13,6 +13,7 @@ namespace ts { newLineCharacter: string; host: LanguageServiceHost; cancellationToken: CancellationToken; + rulesProvider: formatting.RulesProvider; } export namespace codefix { diff --git a/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts b/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts index 4528c48774..207d039df8 100644 --- a/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts +++ b/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts @@ -26,22 +26,13 @@ namespace ts.codefix { } } } - - const newPosition = getOpenBraceEnd(constructor, sourceFile); - const changes = [{ - fileName: sourceFile.fileName, textChanges: [{ - newText: superCall.getText(sourceFile), - span: { start: newPosition, length: 0 } - }, - { - newText: "", - span: { start: superCall.getStart(sourceFile), length: superCall.getWidth(sourceFile) } - }] - }]; + const changeTracker = textChanges.ChangeTracker.fromCodeFixContext(context); + changeTracker.insertNodeAfter(sourceFile, getOpenBrace(constructor, sourceFile), superCall, { insertTrailingNewLine: true }); + changeTracker.deleteNode(sourceFile, superCall); return [{ description: getLocaleSpecificMessage(Diagnostics.Make_super_call_the_first_statement_in_the_constructor), - changes + changes: changeTracker.getChanges() }]; function findSuperCall(n: Node): ExpressionStatement { diff --git a/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts b/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts index 0dede87cf2..27b655f19c 100644 --- a/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts +++ b/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts @@ -10,10 +10,13 @@ namespace ts.codefix { return undefined; } - const newPosition = getOpenBraceEnd(token.parent, sourceFile); + const changeTracker = textChanges.ChangeTracker.fromCodeFixContext(context); + const superCall = createStatement(createCall(createSuper(), /*typeArguments*/ undefined, /*argumentsArray*/ emptyArray)); + changeTracker.insertNodeAfter(sourceFile, getOpenBrace(token.parent, sourceFile), superCall, { insertTrailingNewLine: true }); + return [{ description: getLocaleSpecificMessage(Diagnostics.Add_missing_super_call), - changes: [{ fileName: sourceFile.fileName, textChanges: [{ newText: "super();", span: { start: newPosition, length: 0 } }] }] + changes: changeTracker.getChanges() }]; } }); diff --git a/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts b/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts index 1e72700ec0..80d4345a94 100644 --- a/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts +++ b/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts @@ -21,26 +21,20 @@ namespace ts.codefix { return undefined; } - let changeStart = extendsToken.getStart(sourceFile); - let changeEnd = extendsToken.getEnd(); - const textChanges: TextChange[] = [{ newText: " implements", span: { start: changeStart, length: changeEnd - changeStart } }]; + const changeTracker = textChanges.ChangeTracker.fromCodeFixContext(context); + changeTracker.replaceNode(sourceFile, extendsToken, createToken(SyntaxKind.ImplementsKeyword)); // We replace existing keywords with commas. for (let i = 1; i < heritageClauses.length; i++) { const keywordToken = heritageClauses[i].getFirstToken(); if (keywordToken) { - changeStart = keywordToken.getStart(sourceFile); - changeEnd = keywordToken.getEnd(); - textChanges.push({ newText: ",", span: { start: changeStart, length: changeEnd - changeStart } }); + changeTracker.replaceNode(sourceFile, keywordToken, createToken(SyntaxKind.CommaToken)); } } const result = [{ description: getLocaleSpecificMessage(Diagnostics.Change_extends_to_implements), - changes: [{ - fileName: sourceFile.fileName, - textChanges: textChanges - }] + changes: changeTracker.getChanges() }]; return result; diff --git a/src/services/codefixes/fixForgottenThisPropertyAccess.ts b/src/services/codefixes/fixForgottenThisPropertyAccess.ts index c9d59dd833..711a3289a2 100644 --- a/src/services/codefixes/fixForgottenThisPropertyAccess.ts +++ b/src/services/codefixes/fixForgottenThisPropertyAccess.ts @@ -5,11 +5,15 @@ namespace ts.codefix { getCodeActions: (context: CodeFixContext) => { const sourceFile = context.sourceFile; const token = getTokenAtPosition(sourceFile, context.span.start); - const start = token.getStart(sourceFile); + if (token.kind !== SyntaxKind.Identifier) { + return undefined; + } + const changeTracker = textChanges.ChangeTracker.fromCodeFixContext(context); + changeTracker.replaceNode(sourceFile, token, createPropertyAccess(createThis(), token)); return [{ description: getLocaleSpecificMessage(Diagnostics.Add_this_to_unresolved_variable), - changes: [{ fileName: sourceFile.fileName, textChanges: [{ newText: "this.", span: { start, length: 0 } }] }] + changes: changeTracker.getChanges() }]; } }); diff --git a/src/services/codefixes/unusedIdentifierFixes.ts b/src/services/codefixes/unusedIdentifierFixes.ts index a45a3c26db..e2561e208f 100644 --- a/src/services/codefixes/unusedIdentifierFixes.ts +++ b/src/services/codefixes/unusedIdentifierFixes.ts @@ -25,17 +25,17 @@ namespace ts.codefix { const forStatement = token.parent.parent.parent; const forInitializer = forStatement.initializer; if (forInitializer.declarations.length === 1) { - return createCodeFixToRemoveNode(forInitializer); + return deleteNode(forInitializer); } else { - return removeSingleItem(forInitializer.declarations, token); + return deleteNodeInList(token.parent); } case SyntaxKind.ForOfStatement: const forOfStatement = token.parent.parent.parent; if (forOfStatement.initializer.kind === SyntaxKind.VariableDeclarationList) { const forOfInitializer = forOfStatement.initializer; - return createCodeFix("{}", forOfInitializer.declarations[0].getStart(), forOfInitializer.declarations[0].getWidth()); + return replaceNode(forOfInitializer.declarations[0], createObjectLiteral()); } break; @@ -47,51 +47,59 @@ namespace ts.codefix { case SyntaxKind.CatchClause: const catchClause = token.parent.parent; const parameter = catchClause.variableDeclaration.getChildren()[0]; - return createCodeFixToRemoveNode(parameter); + return deleteNode(parameter); default: const variableStatement = token.parent.parent.parent; if (variableStatement.declarationList.declarations.length === 1) { - return createCodeFixToRemoveNode(variableStatement); + return deleteNode(variableStatement); } else { - const declarations = variableStatement.declarationList.declarations; - return removeSingleItem(declarations, token); + return deleteNodeInList(token.parent); } } case SyntaxKind.TypeParameter: const typeParameters = (token.parent.parent).typeParameters; if (typeParameters.length === 1) { - return createCodeFix("", token.parent.pos - 1, token.parent.end - token.parent.pos + 2); + const previousToken = getTokenAtPosition(sourceFile, typeParameters.pos - 1); + if (!previousToken || previousToken.kind !== SyntaxKind.LessThanToken) { + return deleteRange(typeParameters); + } + const nextToken = getTokenAtPosition(sourceFile, typeParameters.end); + if (!nextToken || nextToken.kind !== SyntaxKind.GreaterThanToken) { + return deleteRange(typeParameters); + } + return deleteNodeRange(previousToken, nextToken); } else { - return removeSingleItem(typeParameters, token); + return deleteNodeInList(token.parent); } case ts.SyntaxKind.Parameter: const functionDeclaration = token.parent.parent; if (functionDeclaration.parameters.length === 1) { - return createCodeFixToRemoveNode(token.parent); + return deleteNode(token.parent); } else { - return removeSingleItem(functionDeclaration.parameters, token); + return deleteNodeInList(token.parent); } // handle case where 'import a = A;' case SyntaxKind.ImportEqualsDeclaration: - const importEquals = findImportDeclaration(token); - return createCodeFixToRemoveNode(importEquals); + const importEquals = getAncestor(token, SyntaxKind.ImportEqualsDeclaration); + return deleteNode(importEquals); case SyntaxKind.ImportSpecifier: const namedImports = token.parent.parent; if (namedImports.elements.length === 1) { // Only 1 import and it is unused. So the entire declaration should be removed. - const importSpec = findImportDeclaration(token); - return createCodeFixToRemoveNode(importSpec); + const importSpec = getAncestor(token, SyntaxKind.ImportDeclaration); + return deleteNode(importSpec); } else { - return removeSingleItem(namedImports.elements, token); + // delete import specifier + return deleteNodeInList(token.parent); } // handle case where "import d, * as ns from './file'" @@ -99,98 +107,79 @@ namespace ts.codefix { case SyntaxKind.ImportClause: // this covers both 'import |d|' and 'import |d,| *' const importClause = token.parent; if (!importClause.namedBindings) { // |import d from './file'| or |import * as ns from './file'| - const importDecl = findImportDeclaration(importClause); - return createCodeFixToRemoveNode(importDecl); + const importDecl = getAncestor(importClause, SyntaxKind.ImportDeclaration); + return deleteNode(importDecl); } else { // import |d,| * as ns from './file' - const start = importClause.name.getStart(); - let end = findFirstNonSpaceCharPosStarting(importClause.name.end); - if (sourceFile.text.charCodeAt(end) === CharacterCodes.comma) { - end = findFirstNonSpaceCharPosStarting(end + 1); + const start = importClause.name.getStart(sourceFile); + const nextToken = getTokenAtPosition(sourceFile, importClause.name.end); + if (nextToken && nextToken.kind === SyntaxKind.CommaToken) { + // shift first non-whitespace position after comma to the start position of the node + return deleteRange({ pos: start, end: skipTrivia(sourceFile.text, nextToken.end, /*stopAfterLineBreaks*/ false, /*stopAtComments*/true) }); + } + else { + return deleteNode(importClause.name); } - - return createCodeFix("", start, end - start); } case SyntaxKind.NamespaceImport: const namespaceImport = token.parent; if (namespaceImport.name == token && !(namespaceImport.parent).name) { - const importDecl = findImportDeclaration(namespaceImport); - return createCodeFixToRemoveNode(importDecl); + const importDecl = getAncestor(namespaceImport, SyntaxKind.ImportDeclaration); + return deleteNode(importDecl); } else { - const start = (namespaceImport.parent).name.end; - return createCodeFix("", start, (namespaceImport.parent).namedBindings.end - start); + const previousToken = getTokenAtPosition(sourceFile, namespaceImport.pos - 1); + if (previousToken && previousToken.kind === SyntaxKind.CommaToken) { + const startPosition = textChanges.getAdjustedStartPosition(sourceFile, previousToken, {}, /*forDeleteOperation*/ true); + return deleteRange({ pos: startPosition, end: namespaceImport.end }); + } + return deleteRange(namespaceImport); } } break; case SyntaxKind.PropertyDeclaration: case SyntaxKind.NamespaceImport: - return createCodeFixToRemoveNode(token.parent); + return deleteNode(token.parent); } if (isDeclarationName(token)) { - return createCodeFixToRemoveNode(token.parent); + return deleteNode(token.parent); } else if (isLiteralComputedPropertyDeclarationName(token)) { - return createCodeFixToRemoveNode(token.parent.parent); + return deleteNode(token.parent.parent); } else { return undefined; } - function findImportDeclaration(token: Node): Node { - let importDecl = token; - while (importDecl.kind != SyntaxKind.ImportDeclaration && importDecl.parent) { - importDecl = importDecl.parent; - } - - return importDecl; + function deleteNode(n: Node) { + return makeChange(textChanges.ChangeTracker.fromCodeFixContext(context).deleteNode(sourceFile, n)); } - function createCodeFixToRemoveNode(node: Node) { - let end = node.getEnd(); - const endCharCode = sourceFile.text.charCodeAt(end); - const afterEndCharCode = sourceFile.text.charCodeAt(end + 1); - if (isLineBreak(endCharCode)) { - end += 1; - } - // in the case of CR LF, you could have two consecutive new line characters for one new line. - // this needs to be differenciated from two LF LF chars that actually mean two new lines. - if (isLineBreak(afterEndCharCode) && endCharCode !== afterEndCharCode) { - end += 1; - } - - const start = node.getStart(); - return createCodeFix("", start, end - start); + function deleteRange(range: TextRange) { + return makeChange(textChanges.ChangeTracker.fromCodeFixContext(context).deleteRange(sourceFile, range)); } - function findFirstNonSpaceCharPosStarting(start: number) { - while (isWhiteSpace(sourceFile.text.charCodeAt(start))) { - start += 1; - } - return start; + function deleteNodeInList(n: Node) { + return makeChange(textChanges.ChangeTracker.fromCodeFixContext(context).deleteNodeInList(sourceFile, n)); } - function createCodeFix(newText: string, start: number, length: number): CodeAction[] { + function deleteNodeRange(start: Node, end: Node) { + return makeChange(textChanges.ChangeTracker.fromCodeFixContext(context).deleteNodeRange(sourceFile, start, end)); + } + + function replaceNode(n: Node, newNode: Node) { + return makeChange(textChanges.ChangeTracker.fromCodeFixContext(context).replaceNode(sourceFile, n, newNode)); + } + + function makeChange(changeTracker: textChanges.ChangeTracker) { return [{ description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Remove_declaration_for_Colon_0), { 0: token.getText() }), - changes: [{ - fileName: sourceFile.fileName, - textChanges: [{ newText, span: { start, length } }] - }] + changes: changeTracker.getChanges() }]; } - - function removeSingleItem(elements: NodeArray, token: T): CodeAction[] { - if (elements[0] === token.parent) { - return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos + 1); - } - else { - return createCodeFix("", token.parent.pos - 1, token.parent.end - token.parent.pos + 1); - } - } } }); } \ No newline at end of file diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 201d64e4d7..4fa3b71a3a 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -314,24 +314,55 @@ namespace ts.formatting { return 0; } + /* @internal */ + export function formatNode(node: Node, sourceFileLike: SourceFileLike, languageVariant: LanguageVariant, initialIndentation: number, delta: number, rulesProvider: RulesProvider): TextChange[] { + const range = { pos: 0, end: sourceFileLike.text.length }; + return formatSpanWorker( + range, + node, + initialIndentation, + delta, + getFormattingScanner(sourceFileLike.text, languageVariant, range.pos, range.end), + rulesProvider.getFormatOptions(), + rulesProvider, + FormattingRequestKind.FormatSelection, + _ => false, // assume that node does not have any errors + sourceFileLike); + } + function formatSpan(originalRange: TextRange, sourceFile: SourceFile, options: FormatCodeSettings, rulesProvider: RulesProvider, requestKind: FormattingRequestKind): TextChange[] { + // find the smallest node that fully wraps the range and compute the initial indentation for the node + const enclosingNode = findEnclosingNode(originalRange, sourceFile); + return formatSpanWorker( + originalRange, + enclosingNode, + SmartIndenter.getIndentationForNode(enclosingNode, originalRange, sourceFile, options), + getOwnOrInheritedDelta(enclosingNode, options, sourceFile), + getFormattingScanner(sourceFile.text, sourceFile.languageVariant, getScanStartPosition(enclosingNode, originalRange, sourceFile), originalRange.end), + options, + rulesProvider, + requestKind, + prepareRangeContainsErrorFunction(sourceFile.parseDiagnostics, originalRange), + sourceFile); + } - const rangeContainsError = prepareRangeContainsErrorFunction(sourceFile.parseDiagnostics, originalRange); + function formatSpanWorker(originalRange: TextRange, + enclosingNode: Node, + initialIndentation: number, + delta: number, + formattingScanner: FormattingScanner, + options: FormatCodeSettings, + rulesProvider: RulesProvider, + requestKind: FormattingRequestKind, + rangeContainsError: (r: TextRange) => boolean, + sourceFile: SourceFileLike): TextChange[] { // formatting context is used by rules provider const formattingContext = new FormattingContext(sourceFile, requestKind); - - // find the smallest node that fully wraps the range and compute the initial indentation for the node - const enclosingNode = findEnclosingNode(originalRange, sourceFile); - - const formattingScanner = getFormattingScanner(sourceFile, getScanStartPosition(enclosingNode, originalRange, sourceFile), originalRange.end); - - const initialIndentation = SmartIndenter.getIndentationForNode(enclosingNode, originalRange, sourceFile, options); - let previousRangeHasError: boolean; let previousRange: TextRangeWithKind; let previousParent: Node; @@ -351,7 +382,6 @@ namespace ts.formatting { undecoratedStartLine = sourceFile.getLineAndCharacterOfPosition(getNonDecoratorTokenPosOfNode(enclosingNode, sourceFile)).line; } - const delta = getOwnOrInheritedDelta(enclosingNode, options, sourceFile); processNode(enclosingNode, enclosingNode, startLine, undecoratedStartLine, initialIndentation, delta); } diff --git a/src/services/formatting/formattingContext.ts b/src/services/formatting/formattingContext.ts index bd5ca35247..26b538dfc5 100644 --- a/src/services/formatting/formattingContext.ts +++ b/src/services/formatting/formattingContext.ts @@ -15,7 +15,7 @@ namespace ts.formatting { private contextNodeBlockIsOnOneLine: boolean; private nextNodeBlockIsOnOneLine: boolean; - constructor(public sourceFile: SourceFile, public formattingRequestKind: FormattingRequestKind) { + constructor(public readonly sourceFile: SourceFileLike, public formattingRequestKind: FormattingRequestKind) { } public updateContext(currentRange: TextRangeWithKind, currentTokenParent: Node, nextRange: TextRangeWithKind, nextTokenParent: Node, commonParent: Node) { diff --git a/src/services/formatting/formattingScanner.ts b/src/services/formatting/formattingScanner.ts index 2020352f86..981ae09b2b 100644 --- a/src/services/formatting/formattingScanner.ts +++ b/src/services/formatting/formattingScanner.ts @@ -30,11 +30,11 @@ namespace ts.formatting { RescanJsxText, } - export function getFormattingScanner(sourceFile: SourceFile, startPos: number, endPos: number): FormattingScanner { + export function getFormattingScanner(text: string, languageVariant: LanguageVariant, startPos: number, endPos: number): FormattingScanner { Debug.assert(scanner === undefined, "Scanner should be undefined"); - scanner = sourceFile.languageVariant === LanguageVariant.JSX ? jsxScanner : standardScanner; + scanner = languageVariant === LanguageVariant.JSX ? jsxScanner : standardScanner; - scanner.setText(sourceFile.text); + scanner.setText(text); scanner.setTextPos(startPos); let wasNewLine = true; diff --git a/src/services/formatting/rulesProvider.ts b/src/services/formatting/rulesProvider.ts index 14e08e4857..660d5f34a0 100644 --- a/src/services/formatting/rulesProvider.ts +++ b/src/services/formatting/rulesProvider.ts @@ -24,6 +24,10 @@ namespace ts.formatting { return this.rulesMap; } + public getFormatOptions(): Readonly { + return this.options; + } + public ensureUpToDate(options: ts.FormatCodeSettings) { if (!this.options || !ts.compareDataObjects(this.options, options)) { const activeRules = this.createActiveRules(options); diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index eb9e1ba04c..b5c901482a 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -8,7 +8,19 @@ namespace ts.formatting { Unknown = -1 } - export function getIndentation(position: number, sourceFile: SourceFile, options: EditorSettings): number { + /** + * Computed indentation for a given position in source file + * @param position - position in file + * @param sourceFile - target source file + * @param options - set of editor options that control indentation + * @param assumeNewLineBeforeCloseBrace - false when getIndentation is called on the text from the real source file. + * true - when we need to assume that position is on the newline. This is usefult for codefixes, i.e. + * function f() { + * |} + * when inserting some text after open brace we would like to get the value of indentation as if newline was already there. + * However by default indentation at position | will be 0 so 'assumeNewLineBeforeCloseBrace' allows to override this behavior, + */ + export function getIndentation(position: number, sourceFile: SourceFile, options: EditorSettings, assumeNewLineBeforeCloseBrace = false): number { if (position > sourceFile.text.length) { return getBaseIndentation(options); // past EOF } @@ -71,13 +83,14 @@ namespace ts.formatting { if (positionBelongsToNode(current, position, sourceFile) && shouldIndentChildNode(current, previous)) { currentStart = getStartLineAndCharacterForNode(current, sourceFile); - if (nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken, current, lineAtPosition, sourceFile)) { - indentationDelta = 0; + const nextTokenKind = nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken, current, lineAtPosition, sourceFile); + if (nextTokenKind !== NextTokenKind.Unknown) { + // handle cases when codefix is about to be inserted before the close brace + indentationDelta = assumeNewLineBeforeCloseBrace && nextTokenKind === NextTokenKind.CloseBrace ? options.indentSize : 0; } else { indentationDelta = lineAtPosition !== currentStart.line ? options.indentSize : 0; } - break; } @@ -218,15 +231,21 @@ namespace ts.formatting { return findColumnForFirstNonWhitespaceCharacterInLine(currentLineAndChar, sourceFile, options); } - function nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken: Node, current: Node, lineAtPosition: number, sourceFile: SourceFile): boolean { + const enum NextTokenKind { + Unknown, + OpenBrace, + CloseBrace + } + + function nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken: Node, current: Node, lineAtPosition: number, sourceFile: SourceFile): NextTokenKind { const nextToken = findNextToken(precedingToken, current); if (!nextToken) { - return false; + return NextTokenKind.Unknown; } if (nextToken.kind === SyntaxKind.OpenBraceToken) { // open braces are always indented at the parent level - return true; + return NextTokenKind.OpenBrace; } else if (nextToken.kind === SyntaxKind.CloseBraceToken) { // close braces are indented at the parent level if they are located on the same line with cursor @@ -239,17 +258,17 @@ namespace ts.formatting { // $} const nextTokenStartLine = getStartLineAndCharacterForNode(nextToken, sourceFile).line; - return lineAtPosition === nextTokenStartLine; + return lineAtPosition === nextTokenStartLine ? NextTokenKind.CloseBrace : NextTokenKind.Unknown; } - return false; + return NextTokenKind.Unknown; } - function getStartLineAndCharacterForNode(n: Node, sourceFile: SourceFile): LineAndCharacter { + function getStartLineAndCharacterForNode(n: Node, sourceFile: SourceFileLike): LineAndCharacter { return sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile)); } - export function childStartsOnTheSameLineWithElseInIfStatement(parent: Node, child: TextRangeWithKind, childStartLine: number, sourceFile: SourceFile): boolean { + export function childStartsOnTheSameLineWithElseInIfStatement(parent: Node, child: TextRangeWithKind, childStartLine: number, sourceFile: SourceFileLike): boolean { if (parent.kind === SyntaxKind.IfStatement && (parent).elseStatement === child) { const elseKeyword = findChildOfKind(parent, SyntaxKind.ElseKeyword, sourceFile); Debug.assert(elseKeyword !== undefined); @@ -261,15 +280,15 @@ namespace ts.formatting { return false; } - function getContainingList(node: Node, sourceFile: SourceFile): NodeArray { + function getListIfStartEndIsInListRange(list: NodeArray, start: number, end: number) { + return list && rangeContainsStartEnd(list, start, end) ? list : undefined; + } + + export function getContainingList(node: Node, sourceFile: SourceFile): NodeArray { if (node.parent) { switch (node.parent.kind) { case SyntaxKind.TypeReference: - if ((node.parent).typeArguments && - rangeContainsStartEnd((node.parent).typeArguments, node.getStart(sourceFile), node.getEnd())) { - return (node.parent).typeArguments; - } - break; + return getListIfStartEndIsInListRange((node.parent).typeArguments, node.getStart(sourceFile), node.getEnd()); case SyntaxKind.ObjectLiteralExpression: return (node.parent).properties; case SyntaxKind.ArrayLiteralExpression: @@ -280,30 +299,26 @@ namespace ts.formatting { case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: case SyntaxKind.CallSignature: + case SyntaxKind.Constructor: + case SyntaxKind.ConstructorType: case SyntaxKind.ConstructSignature: { const start = node.getStart(sourceFile); - if ((node.parent).typeParameters && - rangeContainsStartEnd((node.parent).typeParameters, start, node.getEnd())) { - return (node.parent).typeParameters; - } - if (rangeContainsStartEnd((node.parent).parameters, start, node.getEnd())) { - return (node.parent).parameters; - } - break; + return getListIfStartEndIsInListRange((node.parent).typeParameters, start, node.getEnd()) || + getListIfStartEndIsInListRange((node.parent).parameters, start, node.getEnd()); } + case SyntaxKind.ClassDeclaration: + return getListIfStartEndIsInListRange((node.parent).typeParameters, node.getStart(sourceFile), node.getEnd()); case SyntaxKind.NewExpression: case SyntaxKind.CallExpression: { const start = node.getStart(sourceFile); - if ((node.parent).typeArguments && - rangeContainsStartEnd((node.parent).typeArguments, start, node.getEnd())) { - return (node.parent).typeArguments; - } - if ((node.parent).arguments && - rangeContainsStartEnd((node.parent).arguments, start, node.getEnd())) { - return (node.parent).arguments; - } - break; + return getListIfStartEndIsInListRange((node.parent).typeArguments, start, node.getEnd()) || + getListIfStartEndIsInListRange((node.parent).arguments, start, node.getEnd()); } + case SyntaxKind.VariableDeclarationList: + return getListIfStartEndIsInListRange((node.parent).declarations, node.getStart(sourceFile), node.getEnd()); + case SyntaxKind.NamedImports: + case SyntaxKind.NamedExports: + return getListIfStartEndIsInListRange((node.parent).elements, node.getStart(sourceFile), node.getEnd()); } } return undefined; @@ -400,7 +415,7 @@ namespace ts.formatting { value of 'character' for '$' is 3 value of 'column' for '$' is 6 (assuming that tab size is 4) */ - export function findFirstNonWhitespaceCharacterAndColumn(startPos: number, endPos: number, sourceFile: SourceFile, options: EditorSettings) { + export function findFirstNonWhitespaceCharacterAndColumn(startPos: number, endPos: number, sourceFile: SourceFileLike, options: EditorSettings) { let character = 0; let column = 0; for (let pos = startPos; pos < endPos; pos++) { @@ -421,7 +436,7 @@ namespace ts.formatting { return { column, character }; } - export function findFirstNonWhitespaceColumn(startPos: number, endPos: number, sourceFile: SourceFile, options: EditorSettings): number { + export function findFirstNonWhitespaceColumn(startPos: number, endPos: number, sourceFile: SourceFileLike, options: EditorSettings): number { return findFirstNonWhitespaceCharacterAndColumn(startPos, endPos, sourceFile, options).column; } diff --git a/src/services/services.ts b/src/services/services.ts index f122e39bcc..beb52f7011 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -24,6 +24,7 @@ /// /// /// +/// /// /// @@ -63,7 +64,7 @@ namespace ts { return getSourceFileOfNode(this); } - public getStart(sourceFile?: SourceFile, includeJsDocComment?: boolean): number { + public getStart(sourceFile?: SourceFileLike, includeJsDocComment?: boolean): number { return getTokenPosOfNode(this, sourceFile, includeJsDocComment); } @@ -129,7 +130,7 @@ namespace ts { return list; } - private createChildren(sourceFile?: SourceFile) { + private createChildren(sourceFile?: SourceFileLike) { let children: Node[]; if (this.kind >= SyntaxKind.FirstNode) { scanner.setText((sourceFile || this.getSourceFile()).text); @@ -182,7 +183,7 @@ namespace ts { return this._children[index]; } - public getChildren(sourceFile?: SourceFile): Node[] { + public getChildren(sourceFile?: SourceFileLike): Node[] { if (!this._children) this.createChildren(sourceFile); return this._children; } @@ -231,7 +232,7 @@ namespace ts { return getSourceFileOfNode(this); } - public getStart(sourceFile?: SourceFile, includeJsDocComment?: boolean): number { + public getStart(sourceFile?: SourceFileLike, includeJsDocComment?: boolean): number { return getTokenPosOfNode(this, sourceFile, includeJsDocComment); } @@ -1682,7 +1683,7 @@ namespace ts { return []; } - function getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[]): CodeAction[] { + function getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[] { synchronizeHostData(); const sourceFile = getValidSourceFile(fileName); const span = { start, length: end - start }; @@ -1700,7 +1701,8 @@ namespace ts { program: program, newLineCharacter: newLineChar, host: host, - cancellationToken: cancellationToken + cancellationToken: cancellationToken, + rulesProvider: getRuleProvider(formatOptions) }; const fixes = codefix.getFixes(context); diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts new file mode 100644 index 0000000000..5c345e6e4e --- /dev/null +++ b/src/services/textChanges.ts @@ -0,0 +1,475 @@ +/* @internal */ +namespace ts.textChanges { + + /** + * Currently for simplicity we store recovered positions on the node itself. + * It can be changed to side-table later if we decide that current design is too invasive. + */ + function getPos(n: TextRange) { + return (n)["__pos"]; + } + + function setPos(n: TextRange, pos: number) { + (n)["__pos"] = pos; + } + + function getEnd(n: TextRange) { + return (n)["__end"]; + } + + function setEnd(n: TextRange, end: number) { + (n)["__end"] = end; + } + + export interface ConfigurableStart { + useNonAdjustedStartPosition?: boolean; + } + export interface ConfigurableEnd { + useNonAdjustedEndPosition?: boolean; + } + + /** + * Usually node.pos points to a position immediately after the previous token. + * If this position is used as a beginning of the span to remove - it might lead to removing the trailing trivia of the previous node, i.e: + * const x; // this is x + * ^ - pos for the next variable declaration will point here + * const y; // this is y + * ^ - end for previous variable declaration + * Usually leading trivia of the variable declaration 'y' should not include trailing trivia (whitespace, comment 'this is x' and newline) from the preceding + * variable declaration and trailing trivia for 'y' should include (whitespace, comment 'this is y', newline). + * By default when removing nodes we adjust start and end positions to respect specification of the trivia above. + * If pos\end should be interpreted literally 'useNonAdjustedStartPosition' or 'useNonAdjustedEndPosition' should be set to true + */ + export type ConfigurableStartEnd = ConfigurableStart & ConfigurableEnd; + + export interface InsertNodeOptions { + /** + * Set this value to true to make sure that node text of newly inserted node ends with new line + */ + insertTrailingNewLine?: boolean; + /** + * Set this value to true to make sure that node text of newly inserted node starts with new line + */ + insertLeadingNewLine?: boolean; + /** + * Text of inserted node will be formatted with this indentation, otherwise indentation will be inferred from the old node + */ + indentation?: number; + /** + * Text of inserted node will be formatted with this delta, otherwise delta will be inferred from the new node kind + */ + delta?: number; + } + + export type ChangeNodeOptions = ConfigurableStartEnd & InsertNodeOptions; + + interface Change { + readonly sourceFile: SourceFile; + readonly range: TextRange; + readonly oldNode?: Node; + readonly node?: Node; + readonly options?: ChangeNodeOptions; + } + + export function getAdjustedStartPosition(sourceFile: SourceFile, node: Node, options: ConfigurableStart, forDeleteOperation: boolean) { + if (options.useNonAdjustedStartPosition) { + return node.getFullStart(); + } + const fullStart = node.getFullStart(); + const start = node.getStart(sourceFile); + if (fullStart === start) { + return start; + } + const fullStartLine = getLineStartPositionForPosition(fullStart, sourceFile); + const startLine = getLineStartPositionForPosition(start, sourceFile); + if (startLine === fullStartLine) { + // full start and start of the node are on the same line + // a, b; + // ^ ^ + // | start + // fullstart + // when b is replaced - we usually want to keep the leading trvia + // when b is deleted - we delete it + return forDeleteOperation ? fullStart : start; + } + // get start position of the line following the line that contains fullstart position + let adjustedStartPosition = getStartPositionOfLine(getLineOfLocalPosition(sourceFile, fullStartLine) + 1, sourceFile); + // skip whitespaces/newlines + adjustedStartPosition = skipTrivia(sourceFile.text, adjustedStartPosition, /*stopAfterLineBreak*/ false, /*stopAtComments*/ true); + return getStartPositionOfLine(getLineOfLocalPosition(sourceFile, adjustedStartPosition), sourceFile); + } + + export function getAdjustedEndPosition(sourceFile: SourceFile, node: Node, options: ConfigurableEnd) { + if (options.useNonAdjustedEndPosition) { + return node.getEnd(); + } + const end = node.getEnd(); + const newEnd = skipTrivia(sourceFile.text, end, /*stopAfterLineBreak*/ true); + // check if last character before newPos is linebreak + // if yes - considered all skipped trivia to be trailing trivia of the node + return newEnd !== end && isLineBreak(sourceFile.text.charCodeAt(newEnd - 1)) + ? newEnd + : end; + } + + function isSeparator(node: Node, separator: Node): boolean { + return node.parent && (separator.kind === SyntaxKind.CommaToken || (separator.kind === SyntaxKind.SemicolonToken && node.parent.kind === SyntaxKind.ObjectLiteralExpression)); + } + + export class ChangeTracker { + private changes: Change[] = []; + private readonly newLineCharacter: string; + + public static fromCodeFixContext(context: CodeFixContext) { + return new ChangeTracker(context.newLineCharacter === "\n" ? NewLineKind.LineFeed : NewLineKind.CarriageReturnLineFeed, context.rulesProvider); + } + + constructor( + private readonly newLine: NewLineKind, + private readonly rulesProvider: formatting.RulesProvider, + private readonly validator?: (text: NonFormattedText) => void) { + this.newLineCharacter = getNewLineCharacter({ newLine }); + } + + public deleteNode(sourceFile: SourceFile, node: Node, options: ConfigurableStartEnd = {}) { + const startPosition = getAdjustedStartPosition(sourceFile, node, options, /*forDeleteOperation*/ true); + const endPosition = getAdjustedEndPosition(sourceFile, node, options); + this.changes.push({ sourceFile, options, range: { pos: startPosition, end: endPosition } }); + return this; + } + + public deleteRange(sourceFile: SourceFile, range: TextRange) { + this.changes.push({ sourceFile, range }); + return this; + } + + public deleteNodeRange(sourceFile: SourceFile, startNode: Node, endNode: Node, options: ConfigurableStartEnd = {}) { + const startPosition = getAdjustedStartPosition(sourceFile, startNode, options, /*forDeleteOperation*/ true); + const endPosition = getAdjustedEndPosition(sourceFile, endNode, options); + this.changes.push({ sourceFile, options, range: { pos: startPosition, end: endPosition } }); + return this; + } + + public deleteNodeInList(sourceFile: SourceFile, node: Node) { + const containingList = formatting.SmartIndenter.getContainingList(node, sourceFile); + if (!containingList) { + return; + } + const index = containingList.indexOf(node); + if (index < 0) { + return this; + } + if (containingList.length === 1) { + this.deleteNode(sourceFile, node); + return this; + } + if (index !== containingList.length - 1) { + const nextToken = getTokenAtPosition(sourceFile, node.end); + if (nextToken && isSeparator(node, nextToken)) { + // find first non-whitespace position in the leading trivia of the node + const startPosition = skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, node, {}, /*forDeleteOperation*/ true), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true); + const nextElement = containingList[index + 1]; + /// find first non-whitespace position in the leading trivia of the next node + const endPosition = skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, nextElement, {}, /*forDeleteOperation*/ true), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true); + // shift next node so its first non-whitespace position will be moved to the first non-whitespace position of the deleted node + this.deleteRange(sourceFile, { pos: startPosition, end: endPosition }); + } + } + else { + const previousToken = getTokenAtPosition(sourceFile, containingList[index - 1].end); + if (previousToken && isSeparator(node, previousToken)) { + this.deleteNodeRange(sourceFile, previousToken, node); + } + } + return this; + } + + public replaceRange(sourceFile: SourceFile, range: TextRange, newNode: Node, options: InsertNodeOptions = {}) { + this.changes.push({ sourceFile, range, options, node: newNode }); + return this; + } + + public replaceNode(sourceFile: SourceFile, oldNode: Node, newNode: Node, options: ChangeNodeOptions = {}) { + const startPosition = getAdjustedStartPosition(sourceFile, oldNode, options, /*forDeleteOperation*/ false); + const endPosition = getAdjustedEndPosition(sourceFile, oldNode, options); + this.changes.push({ sourceFile, options, oldNode, node: newNode, range: { pos: startPosition, end: endPosition } }); + return this; + } + + public replaceNodeRange(sourceFile: SourceFile, startNode: Node, endNode: Node, newNode: Node, options: ChangeNodeOptions = {}) { + const startPosition = getAdjustedStartPosition(sourceFile, startNode, options, /*forDeleteOperation*/ false); + const endPosition = getAdjustedEndPosition(sourceFile, endNode, options); + this.changes.push({ sourceFile, options, oldNode: startNode, node: newNode, range: { pos: startPosition, end: endPosition } }); + return this; + } + + public insertNodeAt(sourceFile: SourceFile, pos: number, newNode: Node, options: InsertNodeOptions = {}) { + this.changes.push({ sourceFile, options, node: newNode, range: { pos: pos, end: pos } }); + return this; + } + + public insertNodeBefore(sourceFile: SourceFile, before: Node, newNode: Node, options: InsertNodeOptions & ConfigurableStart = {}) { + const startPosition = getAdjustedStartPosition(sourceFile, before, options, /*forDeleteOperation*/ false); + this.changes.push({ sourceFile, options, oldNode: before, node: newNode, range: { pos: startPosition, end: startPosition } }); + return this; + } + + public insertNodeAfter(sourceFile: SourceFile, after: Node, newNode: Node, options: InsertNodeOptions & ConfigurableEnd = {}) { + const endPosition = getAdjustedEndPosition(sourceFile, after, options); + this.changes.push({ sourceFile, options, oldNode: after, node: newNode, range: { pos: endPosition, end: endPosition } }); + return this; + } + + public getChanges(): FileTextChanges[] { + const changesPerFile = createFileMap(); + // group changes per file + for (const c of this.changes) { + let changesInFile = changesPerFile.get(c.sourceFile.path); + if (!changesInFile) { + changesPerFile.set(c.sourceFile.path, changesInFile = []); + }; + changesInFile.push(c); + } + // convert changes + const fileChangesList: FileTextChanges[] = []; + changesPerFile.forEachValue(path => { + const changesInFile = changesPerFile.get(path); + const sourceFile = changesInFile[0].sourceFile; + ChangeTracker.normalize(changesInFile); + + const fileTextChanges: FileTextChanges = { fileName: sourceFile.fileName, textChanges: [] }; + for (const c of changesInFile) { + fileTextChanges.textChanges.push({ + span: this.computeSpan(c, sourceFile), + newText: this.computeNewText(c, sourceFile) + }); + } + fileChangesList.push(fileTextChanges); + }); + + return fileChangesList; + } + + private computeSpan(change: Change, _sourceFile: SourceFile): TextSpan { + return createTextSpanFromBounds(change.range.pos, change.range.end); + } + + private computeNewText(change: Change, sourceFile: SourceFile): string { + if (!change.node) { + // deletion case + return ""; + } + const options = change.options || {}; + const nonFormattedText = getNonformattedText(change.node, sourceFile, this.newLine); + if (this.validator) { + this.validator(nonFormattedText); + } + + const formatOptions = this.rulesProvider.getFormatOptions(); + const pos = change.range.pos; + const posStartsLine = getLineStartPositionForPosition(pos, sourceFile) === pos; + + const initialIndentation = + change.options.indentation !== undefined + ? change.options.indentation + : change.oldNode + ? formatting.SmartIndenter.getIndentation(change.range.pos, sourceFile, formatOptions, posStartsLine || change.options.insertLeadingNewLine) + : 0; + const delta = + change.options.delta !== undefined + ? change.options.delta + : formatting.SmartIndenter.shouldIndentChildNode(change.node) + ? formatOptions.indentSize + : 0; + + let text = applyFormatting(nonFormattedText, sourceFile, initialIndentation, delta, this.rulesProvider); + // strip initial indentation (spaces or tabs) if text will be inserted in the middle of the line + text = posStartsLine ? text : text.replace(/^\s+/, ""); + + if (options.insertLeadingNewLine) { + text = this.newLineCharacter + text; + } + if (options.insertTrailingNewLine) { + text = text + this.newLineCharacter; + } + return text; + } + + private static normalize(changes: Change[]) { + // order changes by start position + changes.sort((a, b) => a.range.pos - b.range.pos); + // verify that end position of the change is less than start position of the next change + for (let i = 0; i < changes.length - 2; i++) { + Debug.assert(changes[i].range.end <= changes[i + 1].range.pos); + } + } + } + + export interface NonFormattedText { + readonly text: string; + readonly node: Node; + } + + export function getNonformattedText(node: Node, sourceFile: SourceFile, newLine: NewLineKind): NonFormattedText { + const options = { newLine, target: sourceFile.languageVersion }; + const writer = new Writer(getNewLineCharacter(options)); + const printer = createPrinter(options, writer); + printer.writeNode(EmitHint.Unspecified, node, sourceFile, writer); + return { text: writer.getText(), node: assignPositionsToNode(node) }; + } + + export function applyFormatting(nonFormattedText: NonFormattedText, sourceFile: SourceFile, initialIndentation: number, delta: number, rulesProvider: formatting.RulesProvider) { + const lineMap = computeLineStarts(nonFormattedText.text); + const file: SourceFileLike = { + text: nonFormattedText.text, + lineMap, + getLineAndCharacterOfPosition: pos => computeLineAndCharacterOfPosition(lineMap, pos) + }; + const changes = formatting.formatNode(nonFormattedText.node, file, sourceFile.languageVariant, initialIndentation, delta, rulesProvider); + return applyChanges(nonFormattedText.text, changes); + } + + export function applyChanges(text: string, changes: TextChange[]): string { + for (let i = changes.length - 1; i >= 0; i--) { + const change = changes[i]; + text = `${text.substring(0, change.span.start)}${change.newText}${text.substring(textSpanEnd(change.span))}`; + } + return text; + } + + function isTrivia(s: string) { + return skipTrivia(s, 0) === s.length; + } + + const nullTransformationContext: TransformationContext = { + enableEmitNotification: noop, + enableSubstitution: noop, + endLexicalEnvironment: () => undefined, + getCompilerOptions: notImplemented, + getEmitHost: notImplemented, + getEmitResolver: notImplemented, + hoistFunctionDeclaration: noop, + hoistVariableDeclaration: noop, + isEmitNotificationEnabled: notImplemented, + isSubstitutionEnabled: notImplemented, + onEmitNode: noop, + onSubstituteNode: notImplemented, + readEmitHelpers: notImplemented, + requestEmitHelper: noop, + resumeLexicalEnvironment: noop, + startLexicalEnvironment: noop, + suspendLexicalEnvironment: noop + }; + + function assignPositionsToNode(node: Node): Node { + const visited = visitEachChild(node, assignPositionsToNode, nullTransformationContext, assignPositionsToNodeArray); + // create proxy node for non synthesized nodes + const newNode = nodeIsSynthesized(visited) + ? visited + : (Proxy.prototype = visited, new (Proxy)()); + newNode.pos = getPos(node); + newNode.end = getEnd(node); + return newNode; + + function Proxy() { } + } + + function assignPositionsToNodeArray(nodes: NodeArray, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number) { + const visited = visitNodes(nodes, visitor, test, start, count); + if (!visited) { + return visited; + } + // clone nodearray if necessary + const nodeArray = visited === nodes ? createNodeArray(visited) : visited; + nodeArray.pos = getPos(nodes); + nodeArray.end = getEnd(nodes); + return nodeArray; + } + + class Writer implements EmitTextWriter, PrintHandlers { + private lastNonTriviaPosition = 0; + private readonly writer: EmitTextWriter; + + public readonly onEmitNode: PrintHandlers["onEmitNode"]; + public readonly onBeforeEmitNodeArray: PrintHandlers["onBeforeEmitNodeArray"]; + public readonly onAfterEmitNodeArray: PrintHandlers["onAfterEmitNodeArray"]; + + constructor(newLine: string) { + this.writer = createTextWriter(newLine); + this.onEmitNode = (hint, node, printCallback) => { + setPos(node, this.lastNonTriviaPosition); + printCallback(hint, node); + setEnd(node, this.lastNonTriviaPosition); + }; + this.onBeforeEmitNodeArray = nodes => { + if (nodes) { + setPos(nodes, this.lastNonTriviaPosition); + } + }; + this.onAfterEmitNodeArray = nodes => { + if (nodes) { + setEnd(nodes, this.lastNonTriviaPosition); + } + }; + } + + private setLastNonTriviaPosition(s: string, force: boolean) { + if (force || !isTrivia(s)) { + this.lastNonTriviaPosition = this.writer.getTextPos(); + let i = 0; + while (isWhiteSpace(s.charCodeAt(s.length - i - 1))) { + i++; + } + // trim trailing whitespaces + this.lastNonTriviaPosition -= i; + } + } + + write(s: string): void { + this.writer.write(s); + this.setLastNonTriviaPosition(s, /*force*/ false); + } + writeTextOfNode(text: string, node: Node): void { + this.writer.writeTextOfNode(text, node); + } + writeLine(): void { + this.writer.writeLine(); + } + increaseIndent(): void { + this.writer.increaseIndent(); + } + decreaseIndent(): void { + this.writer.decreaseIndent(); + } + getText(): string { + return this.writer.getText(); + } + rawWrite(s: string): void { + this.writer.rawWrite(s); + this.setLastNonTriviaPosition(s, /*force*/ false); + } + writeLiteral(s: string): void { + this.writer.writeLiteral(s); + this.setLastNonTriviaPosition(s, /*force*/ true); + } + getTextPos(): number { + return this.writer.getTextPos(); + } + getLine(): number { + return this.writer.getLine(); + } + getColumn(): number { + return this.writer.getColumn(); + } + getIndent(): number { + return this.writer.getIndent(); + } + isAtStartOfLine(): boolean { + return this.writer.isAtStartOfLine(); + } + reset(): void { + this.writer.reset(); + this.lastNonTriviaPosition = 0; + } + } +} \ No newline at end of file diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index ae2150d981..f5cd2cd475 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -62,6 +62,7 @@ "shims.ts", "signatureHelp.ts", "symbolDisplay.ts", + "textChanges.ts", "formatting/formatting.ts", "formatting/formattingContext.ts", "formatting/formattingRequestKind.ts", diff --git a/src/services/types.ts b/src/services/types.ts index c7852db6d6..149bb4340d 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -4,7 +4,11 @@ namespace ts { getChildCount(sourceFile?: SourceFile): number; getChildAt(index: number, sourceFile?: SourceFile): Node; getChildren(sourceFile?: SourceFile): Node[]; + /* @internal */ + getChildren(sourceFile?: SourceFileLike): Node[]; getStart(sourceFile?: SourceFile, includeJsDocComment?: boolean): number; + /* @internal */ + getStart(sourceFile?: SourceFileLike, includeJsDocComment?: boolean): number; getFullStart(): number; getEnd(): number; getWidth(sourceFile?: SourceFile): number; @@ -59,6 +63,10 @@ namespace ts { update(newText: string, textChangeRange: TextChangeRange): SourceFile; } + export interface SourceFileLike { + getLineAndCharacterOfPosition(pos: number): LineAndCharacter; + } + /** * Represents an immutable snapshot of a script at a specified time.Once acquired, the * snapshot is observably immutable. i.e. the same calls with the same parameters will return @@ -248,7 +256,7 @@ namespace ts { isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean; - getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[]): CodeAction[]; + getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[]; getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput; diff --git a/src/services/utilities.ts b/src/services/utilities.ts index a4f574b9c2..0ffd5d27bc 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -394,8 +394,8 @@ namespace ts { list: Node; } - export function getLineStartPositionForPosition(position: number, sourceFile: SourceFile): number { - const lineStarts = sourceFile.getLineStarts(); + export function getLineStartPositionForPosition(position: number, sourceFile: SourceFileLike): number { + const lineStarts = getLineStarts(sourceFile); const line = sourceFile.getLineAndCharacterOfPosition(position).line; return lineStarts[line]; } @@ -604,7 +604,7 @@ namespace ts { return !!findChildOfKind(n, kind, sourceFile); } - export function findChildOfKind(n: Node, kind: SyntaxKind, sourceFile?: SourceFile): Node | undefined { + export function findChildOfKind(n: Node, kind: SyntaxKind, sourceFile?: SourceFileLike): Node | undefined { return forEach(n.getChildren(sourceFile), c => c.kind === kind && c); } @@ -1003,10 +1003,6 @@ namespace ts { return undefined; } - export function isToken(n: Node): boolean { - return n.kind >= SyntaxKind.FirstToken && n.kind <= SyntaxKind.LastToken; - } - export function isWord(kind: SyntaxKind): boolean { return kind === SyntaxKind.Identifier || isKeyword(kind); } @@ -1384,8 +1380,8 @@ namespace ts { }; } - export function getOpenBraceEnd(constructor: ConstructorDeclaration, sourceFile: SourceFile) { + export function getOpenBrace(constructor: ConstructorDeclaration, sourceFile: SourceFile) { // First token is the open curly, this is where we want to put the 'super' call. - return constructor.body.getFirstToken(sourceFile).getEnd(); + return constructor.body.getFirstToken(sourceFile); } } diff --git a/tests/baselines/reference/textChanges/deleteNode1.js b/tests/baselines/reference/textChanges/deleteNode1.js new file mode 100644 index 0000000000..c73c0eaf9f --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNode1.js @@ -0,0 +1,13 @@ +===ORIGINAL=== + +var x = 1; // some comment - 1 +/** + * comment 2 + */ +var y = 2; // comment 3 +var z = 3; // comment 4 + +===MODIFIED=== + +var x = 1; // some comment - 1 +var z = 3; // comment 4 diff --git a/tests/baselines/reference/textChanges/deleteNode2.js b/tests/baselines/reference/textChanges/deleteNode2.js new file mode 100644 index 0000000000..828a9b5b8f --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNode2.js @@ -0,0 +1,12 @@ +===ORIGINAL=== + +var x = 1; // some comment - 1 +/** + * comment 2 + */ +var y = 2; // comment 3 +var z = 3; // comment 4 + +===MODIFIED=== + +var x = 1;var z = 3; // comment 4 diff --git a/tests/baselines/reference/textChanges/deleteNode3.js b/tests/baselines/reference/textChanges/deleteNode3.js new file mode 100644 index 0000000000..acb26c7daa --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNode3.js @@ -0,0 +1,14 @@ +===ORIGINAL=== + +var x = 1; // some comment - 1 +/** + * comment 2 + */ +var y = 2; // comment 3 +var z = 3; // comment 4 + +===MODIFIED=== + +var x = 1; // some comment - 1 + // comment 3 +var z = 3; // comment 4 diff --git a/tests/baselines/reference/textChanges/deleteNode4.js b/tests/baselines/reference/textChanges/deleteNode4.js new file mode 100644 index 0000000000..b6edb25bc5 --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNode4.js @@ -0,0 +1,13 @@ +===ORIGINAL=== + +var x = 1; // some comment - 1 +/** + * comment 2 + */ +var y = 2; // comment 3 +var z = 3; // comment 4 + +===MODIFIED=== + +var x = 1; // comment 3 +var z = 3; // comment 4 diff --git a/tests/baselines/reference/textChanges/deleteNode5.js b/tests/baselines/reference/textChanges/deleteNode5.js new file mode 100644 index 0000000000..6f896535f0 --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNode5.js @@ -0,0 +1,16 @@ +===ORIGINAL=== + +var x = 1; // some comment - 1 +/** + * comment 2 + */ +var y = 2; // comment 3 +var z = 3; // comment 4 + +===MODIFIED=== + +/** + * comment 2 + */ +var y = 2; // comment 3 +var z = 3; // comment 4 diff --git a/tests/baselines/reference/textChanges/deleteNodeInList1.js b/tests/baselines/reference/textChanges/deleteNodeInList1.js new file mode 100644 index 0000000000..b603913566 --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeInList1.js @@ -0,0 +1,4 @@ +===ORIGINAL=== +var a = 1, b = 2, c = 3; +===MODIFIED=== +var b = 2, c = 3; \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/deleteNodeInList10.js b/tests/baselines/reference/textChanges/deleteNodeInList10.js new file mode 100644 index 0000000000..46da605a71 --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeInList10.js @@ -0,0 +1,10 @@ +===ORIGINAL=== + +function foo(a: number,b: string,c = true) { + return 1; +} +===MODIFIED=== + +function foo(b: string,c = true) { + return 1; +} \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/deleteNodeInList11.js b/tests/baselines/reference/textChanges/deleteNodeInList11.js new file mode 100644 index 0000000000..f5aa666e52 --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeInList11.js @@ -0,0 +1,10 @@ +===ORIGINAL=== + +function foo(a: number,b: string,c = true) { + return 1; +} +===MODIFIED=== + +function foo(a: number,c = true) { + return 1; +} \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/deleteNodeInList12.js b/tests/baselines/reference/textChanges/deleteNodeInList12.js new file mode 100644 index 0000000000..db05ef06db --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeInList12.js @@ -0,0 +1,10 @@ +===ORIGINAL=== + +function foo(a: number,b: string,c = true) { + return 1; +} +===MODIFIED=== + +function foo(a: number,b: string) { + return 1; +} \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/deleteNodeInList13.js b/tests/baselines/reference/textChanges/deleteNodeInList13.js new file mode 100644 index 0000000000..599d3a31d4 --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeInList13.js @@ -0,0 +1,15 @@ +===ORIGINAL=== + +function foo( + a: number, + b: string, + c = true) { + return 1; +} +===MODIFIED=== + +function foo( + b: string, + c = true) { + return 1; +} \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/deleteNodeInList14.js b/tests/baselines/reference/textChanges/deleteNodeInList14.js new file mode 100644 index 0000000000..da3596b38b --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeInList14.js @@ -0,0 +1,15 @@ +===ORIGINAL=== + +function foo( + a: number, + b: string, + c = true) { + return 1; +} +===MODIFIED=== + +function foo( + a: number, + c = true) { + return 1; +} \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/deleteNodeInList15.js b/tests/baselines/reference/textChanges/deleteNodeInList15.js new file mode 100644 index 0000000000..02f649dabd --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeInList15.js @@ -0,0 +1,15 @@ +===ORIGINAL=== + +function foo( + a: number, + b: string, + c = true) { + return 1; +} +===MODIFIED=== + +function foo( + a: number, + b: string) { + return 1; +} \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/deleteNodeInList1_1.js b/tests/baselines/reference/textChanges/deleteNodeInList1_1.js new file mode 100644 index 0000000000..87709601c4 --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeInList1_1.js @@ -0,0 +1,4 @@ +===ORIGINAL=== +var a = 1,b = 2,c = 3; +===MODIFIED=== +var b = 2,c = 3; \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/deleteNodeInList2.js b/tests/baselines/reference/textChanges/deleteNodeInList2.js new file mode 100644 index 0000000000..18e4a0cd30 --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeInList2.js @@ -0,0 +1,4 @@ +===ORIGINAL=== +var a = 1, b = 2, c = 3; +===MODIFIED=== +var a = 1, c = 3; \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/deleteNodeInList2_1.js b/tests/baselines/reference/textChanges/deleteNodeInList2_1.js new file mode 100644 index 0000000000..b4098a8930 --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeInList2_1.js @@ -0,0 +1,4 @@ +===ORIGINAL=== +var a = 1,b = 2,c = 3; +===MODIFIED=== +var a = 1,c = 3; \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/deleteNodeInList3.js b/tests/baselines/reference/textChanges/deleteNodeInList3.js new file mode 100644 index 0000000000..1c6ff4aa29 --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeInList3.js @@ -0,0 +1,4 @@ +===ORIGINAL=== +var a = 1, b = 2, c = 3; +===MODIFIED=== +var a = 1, b = 2; \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/deleteNodeInList3_1.js b/tests/baselines/reference/textChanges/deleteNodeInList3_1.js new file mode 100644 index 0000000000..ead2a1a42f --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeInList3_1.js @@ -0,0 +1,4 @@ +===ORIGINAL=== +var a = 1,b = 2,c = 3; +===MODIFIED=== +var a = 1,b = 2; \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/deleteNodeInList4.js b/tests/baselines/reference/textChanges/deleteNodeInList4.js new file mode 100644 index 0000000000..61bdf9159c --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeInList4.js @@ -0,0 +1,13 @@ +===ORIGINAL=== + +namespace M { + var a = 1, + b = 2, + c = 3; +} +===MODIFIED=== + +namespace M { + var b = 2, + c = 3; +} \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/deleteNodeInList4_1.js b/tests/baselines/reference/textChanges/deleteNodeInList4_1.js new file mode 100644 index 0000000000..19ff5475d1 --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeInList4_1.js @@ -0,0 +1,17 @@ +===ORIGINAL=== + +namespace M { + var a = 1, // comment 1 + // comment 2 + b = 2, // comment 3 + // comment 4 + c = 3; // comment 5 +} +===MODIFIED=== + +namespace M { + var // comment 2 + b = 2, // comment 3 + // comment 4 + c = 3; // comment 5 +} \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/deleteNodeInList5.js b/tests/baselines/reference/textChanges/deleteNodeInList5.js new file mode 100644 index 0000000000..0ed65877d2 --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeInList5.js @@ -0,0 +1,13 @@ +===ORIGINAL=== + +namespace M { + var a = 1, + b = 2, + c = 3; +} +===MODIFIED=== + +namespace M { + var a = 1, + c = 3; +} \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/deleteNodeInList5_1.js b/tests/baselines/reference/textChanges/deleteNodeInList5_1.js new file mode 100644 index 0000000000..224b92481d --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeInList5_1.js @@ -0,0 +1,16 @@ +===ORIGINAL=== + +namespace M { + var a = 1, // comment 1 + // comment 2 + b = 2, // comment 3 + // comment 4 + c = 3; // comment 5 +} +===MODIFIED=== + +namespace M { + var a = 1, // comment 1 + // comment 4 + c = 3; // comment 5 +} \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/deleteNodeInList6.js b/tests/baselines/reference/textChanges/deleteNodeInList6.js new file mode 100644 index 0000000000..4093329023 --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeInList6.js @@ -0,0 +1,13 @@ +===ORIGINAL=== + +namespace M { + var a = 1, + b = 2, + c = 3; +} +===MODIFIED=== + +namespace M { + var a = 1, + b = 2; +} \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/deleteNodeInList6_1.js b/tests/baselines/reference/textChanges/deleteNodeInList6_1.js new file mode 100644 index 0000000000..6acc20aa82 --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeInList6_1.js @@ -0,0 +1,16 @@ +===ORIGINAL=== + +namespace M { + var a = 1, // comment 1 + // comment 2 + b = 2, // comment 3 + // comment 4 + c = 3; // comment 5 +} +===MODIFIED=== + +namespace M { + var a = 1, // comment 1 + // comment 2 + b = 2; // comment 5 +} \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/deleteNodeInList7.js b/tests/baselines/reference/textChanges/deleteNodeInList7.js new file mode 100644 index 0000000000..564ff3f86a --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeInList7.js @@ -0,0 +1,10 @@ +===ORIGINAL=== + +function foo(a: number, b: string, c = true) { + return 1; +} +===MODIFIED=== + +function foo(b: string, c = true) { + return 1; +} \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/deleteNodeInList8.js b/tests/baselines/reference/textChanges/deleteNodeInList8.js new file mode 100644 index 0000000000..b3a0a0f4c4 --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeInList8.js @@ -0,0 +1,10 @@ +===ORIGINAL=== + +function foo(a: number, b: string, c = true) { + return 1; +} +===MODIFIED=== + +function foo(a: number, c = true) { + return 1; +} \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/deleteNodeInList9.js b/tests/baselines/reference/textChanges/deleteNodeInList9.js new file mode 100644 index 0000000000..96878a6086 --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeInList9.js @@ -0,0 +1,10 @@ +===ORIGINAL=== + +function foo(a: number, b: string, c = true) { + return 1; +} +===MODIFIED=== + +function foo(a: number, b: string) { + return 1; +} \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/deleteNodeRange1.js b/tests/baselines/reference/textChanges/deleteNodeRange1.js new file mode 100644 index 0000000000..f9fa45ebb1 --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeRange1.js @@ -0,0 +1,16 @@ +===ORIGINAL=== + +// comment 1 +var x = 1; // comment 2 +// comment 3 +var y = 2; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 + +===MODIFIED=== + +// comment 1 +var x = 1; // comment 2 +// comment 6 +var a = 4; // comment 7 diff --git a/tests/baselines/reference/textChanges/deleteNodeRange2.js b/tests/baselines/reference/textChanges/deleteNodeRange2.js new file mode 100644 index 0000000000..aacea6ff5e --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeRange2.js @@ -0,0 +1,15 @@ +===ORIGINAL=== + +// comment 1 +var x = 1; // comment 2 +// comment 3 +var y = 2; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 + +===MODIFIED=== + +// comment 1 +var x = 1;// comment 6 +var a = 4; // comment 7 diff --git a/tests/baselines/reference/textChanges/deleteNodeRange3.js b/tests/baselines/reference/textChanges/deleteNodeRange3.js new file mode 100644 index 0000000000..bb2bb36ca2 --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeRange3.js @@ -0,0 +1,17 @@ +===ORIGINAL=== + +// comment 1 +var x = 1; // comment 2 +// comment 3 +var y = 2; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 + +===MODIFIED=== + +// comment 1 +var x = 1; // comment 2 + // comment 5 +// comment 6 +var a = 4; // comment 7 diff --git a/tests/baselines/reference/textChanges/deleteNodeRange4.js b/tests/baselines/reference/textChanges/deleteNodeRange4.js new file mode 100644 index 0000000000..3e9ad960b1 --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeRange4.js @@ -0,0 +1,16 @@ +===ORIGINAL=== + +// comment 1 +var x = 1; // comment 2 +// comment 3 +var y = 2; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 + +===MODIFIED=== + +// comment 1 +var x = 1; // comment 5 +// comment 6 +var a = 4; // comment 7 diff --git a/tests/baselines/reference/textChanges/deleteRange1.js b/tests/baselines/reference/textChanges/deleteRange1.js new file mode 100644 index 0000000000..362e678452 --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteRange1.js @@ -0,0 +1,15 @@ +===ORIGINAL=== + +function foo() { + return 1; +} + +function bar() { + return 2; +} + +===MODIFIED=== + +function bar() { + return 2; +} diff --git a/tests/baselines/reference/textChanges/extractMethodLike.js b/tests/baselines/reference/textChanges/extractMethodLike.js new file mode 100644 index 0000000000..fa1d625dc4 --- /dev/null +++ b/tests/baselines/reference/textChanges/extractMethodLike.js @@ -0,0 +1,49 @@ +===ORIGINAL=== + +namespace M +{ + namespace M2 + { + function foo() { + // comment 1 + const x = 1; + + /** + * comment 2 line 1 + * comment 2 line 2 + */ + function f() { + return 100; + } + const y = 2; // comment 3 + return 1; + } + } +} +===MODIFIED=== + +namespace M +{ + function bar(): any + { + /** + * comment 2 line 1 + * comment 2 line 2 + */ + function f() + { + return 100; + } + const y = 2; // comment 3 + return 1; + } + namespace M2 + { + function foo() { + // comment 1 + const x = 1; + + return bar(); + } + } +} \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeAfter1.js b/tests/baselines/reference/textChanges/insertNodeAfter1.js new file mode 100644 index 0000000000..e6d7387f6b --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeAfter1.js @@ -0,0 +1,26 @@ +===ORIGINAL=== + +namespace M { + // comment 1 + var x = 1; // comment 2 + // comment 3 + var y; // comment 4 + var z = 3; // comment 5 + // comment 6 + var a = 4; // comment 7 +} +===MODIFIED=== + +namespace M { + // comment 1 + var x = 1; // comment 2 + // comment 3 + var y; // comment 4 + public class class1 implements interface1 + { + property1: boolean; + } + var z = 3; // comment 5 + // comment 6 + var a = 4; // comment 7 +} \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeAfter2.js b/tests/baselines/reference/textChanges/insertNodeAfter2.js new file mode 100644 index 0000000000..7c027e35b5 --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeAfter2.js @@ -0,0 +1,26 @@ +===ORIGINAL=== + +namespace M { + // comment 1 + var x = 1; // comment 2 + // comment 3 + var y; // comment 4 + var z = 3; // comment 5 + // comment 6 + var a = 4; // comment 7 +} +===MODIFIED=== + +namespace M { + // comment 1 + var x = 1; // comment 2 + // comment 3 + var y; // comment 4 + var z = 3; // comment 5 + // comment 6 + var a = 4; // comment 7 +} +public class class1 implements interface1 +{ + property1: boolean; +} \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeAfter3-block with newline.js b/tests/baselines/reference/textChanges/insertNodeAfter3-block with newline.js new file mode 100644 index 0000000000..41bfb72b57 --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeAfter3-block with newline.js @@ -0,0 +1,16 @@ +===ORIGINAL=== + +class A { + constructor() { + + } +} + +===MODIFIED=== + +class A { + constructor() { + super(); + + } +} diff --git a/tests/baselines/reference/textChanges/insertNodeAfter3.js b/tests/baselines/reference/textChanges/insertNodeAfter3.js new file mode 100644 index 0000000000..3765bbaf03 --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeAfter3.js @@ -0,0 +1,14 @@ +===ORIGINAL=== + +class A { + constructor() { + } +} + +===MODIFIED=== + +class A { + constructor() { + super(); + } +} diff --git a/tests/baselines/reference/textChanges/insertNodeAfter4.js b/tests/baselines/reference/textChanges/insertNodeAfter4.js new file mode 100644 index 0000000000..3ca51db498 --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeAfter4.js @@ -0,0 +1,16 @@ +===ORIGINAL=== + +class A { + constructor() { + var x = 1; + } +} + +===MODIFIED=== + +class A { + constructor() { + var x = 1; + super(); + } +} diff --git a/tests/baselines/reference/textChanges/insertNodeAt1.js b/tests/baselines/reference/textChanges/insertNodeAt1.js new file mode 100644 index 0000000000..9c7ac46f8a --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeAt1.js @@ -0,0 +1,22 @@ +===ORIGINAL=== + +// comment 1 +var x = 1; // comment 2 +// comment 3 +var y; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 +===MODIFIED=== + +// comment 1 +var x = 1; // comment 2 +// comment 3 +public class class1 implements interface1 +{ + property1: boolean; +} +var y; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeAt2.js b/tests/baselines/reference/textChanges/insertNodeAt2.js new file mode 100644 index 0000000000..81c3e2afc3 --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeAt2.js @@ -0,0 +1,20 @@ +===ORIGINAL=== + +// comment 1 +var x = 1; // comment 2 +// comment 3 +var y; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 +===MODIFIED=== + +// comment 1 +var x = 1; // comment 2 +// comment 3 +var yz1 = { + p1: 1 +}; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeBefore1.js b/tests/baselines/reference/textChanges/insertNodeBefore1.js new file mode 100644 index 0000000000..deebe10b69 --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeBefore1.js @@ -0,0 +1,26 @@ +===ORIGINAL=== + +namespace M { + // comment 1 + var x = 1; // comment 2 + // comment 3 + var y; // comment 4 + var z = 3; // comment 5 + // comment 6 + var a = 4; // comment 7 +} +===MODIFIED=== + +namespace M { + // comment 1 + var x = 1; // comment 2 + public class class1 implements interface1 + { + property1: boolean; + } + // comment 3 + var y; // comment 4 + var z = 3; // comment 5 + // comment 6 + var a = 4; // comment 7 +} \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeBefore2.js b/tests/baselines/reference/textChanges/insertNodeBefore2.js new file mode 100644 index 0000000000..1792cd5e69 --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeBefore2.js @@ -0,0 +1,26 @@ +===ORIGINAL=== + +namespace M { + // comment 1 + var x = 1; // comment 2 + // comment 3 + var y; // comment 4 + var z = 3; // comment 5 + // comment 6 + var a = 4; // comment 7 +} +===MODIFIED=== + +public class class1 implements interface1 +{ + property1: boolean; +} +namespace M { + // comment 1 + var x = 1; // comment 2 + // comment 3 + var y; // comment 4 + var z = 3; // comment 5 + // comment 6 + var a = 4; // comment 7 +} \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/replaceNode1.js b/tests/baselines/reference/textChanges/replaceNode1.js new file mode 100644 index 0000000000..8511d51038 --- /dev/null +++ b/tests/baselines/reference/textChanges/replaceNode1.js @@ -0,0 +1,20 @@ +===ORIGINAL=== + +// comment 1 +var x = 1; // comment 2 +// comment 3 +var y = 2; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 +===MODIFIED=== + +// comment 1 +var x = 1; // comment 2 +public class class1 implements interface1 +{ + property1: boolean; +} +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/replaceNode1NoLineBreakBefore.js b/tests/baselines/reference/textChanges/replaceNode1NoLineBreakBefore.js new file mode 100644 index 0000000000..44183d402a --- /dev/null +++ b/tests/baselines/reference/textChanges/replaceNode1NoLineBreakBefore.js @@ -0,0 +1,13 @@ +===ORIGINAL=== + +namespace A { + const x = 1, y = "2"; +} + +===MODIFIED=== + +namespace A { + const x = 1, z1 = { + p1: 1 + }; +} diff --git a/tests/baselines/reference/textChanges/replaceNode2.js b/tests/baselines/reference/textChanges/replaceNode2.js new file mode 100644 index 0000000000..66a17f7c91 --- /dev/null +++ b/tests/baselines/reference/textChanges/replaceNode2.js @@ -0,0 +1,20 @@ +===ORIGINAL=== + +// comment 1 +var x = 1; // comment 2 +// comment 3 +var y = 2; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 +===MODIFIED=== + +// comment 1 +var x = 1; +public class class1 implements interface1 +{ + property1: boolean; +} +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/replaceNode3.js b/tests/baselines/reference/textChanges/replaceNode3.js new file mode 100644 index 0000000000..9f321a9743 --- /dev/null +++ b/tests/baselines/reference/textChanges/replaceNode3.js @@ -0,0 +1,21 @@ +===ORIGINAL=== + +// comment 1 +var x = 1; // comment 2 +// comment 3 +var y = 2; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 +===MODIFIED=== + +// comment 1 +var x = 1; // comment 2 +public class class1 implements interface1 +{ + property1: boolean; +} + // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/replaceNode4.js b/tests/baselines/reference/textChanges/replaceNode4.js new file mode 100644 index 0000000000..e5bbf0e306 --- /dev/null +++ b/tests/baselines/reference/textChanges/replaceNode4.js @@ -0,0 +1,19 @@ +===ORIGINAL=== + +// comment 1 +var x = 1; // comment 2 +// comment 3 +var y = 2; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 +===MODIFIED=== + +// comment 1 +var x = 1;public class class1 implements interface1 +{ + property1: boolean; +} // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/replaceNode5.js b/tests/baselines/reference/textChanges/replaceNode5.js new file mode 100644 index 0000000000..ad3ec0ab0e --- /dev/null +++ b/tests/baselines/reference/textChanges/replaceNode5.js @@ -0,0 +1,19 @@ +===ORIGINAL=== + +// comment 1 +var x = 1; // comment 2 +// comment 3 +var y = 2; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 +===MODIFIED=== +public class class1 implements interface1 +{ + property1: boolean; +} // comment 2 +// comment 3 +var y = 2; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/replaceNodeRange1.js b/tests/baselines/reference/textChanges/replaceNodeRange1.js new file mode 100644 index 0000000000..5fc16960a8 --- /dev/null +++ b/tests/baselines/reference/textChanges/replaceNodeRange1.js @@ -0,0 +1,19 @@ +===ORIGINAL=== + +// comment 1 +var x = 1; // comment 2 +// comment 3 +var y = 2; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 +===MODIFIED=== + +// comment 1 +var x = 1; // comment 2 +public class class1 implements interface1 +{ + property1: boolean; +} +// comment 6 +var a = 4; // comment 7 \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/replaceNodeRange2.js b/tests/baselines/reference/textChanges/replaceNodeRange2.js new file mode 100644 index 0000000000..e8f9506d60 --- /dev/null +++ b/tests/baselines/reference/textChanges/replaceNodeRange2.js @@ -0,0 +1,19 @@ +===ORIGINAL=== + +// comment 1 +var x = 1; // comment 2 +// comment 3 +var y = 2; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 +===MODIFIED=== + +// comment 1 +var x = 1; +public class class1 implements interface1 +{ + property1: boolean; +} +// comment 6 +var a = 4; // comment 7 \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/replaceNodeRange3.js b/tests/baselines/reference/textChanges/replaceNodeRange3.js new file mode 100644 index 0000000000..a20dddc53f --- /dev/null +++ b/tests/baselines/reference/textChanges/replaceNodeRange3.js @@ -0,0 +1,20 @@ +===ORIGINAL=== + +// comment 1 +var x = 1; // comment 2 +// comment 3 +var y = 2; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 +===MODIFIED=== + +// comment 1 +var x = 1; // comment 2 +public class class1 implements interface1 +{ + property1: boolean; +} + // comment 5 +// comment 6 +var a = 4; // comment 7 \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/replaceNodeRange4.js b/tests/baselines/reference/textChanges/replaceNodeRange4.js new file mode 100644 index 0000000000..ad50a1f01f --- /dev/null +++ b/tests/baselines/reference/textChanges/replaceNodeRange4.js @@ -0,0 +1,18 @@ +===ORIGINAL=== + +// comment 1 +var x = 1; // comment 2 +// comment 3 +var y = 2; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 +===MODIFIED=== + +// comment 1 +var x = 1;public class class1 implements interface1 +{ + property1: boolean; +} // comment 5 +// comment 6 +var a = 4; // comment 7 \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/replaceRange.js b/tests/baselines/reference/textChanges/replaceRange.js new file mode 100644 index 0000000000..8cb8328616 --- /dev/null +++ b/tests/baselines/reference/textChanges/replaceRange.js @@ -0,0 +1,19 @@ +===ORIGINAL=== + +// comment 1 +var x = 1; // comment 2 +// comment 3 +var y = 2; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 +===MODIFIED=== + +// comment 1 +var x = 1; // comment 2 +// comment 3 +public class class1 implements interface1 +{ + property1: boolean; +} +var a = 4; // comment 7 \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/replaceRangeNoLineBreakBefore.js b/tests/baselines/reference/textChanges/replaceRangeNoLineBreakBefore.js new file mode 100644 index 0000000000..72a45ee56e --- /dev/null +++ b/tests/baselines/reference/textChanges/replaceRangeNoLineBreakBefore.js @@ -0,0 +1,6 @@ +===ORIGINAL=== +const x = 1, y = "2"; +===MODIFIED=== +const x = 1, z1 = { + p1: 1 +}; \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/replaceRangeWithForcedIndentation.js b/tests/baselines/reference/textChanges/replaceRangeWithForcedIndentation.js new file mode 100644 index 0000000000..304b81b135 --- /dev/null +++ b/tests/baselines/reference/textChanges/replaceRangeWithForcedIndentation.js @@ -0,0 +1,19 @@ +===ORIGINAL=== + +// comment 1 +var x = 1; // comment 2 +// comment 3 +var y = 2; // comment 4 +var z = 3; // comment 5 +// comment 6 +var a = 4; // comment 7 +===MODIFIED=== + +// comment 1 +var x = 1; // comment 2 +// comment 3 + public class class1 implements interface1 + { + property1: boolean; + } +var a = 4; // comment 7 \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixAddForgottenThis01.ts b/tests/cases/fourslash/codeFixAddForgottenThis01.ts index 90d191b6ba..07f0634821 100644 --- a/tests/cases/fourslash/codeFixAddForgottenThis01.ts +++ b/tests/cases/fourslash/codeFixAddForgottenThis01.ts @@ -2,9 +2,11 @@ ////class C { //// foo: number; -//// constructor() { -//// [|foo = 10|]; -//// } +//// constructor() {[| +//// foo = 10; +//// |]} ////} -verify.rangeAfterCodeFix("this.foo = 10"); \ No newline at end of file +verify.rangeAfterCodeFix(` + this.foo = 10; + `, /*includeWhitespace*/ true); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixSuperAfterThis.ts b/tests/cases/fourslash/codeFixSuperAfterThis.ts index 2bff98ceca..55b44b0788 100644 --- a/tests/cases/fourslash/codeFixSuperAfterThis.ts +++ b/tests/cases/fourslash/codeFixSuperAfterThis.ts @@ -6,8 +6,10 @@ //// private a:number; //// constructor() {[| //// this.a = 12; -//// super();|] -//// } +//// super(); +//// |]} ////} - -verify.rangeAfterCodeFix("super(); this.a = 12;"); \ No newline at end of file +verify.rangeAfterCodeFix(` + super(); + this.a = 12; + `, /*includeWhiteSpace*/ true); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixSuperCall.ts b/tests/cases/fourslash/codeFixSuperCall.ts index c918e74dc3..f7584050a1 100644 --- a/tests/cases/fourslash/codeFixSuperCall.ts +++ b/tests/cases/fourslash/codeFixSuperCall.ts @@ -1,10 +1,11 @@ -/// +/// ////class Base{ ////} ////class C extends Base{ -//// constructor() {[| |] -//// } +//// constructor() {[| +//// |]} ////} - -verify.rangeAfterCodeFix('super();'); +verify.rangeAfterCodeFix(` + super(); + `, /*includeWhitespace*/ true); diff --git a/tests/cases/fourslash/unusedFunctionInNamespace1.ts b/tests/cases/fourslash/unusedFunctionInNamespace1.ts index 288573608f..7a63ff13ca 100644 --- a/tests/cases/fourslash/unusedFunctionInNamespace1.ts +++ b/tests/cases/fourslash/unusedFunctionInNamespace1.ts @@ -8,5 +8,4 @@ //// } |] verify.rangeAfterCodeFix(`namespace greeter { - // some legit comments }`); diff --git a/tests/cases/fourslash/unusedVariableInForLoop7FS.ts b/tests/cases/fourslash/unusedVariableInForLoop7FS.ts index 5aa3251c0b..7f99863ba4 100644 --- a/tests/cases/fourslash/unusedVariableInForLoop7FS.ts +++ b/tests/cases/fourslash/unusedVariableInForLoop7FS.ts @@ -1,12 +1,16 @@ /// // @noUnusedLocals: true -//// function f1 () { -//// for (const elem of ["a", "b", "c"]) { -//// elem; -//// [|var x = 20; -//// }|] -////} +////function f1 () [|{ +//// for (const elem of ["a", "b", "c"]) { +//// elem; +//// var x = 20; +//// } +////}|] //// -verify.rangeAfterCodeFix("}"); +verify.rangeAfterCodeFix(`{ + for (const elem of ["a", "b", "c"]) { + elem; + } +}`, /*includeWhiteSpace*/ true); From 0b1fff7e66a93b6e887895725f8c10b4b1b9b28e Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 6 Jan 2017 17:15:39 -0800 Subject: [PATCH 034/164] Add `--checkJsFiles` --- src/compiler/commandLineParser.ts | 6 ++++++ src/compiler/diagnosticMessages.json | 4 ++++ src/compiler/program.ts | 2 +- src/compiler/types.ts | 1 + 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index dc69297289..85a099c6dc 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -481,6 +481,12 @@ namespace ts { name: "plugin", type: "object" } + }, + { + name: "checkJsFiles", + type: "boolean", + experimental: true, + description: Diagnostics.Report_errors_in_js_files } ]; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 318f06ceea..83b4cb961a 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3362,5 +3362,9 @@ "Octal literals are not allowed in enums members initializer. Use the syntax '{0}'.": { "category": "Error", "code": 8018 + }, + "Report errors in .js files.": { + "category": "Message", + "code": 8019 } } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index d9ddf486e0..ecef2377ba 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -907,7 +907,7 @@ namespace ts { // For JavaScript files, we don't want to report semantic errors. // Instead, we'll report errors for using TypeScript-only constructs from within a // JavaScript file when we get syntactic diagnostics for the file. - const checkDiagnostics = isSourceFileJavaScript(sourceFile) ? [] : typeChecker.getDiagnostics(sourceFile, cancellationToken); + const checkDiagnostics = !options.checkJsFiles && isSourceFileJavaScript(sourceFile) ? [] : typeChecker.getDiagnostics(sourceFile, cancellationToken); const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName); const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f96f862388..02d0a784b3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3312,6 +3312,7 @@ alwaysStrict?: boolean; // Always combine with strict property baseUrl?: string; charset?: string; + checkJsFiles?: boolean; /* @internal */ configFilePath?: string; declaration?: boolean; declarationDir?: string; From 9f0c5ce1418df7ffb14eb7fefca4910a436dd3d2 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 6 Jan 2017 19:03:17 -0800 Subject: [PATCH 035/164] Add support for `//@check` directives --- src/compiler/parser.ts | 5 +++++ src/compiler/program.ts | 3 ++- src/compiler/types.ts | 1 + src/services/services.ts | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 308d3a317f..48fe3ce542 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5817,6 +5817,7 @@ namespace ts { const typeReferenceDirectives: FileReference[] = []; const amdDependencies: { path: string; name: string }[] = []; let amdModuleName: string; + let hasCheckDirective = false; // Keep scanning all the leading trivia in the file until we get to something that // isn't trivia. Any single line comment will be analyzed to see if it is a @@ -5878,6 +5879,9 @@ namespace ts { amdDependencies.push(amdDependency); } } + + const checkDirectiveRegEx = /^\/\/\s*@check\s*/gim; + hasCheckDirective = hasCheckDirective || !!checkDirectiveRegEx.exec(comment); } } @@ -5885,6 +5889,7 @@ namespace ts { sourceFile.typeReferenceDirectives = typeReferenceDirectives; sourceFile.amdDependencies = amdDependencies; sourceFile.moduleName = amdModuleName; + sourceFile.hasCheckDirective = hasCheckDirective; } function setExternalModuleIndicator(sourceFile: SourceFile) { diff --git a/src/compiler/program.ts b/src/compiler/program.ts index ecef2377ba..64da4f6de7 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -907,7 +907,8 @@ namespace ts { // For JavaScript files, we don't want to report semantic errors. // Instead, we'll report errors for using TypeScript-only constructs from within a // JavaScript file when we get syntactic diagnostics for the file. - const checkDiagnostics = !options.checkJsFiles && isSourceFileJavaScript(sourceFile) ? [] : typeChecker.getDiagnostics(sourceFile, cancellationToken); + const includeCheckDiagnostics = options.checkJsFiles || sourceFile.hasCheckDirective || !isSourceFileJavaScript(sourceFile); + const checkDiagnostics = includeCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : []; const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName); const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 02d0a784b3..3028b295d2 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2272,6 +2272,7 @@ /* @internal */ moduleAugmentations: LiteralExpression[]; /* @internal */ patternAmbientModules?: PatternAmbientModule[]; /* @internal */ ambientModuleNames: string[]; + /* @internal */ hasCheckDirective: boolean; } export interface Bundle extends Node { diff --git a/src/services/services.ts b/src/services/services.ts index f122e39bcc..037894661f 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -473,6 +473,7 @@ namespace ts { public moduleAugmentations: LiteralExpression[]; private namedDeclarations: Map; public ambientModuleNames: string[]; + public hasCheckDirective: boolean; constructor(kind: SyntaxKind, pos: number, end: number) { super(kind, pos, end); From 0b247b12a35b004f90489fcd9bc05bdc210a6394 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 6 Mar 2017 14:49:50 -0800 Subject: [PATCH 036/164] Add tests --- tests/baselines/reference/checkJsFiles.errors.txt | 13 +++++++++++++ tests/baselines/reference/checkJsFiles2.errors.txt | 14 ++++++++++++++ tests/baselines/reference/checkJsFiles3.errors.txt | 14 ++++++++++++++ tests/cases/compiler/checkJsFiles.ts | 6 ++++++ tests/cases/compiler/checkJsFiles2.ts | 7 +++++++ tests/cases/compiler/checkJsFiles3.ts | 6 ++++++ 6 files changed, 60 insertions(+) create mode 100644 tests/baselines/reference/checkJsFiles.errors.txt create mode 100644 tests/baselines/reference/checkJsFiles2.errors.txt create mode 100644 tests/baselines/reference/checkJsFiles3.errors.txt create mode 100644 tests/cases/compiler/checkJsFiles.ts create mode 100644 tests/cases/compiler/checkJsFiles2.ts create mode 100644 tests/cases/compiler/checkJsFiles3.ts diff --git a/tests/baselines/reference/checkJsFiles.errors.txt b/tests/baselines/reference/checkJsFiles.errors.txt new file mode 100644 index 0000000000..8371e101dd --- /dev/null +++ b/tests/baselines/reference/checkJsFiles.errors.txt @@ -0,0 +1,13 @@ +error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file. + Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. +tests/cases/compiler/a.js(3,1): error TS2322: Type '0' is not assignable to type 'string'. + + +!!! error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file. +!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. +==== tests/cases/compiler/a.js (1 errors) ==== + + var x = "string"; + x = 0; + ~ +!!! error TS2322: Type '0' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/checkJsFiles2.errors.txt b/tests/baselines/reference/checkJsFiles2.errors.txt new file mode 100644 index 0000000000..566ba3786b --- /dev/null +++ b/tests/baselines/reference/checkJsFiles2.errors.txt @@ -0,0 +1,14 @@ +error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file. + Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. +tests/cases/compiler/a.js(4,1): error TS2322: Type '0' is not assignable to type 'string'. + + +!!! error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file. +!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. +==== tests/cases/compiler/a.js (1 errors) ==== + + // @check + var x = "string"; + x = 0; + ~ +!!! error TS2322: Type '0' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/checkJsFiles3.errors.txt b/tests/baselines/reference/checkJsFiles3.errors.txt new file mode 100644 index 0000000000..566ba3786b --- /dev/null +++ b/tests/baselines/reference/checkJsFiles3.errors.txt @@ -0,0 +1,14 @@ +error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file. + Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. +tests/cases/compiler/a.js(4,1): error TS2322: Type '0' is not assignable to type 'string'. + + +!!! error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file. +!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. +==== tests/cases/compiler/a.js (1 errors) ==== + + // @check + var x = "string"; + x = 0; + ~ +!!! error TS2322: Type '0' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/cases/compiler/checkJsFiles.ts b/tests/cases/compiler/checkJsFiles.ts new file mode 100644 index 0000000000..c36673b023 --- /dev/null +++ b/tests/cases/compiler/checkJsFiles.ts @@ -0,0 +1,6 @@ +// @allowJs: true +// @checkJsFiles: true + +// @fileName: a.js +var x = "string"; +x = 0; \ No newline at end of file diff --git a/tests/cases/compiler/checkJsFiles2.ts b/tests/cases/compiler/checkJsFiles2.ts new file mode 100644 index 0000000000..fe8978666b --- /dev/null +++ b/tests/cases/compiler/checkJsFiles2.ts @@ -0,0 +1,7 @@ +// @allowJs: true +// @checkJsFiles: false + +// @fileName: a.js +// @check +var x = "string"; +x = 0; \ No newline at end of file diff --git a/tests/cases/compiler/checkJsFiles3.ts b/tests/cases/compiler/checkJsFiles3.ts new file mode 100644 index 0000000000..964f909bc6 --- /dev/null +++ b/tests/cases/compiler/checkJsFiles3.ts @@ -0,0 +1,6 @@ +// @allowJs: true + +// @fileName: a.js +// @check +var x = "string"; +x = 0; \ No newline at end of file From 1f9bb693ec389ae740da78106f46794a4653645a Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 6 Mar 2017 21:01:47 -0800 Subject: [PATCH 037/164] Add --noEmit to tests --- tests/baselines/reference/checkJsFiles.errors.txt | 4 ---- tests/baselines/reference/checkJsFiles2.errors.txt | 4 ---- tests/baselines/reference/checkJsFiles3.errors.txt | 4 ---- tests/cases/compiler/checkJsFiles.ts | 1 + tests/cases/compiler/checkJsFiles2.ts | 1 + tests/cases/compiler/checkJsFiles3.ts | 1 + 6 files changed, 3 insertions(+), 12 deletions(-) diff --git a/tests/baselines/reference/checkJsFiles.errors.txt b/tests/baselines/reference/checkJsFiles.errors.txt index 8371e101dd..41344dc384 100644 --- a/tests/baselines/reference/checkJsFiles.errors.txt +++ b/tests/baselines/reference/checkJsFiles.errors.txt @@ -1,10 +1,6 @@ -error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file. - Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. tests/cases/compiler/a.js(3,1): error TS2322: Type '0' is not assignable to type 'string'. -!!! error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file. -!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. ==== tests/cases/compiler/a.js (1 errors) ==== var x = "string"; diff --git a/tests/baselines/reference/checkJsFiles2.errors.txt b/tests/baselines/reference/checkJsFiles2.errors.txt index 566ba3786b..5c1a211a64 100644 --- a/tests/baselines/reference/checkJsFiles2.errors.txt +++ b/tests/baselines/reference/checkJsFiles2.errors.txt @@ -1,10 +1,6 @@ -error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file. - Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. tests/cases/compiler/a.js(4,1): error TS2322: Type '0' is not assignable to type 'string'. -!!! error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file. -!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. ==== tests/cases/compiler/a.js (1 errors) ==== // @check diff --git a/tests/baselines/reference/checkJsFiles3.errors.txt b/tests/baselines/reference/checkJsFiles3.errors.txt index 566ba3786b..5c1a211a64 100644 --- a/tests/baselines/reference/checkJsFiles3.errors.txt +++ b/tests/baselines/reference/checkJsFiles3.errors.txt @@ -1,10 +1,6 @@ -error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file. - Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. tests/cases/compiler/a.js(4,1): error TS2322: Type '0' is not assignable to type 'string'. -!!! error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file. -!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. ==== tests/cases/compiler/a.js (1 errors) ==== // @check diff --git a/tests/cases/compiler/checkJsFiles.ts b/tests/cases/compiler/checkJsFiles.ts index c36673b023..0f19653973 100644 --- a/tests/cases/compiler/checkJsFiles.ts +++ b/tests/cases/compiler/checkJsFiles.ts @@ -1,5 +1,6 @@ // @allowJs: true // @checkJsFiles: true +// @noEmit: true // @fileName: a.js var x = "string"; diff --git a/tests/cases/compiler/checkJsFiles2.ts b/tests/cases/compiler/checkJsFiles2.ts index fe8978666b..e18eecb039 100644 --- a/tests/cases/compiler/checkJsFiles2.ts +++ b/tests/cases/compiler/checkJsFiles2.ts @@ -1,5 +1,6 @@ // @allowJs: true // @checkJsFiles: false +// @noEmit: true // @fileName: a.js // @check diff --git a/tests/cases/compiler/checkJsFiles3.ts b/tests/cases/compiler/checkJsFiles3.ts index 964f909bc6..a0a9a152fe 100644 --- a/tests/cases/compiler/checkJsFiles3.ts +++ b/tests/cases/compiler/checkJsFiles3.ts @@ -1,4 +1,5 @@ // @allowJs: true +// @noEmit: true // @fileName: a.js // @check From b015c1d9b0181bcb499af1e801d9acb70d5a6d4f Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 6 Mar 2017 21:39:32 -0800 Subject: [PATCH 038/164] Allow @check directives to switch on/off checking in a file --- src/compiler/parser.ts | 15 +++++++++++---- src/compiler/program.ts | 7 +++---- src/compiler/types.ts | 6 +++++- src/harness/harness.ts | 2 +- src/services/services.ts | 2 +- .../baselines/reference/checkJsFiles4.errors.txt | 10 ++++++++++ tests/baselines/reference/checkJsFiles5.symbols | 9 +++++++++ tests/baselines/reference/checkJsFiles5.types | 12 ++++++++++++ tests/cases/compiler/checkJsFiles4.ts | 8 ++++++++ tests/cases/compiler/checkJsFiles5.ts | 8 ++++++++ 10 files changed, 68 insertions(+), 11 deletions(-) create mode 100644 tests/baselines/reference/checkJsFiles4.errors.txt create mode 100644 tests/baselines/reference/checkJsFiles5.symbols create mode 100644 tests/baselines/reference/checkJsFiles5.types create mode 100644 tests/cases/compiler/checkJsFiles4.ts create mode 100644 tests/cases/compiler/checkJsFiles5.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 48fe3ce542..ef23ee175f 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5817,7 +5817,7 @@ namespace ts { const typeReferenceDirectives: FileReference[] = []; const amdDependencies: { path: string; name: string }[] = []; let amdModuleName: string; - let hasCheckDirective = false; + let checkJsDirective: CheckJsDirective = undefined; // Keep scanning all the leading trivia in the file until we get to something that // isn't trivia. Any single line comment will be analyzed to see if it is a @@ -5880,8 +5880,15 @@ namespace ts { } } - const checkDirectiveRegEx = /^\/\/\s*@check\s*/gim; - hasCheckDirective = hasCheckDirective || !!checkDirectiveRegEx.exec(comment); + const checkJsDirectiveRegEx = /^\/\/\/?\s*@check(\s+(true|false))?/gim; + const checkJsDirectiveMatchResult = checkJsDirectiveRegEx.exec(comment); + if (checkJsDirectiveMatchResult) { + checkJsDirective = { + enabled: compareStrings(checkJsDirectiveMatchResult[2], "false", /*ignoreCase*/ true) !== Comparison.EqualTo, + end: range.end, + pos: range.pos + }; + } } } @@ -5889,7 +5896,7 @@ namespace ts { sourceFile.typeReferenceDirectives = typeReferenceDirectives; sourceFile.amdDependencies = amdDependencies; sourceFile.moduleName = amdModuleName; - sourceFile.hasCheckDirective = hasCheckDirective; + sourceFile.checkJsDirective = checkJsDirective; } function setExternalModuleIndicator(sourceFile: SourceFile) { diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 64da4f6de7..29559c1219 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -904,10 +904,9 @@ namespace ts { Debug.assert(!!sourceFile.bindDiagnostics); const bindDiagnostics = sourceFile.bindDiagnostics; - // For JavaScript files, we don't want to report semantic errors. - // Instead, we'll report errors for using TypeScript-only constructs from within a - // JavaScript file when we get syntactic diagnostics for the file. - const includeCheckDiagnostics = options.checkJsFiles || sourceFile.hasCheckDirective || !isSourceFileJavaScript(sourceFile); + // For JavaScript files, we don't want to report semantic errors unless ecplicitlly requested. + const includeCheckDiagnostics = !isSourceFileJavaScript(sourceFile) || + (sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : options.checkJsFiles); const checkDiagnostics = includeCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : []; const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName); const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 3028b295d2..beb68a015b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1940,6 +1940,10 @@ fileName: string; } + export interface CheckJsDirective extends TextRange { + enabled: boolean; + } + export type CommentKind = SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia; export interface CommentRange extends TextRange { @@ -2272,7 +2276,7 @@ /* @internal */ moduleAugmentations: LiteralExpression[]; /* @internal */ patternAmbientModules?: PatternAmbientModule[]; /* @internal */ ambientModuleNames: string[]; - /* @internal */ hasCheckDirective: boolean; + /* @internal */ checkJsDirective: CheckJsDirective | undefined; } export interface Bundle extends Node { diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 23e8106864..9304940ce1 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -202,7 +202,7 @@ namespace Utils { for (const childName in node) { if (childName === "parent" || childName === "nextContainer" || childName === "modifiers" || childName === "externalModuleIndicator" || // for now ignore jsdoc comments - childName === "jsDocComment") { + childName === "jsDocComment" || childName === "checkJsDirective") { continue; } const child = (node)[childName]; diff --git a/src/services/services.ts b/src/services/services.ts index 037894661f..a77bacb9a8 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -473,7 +473,7 @@ namespace ts { public moduleAugmentations: LiteralExpression[]; private namedDeclarations: Map; public ambientModuleNames: string[]; - public hasCheckDirective: boolean; + public checkJsDirective: CheckJsDirective | undefined; constructor(kind: SyntaxKind, pos: number, end: number) { super(kind, pos, end); diff --git a/tests/baselines/reference/checkJsFiles4.errors.txt b/tests/baselines/reference/checkJsFiles4.errors.txt new file mode 100644 index 0000000000..87eb0f3b7d --- /dev/null +++ b/tests/baselines/reference/checkJsFiles4.errors.txt @@ -0,0 +1,10 @@ +tests/cases/compiler/a.js(4,1): error TS2322: Type '0' is not assignable to type 'string'. + + +==== tests/cases/compiler/a.js (1 errors) ==== + + // @check true + var x = "string"; + x = 0; + ~ +!!! error TS2322: Type '0' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/checkJsFiles5.symbols b/tests/baselines/reference/checkJsFiles5.symbols new file mode 100644 index 0000000000..cdb53964aa --- /dev/null +++ b/tests/baselines/reference/checkJsFiles5.symbols @@ -0,0 +1,9 @@ +=== tests/cases/compiler/a.js === + +// @check false +var x = "string"; +>x : Symbol(x, Decl(a.js, 2, 3)) + +x = 0; +>x : Symbol(x, Decl(a.js, 2, 3)) + diff --git a/tests/baselines/reference/checkJsFiles5.types b/tests/baselines/reference/checkJsFiles5.types new file mode 100644 index 0000000000..bd1ab8d942 --- /dev/null +++ b/tests/baselines/reference/checkJsFiles5.types @@ -0,0 +1,12 @@ +=== tests/cases/compiler/a.js === + +// @check false +var x = "string"; +>x : string +>"string" : "string" + +x = 0; +>x = 0 : 0 +>x : string +>0 : 0 + diff --git a/tests/cases/compiler/checkJsFiles4.ts b/tests/cases/compiler/checkJsFiles4.ts new file mode 100644 index 0000000000..364397a3e8 --- /dev/null +++ b/tests/cases/compiler/checkJsFiles4.ts @@ -0,0 +1,8 @@ +// @allowJs: true +// @checkJsFiles: false +// @noEmit: true + +// @fileName: a.js +// @check true +var x = "string"; +x = 0; \ No newline at end of file diff --git a/tests/cases/compiler/checkJsFiles5.ts b/tests/cases/compiler/checkJsFiles5.ts new file mode 100644 index 0000000000..572f6b3b5f --- /dev/null +++ b/tests/cases/compiler/checkJsFiles5.ts @@ -0,0 +1,8 @@ +// @allowJs: true +// @checkJsFiles: true +// @noEmit: true + +// @fileName: a.js +// @check false +var x = "string"; +x = 0; \ No newline at end of file From 9305d4d99e9799afb998bd34aede02ec0f4f1401 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 7 Mar 2017 13:48:37 -0800 Subject: [PATCH 039/164] Change flag name to `checkJs` --- src/compiler/commandLineParser.ts | 2 +- src/compiler/program.ts | 2 +- src/compiler/types.ts | 2 +- tests/cases/compiler/checkJsFiles.ts | 2 +- tests/cases/compiler/checkJsFiles2.ts | 2 +- tests/cases/compiler/checkJsFiles4.ts | 2 +- tests/cases/compiler/checkJsFiles5.ts | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 85a099c6dc..70966c48e7 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -483,7 +483,7 @@ namespace ts { } }, { - name: "checkJsFiles", + name: "checkJs", type: "boolean", experimental: true, description: Diagnostics.Report_errors_in_js_files diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 29559c1219..5fd178a891 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -906,7 +906,7 @@ namespace ts { const bindDiagnostics = sourceFile.bindDiagnostics; // For JavaScript files, we don't want to report semantic errors unless ecplicitlly requested. const includeCheckDiagnostics = !isSourceFileJavaScript(sourceFile) || - (sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : options.checkJsFiles); + (sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : options.checkJs); const checkDiagnostics = includeCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : []; const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName); const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index beb68a015b..7e7fe7c28e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3317,7 +3317,7 @@ alwaysStrict?: boolean; // Always combine with strict property baseUrl?: string; charset?: string; - checkJsFiles?: boolean; + checkJs?: boolean; /* @internal */ configFilePath?: string; declaration?: boolean; declarationDir?: string; diff --git a/tests/cases/compiler/checkJsFiles.ts b/tests/cases/compiler/checkJsFiles.ts index 0f19653973..62e2eb3301 100644 --- a/tests/cases/compiler/checkJsFiles.ts +++ b/tests/cases/compiler/checkJsFiles.ts @@ -1,5 +1,5 @@ // @allowJs: true -// @checkJsFiles: true +// @checkJs: true // @noEmit: true // @fileName: a.js diff --git a/tests/cases/compiler/checkJsFiles2.ts b/tests/cases/compiler/checkJsFiles2.ts index e18eecb039..36bc2cbd25 100644 --- a/tests/cases/compiler/checkJsFiles2.ts +++ b/tests/cases/compiler/checkJsFiles2.ts @@ -1,5 +1,5 @@ // @allowJs: true -// @checkJsFiles: false +// @checkJs: false // @noEmit: true // @fileName: a.js diff --git a/tests/cases/compiler/checkJsFiles4.ts b/tests/cases/compiler/checkJsFiles4.ts index 364397a3e8..8bebedf55e 100644 --- a/tests/cases/compiler/checkJsFiles4.ts +++ b/tests/cases/compiler/checkJsFiles4.ts @@ -1,5 +1,5 @@ // @allowJs: true -// @checkJsFiles: false +// @checkJs: false // @noEmit: true // @fileName: a.js diff --git a/tests/cases/compiler/checkJsFiles5.ts b/tests/cases/compiler/checkJsFiles5.ts index 572f6b3b5f..c28114f570 100644 --- a/tests/cases/compiler/checkJsFiles5.ts +++ b/tests/cases/compiler/checkJsFiles5.ts @@ -1,5 +1,5 @@ // @allowJs: true -// @checkJsFiles: true +// @checkJs: true // @noEmit: true // @fileName: a.js From fb218b789746f2c8e12ea8919e4951a7403e9525 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 7 Mar 2017 13:49:52 -0800 Subject: [PATCH 040/164] Error if `--checkJs` is used without `--allowJs` --- src/compiler/program.ts | 4 ++++ tests/baselines/reference/checkJsFiles6.errors.txt | 9 +++++++++ tests/cases/compiler/checkJsFiles6.ts | 6 ++++++ 3 files changed, 19 insertions(+) create mode 100644 tests/baselines/reference/checkJsFiles6.errors.txt create mode 100644 tests/cases/compiler/checkJsFiles6.ts diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 5fd178a891..f524a54985 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1685,6 +1685,10 @@ namespace ts { programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration")); } + if (options.checkJs && !options.allowJs) { + programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "checkJs", "allowJs")); + } + if (options.emitDecoratorMetadata && !options.experimentalDecorators) { programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators")); diff --git a/tests/baselines/reference/checkJsFiles6.errors.txt b/tests/baselines/reference/checkJsFiles6.errors.txt new file mode 100644 index 0000000000..89063e5069 --- /dev/null +++ b/tests/baselines/reference/checkJsFiles6.errors.txt @@ -0,0 +1,9 @@ +error TS5052: Option 'checkJs' cannot be specified without specifying option 'allowJs'. +error TS6054: File 'tests/cases/compiler/a.js' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts'. + + +!!! error TS5052: Option 'checkJs' cannot be specified without specifying option 'allowJs'. +!!! error TS6054: File 'tests/cases/compiler/a.js' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts'. +==== tests/cases/compiler/a.js (0 errors) ==== + + var x; \ No newline at end of file diff --git a/tests/cases/compiler/checkJsFiles6.ts b/tests/cases/compiler/checkJsFiles6.ts new file mode 100644 index 0000000000..358704ae22 --- /dev/null +++ b/tests/cases/compiler/checkJsFiles6.ts @@ -0,0 +1,6 @@ +// @allowJs: false +// @checkJs: true +// @noEmit: true + +// @fileName: a.js +var x; \ No newline at end of file From e9f82145b781f68aa243fb078b8c898552759798 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 7 Mar 2017 23:03:47 -0800 Subject: [PATCH 041/164] Code review comments --- src/compiler/parser.ts | 4 ++-- src/compiler/program.ts | 2 +- tests/baselines/reference/checkJsFiles2.errors.txt | 2 +- tests/baselines/reference/checkJsFiles3.errors.txt | 2 +- tests/baselines/reference/checkJsFiles4.errors.txt | 2 +- tests/baselines/reference/checkJsFiles5.symbols | 2 +- tests/baselines/reference/checkJsFiles5.types | 2 +- tests/cases/compiler/checkJsFiles2.ts | 2 +- tests/cases/compiler/checkJsFiles3.ts | 2 +- tests/cases/compiler/checkJsFiles4.ts | 2 +- tests/cases/compiler/checkJsFiles5.ts | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index ef23ee175f..faff106959 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5880,11 +5880,11 @@ namespace ts { } } - const checkJsDirectiveRegEx = /^\/\/\/?\s*@check(\s+(true|false))?/gim; + const checkJsDirectiveRegEx = /^\/\/\/?\s*(@ts-check|@ts-nocheck)\s*$/gim; const checkJsDirectiveMatchResult = checkJsDirectiveRegEx.exec(comment); if (checkJsDirectiveMatchResult) { checkJsDirective = { - enabled: compareStrings(checkJsDirectiveMatchResult[2], "false", /*ignoreCase*/ true) !== Comparison.EqualTo, + enabled: compareStrings(checkJsDirectiveMatchResult[1], "@ts-check", /*ignoreCase*/ true) === Comparison.EqualTo, end: range.end, pos: range.pos }; diff --git a/src/compiler/program.ts b/src/compiler/program.ts index f524a54985..d46c3b2479 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -904,7 +904,7 @@ namespace ts { Debug.assert(!!sourceFile.bindDiagnostics); const bindDiagnostics = sourceFile.bindDiagnostics; - // For JavaScript files, we don't want to report semantic errors unless ecplicitlly requested. + // For JavaScript files, we don't want to report semantic errors unless explicitly requested. const includeCheckDiagnostics = !isSourceFileJavaScript(sourceFile) || (sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : options.checkJs); const checkDiagnostics = includeCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : []; diff --git a/tests/baselines/reference/checkJsFiles2.errors.txt b/tests/baselines/reference/checkJsFiles2.errors.txt index 5c1a211a64..7fc852fba1 100644 --- a/tests/baselines/reference/checkJsFiles2.errors.txt +++ b/tests/baselines/reference/checkJsFiles2.errors.txt @@ -3,7 +3,7 @@ tests/cases/compiler/a.js(4,1): error TS2322: Type '0' is not assignable to type ==== tests/cases/compiler/a.js (1 errors) ==== - // @check + // @ts-check var x = "string"; x = 0; ~ diff --git a/tests/baselines/reference/checkJsFiles3.errors.txt b/tests/baselines/reference/checkJsFiles3.errors.txt index 5c1a211a64..7fc852fba1 100644 --- a/tests/baselines/reference/checkJsFiles3.errors.txt +++ b/tests/baselines/reference/checkJsFiles3.errors.txt @@ -3,7 +3,7 @@ tests/cases/compiler/a.js(4,1): error TS2322: Type '0' is not assignable to type ==== tests/cases/compiler/a.js (1 errors) ==== - // @check + // @ts-check var x = "string"; x = 0; ~ diff --git a/tests/baselines/reference/checkJsFiles4.errors.txt b/tests/baselines/reference/checkJsFiles4.errors.txt index 87eb0f3b7d..7fc852fba1 100644 --- a/tests/baselines/reference/checkJsFiles4.errors.txt +++ b/tests/baselines/reference/checkJsFiles4.errors.txt @@ -3,7 +3,7 @@ tests/cases/compiler/a.js(4,1): error TS2322: Type '0' is not assignable to type ==== tests/cases/compiler/a.js (1 errors) ==== - // @check true + // @ts-check var x = "string"; x = 0; ~ diff --git a/tests/baselines/reference/checkJsFiles5.symbols b/tests/baselines/reference/checkJsFiles5.symbols index cdb53964aa..76cc21c46a 100644 --- a/tests/baselines/reference/checkJsFiles5.symbols +++ b/tests/baselines/reference/checkJsFiles5.symbols @@ -1,6 +1,6 @@ === tests/cases/compiler/a.js === -// @check false +// @ts-nocheck var x = "string"; >x : Symbol(x, Decl(a.js, 2, 3)) diff --git a/tests/baselines/reference/checkJsFiles5.types b/tests/baselines/reference/checkJsFiles5.types index bd1ab8d942..15704315bb 100644 --- a/tests/baselines/reference/checkJsFiles5.types +++ b/tests/baselines/reference/checkJsFiles5.types @@ -1,6 +1,6 @@ === tests/cases/compiler/a.js === -// @check false +// @ts-nocheck var x = "string"; >x : string >"string" : "string" diff --git a/tests/cases/compiler/checkJsFiles2.ts b/tests/cases/compiler/checkJsFiles2.ts index 36bc2cbd25..2e4d4396e4 100644 --- a/tests/cases/compiler/checkJsFiles2.ts +++ b/tests/cases/compiler/checkJsFiles2.ts @@ -3,6 +3,6 @@ // @noEmit: true // @fileName: a.js -// @check +// @ts-check var x = "string"; x = 0; \ No newline at end of file diff --git a/tests/cases/compiler/checkJsFiles3.ts b/tests/cases/compiler/checkJsFiles3.ts index a0a9a152fe..885bf1979f 100644 --- a/tests/cases/compiler/checkJsFiles3.ts +++ b/tests/cases/compiler/checkJsFiles3.ts @@ -2,6 +2,6 @@ // @noEmit: true // @fileName: a.js -// @check +// @ts-check var x = "string"; x = 0; \ No newline at end of file diff --git a/tests/cases/compiler/checkJsFiles4.ts b/tests/cases/compiler/checkJsFiles4.ts index 8bebedf55e..2e4d4396e4 100644 --- a/tests/cases/compiler/checkJsFiles4.ts +++ b/tests/cases/compiler/checkJsFiles4.ts @@ -3,6 +3,6 @@ // @noEmit: true // @fileName: a.js -// @check true +// @ts-check var x = "string"; x = 0; \ No newline at end of file diff --git a/tests/cases/compiler/checkJsFiles5.ts b/tests/cases/compiler/checkJsFiles5.ts index c28114f570..10f59aed17 100644 --- a/tests/cases/compiler/checkJsFiles5.ts +++ b/tests/cases/compiler/checkJsFiles5.ts @@ -3,6 +3,6 @@ // @noEmit: true // @fileName: a.js -// @check false +// @ts-nocheck var x = "string"; x = 0; \ No newline at end of file From a202fa4c888b55368d3ecd506ba0594cf84577b0 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 8 Mar 2017 23:08:55 -0800 Subject: [PATCH 042/164] add es6 to buildProtocol --- Jakefile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jakefile.js b/Jakefile.js index 4512aa2379..4a31c8da17 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -422,7 +422,7 @@ compileFile(buildProtocolJs, [buildProtocolTs], [], /*useBuiltCompiler*/ false, - {noOutFile: true}); + { noOutFile: true, lib: "es6" }); file(buildProtocolDts, [buildProtocolTs, buildProtocolJs, typescriptServicesDts], function() { From fe7719f0a9747214046eb1dc8bbf5047b2fc90d3 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 7 Mar 2017 23:03:47 -0800 Subject: [PATCH 043/164] Disable check diagnostics per line --- src/compiler/program.ts | 29 +++++++++++- .../checkJsFiles_skipDiagnostics.symbols | 38 +++++++++++++++ .../checkJsFiles_skipDiagnostics.types | 47 +++++++++++++++++++ .../compiler/checkJsFiles_skipDiagnostics.ts | 33 +++++++++++++ 4 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/checkJsFiles_skipDiagnostics.symbols create mode 100644 tests/baselines/reference/checkJsFiles_skipDiagnostics.types create mode 100644 tests/cases/compiler/checkJsFiles_skipDiagnostics.ts diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 67e9f62fe2..bdc8f76cf6 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -4,6 +4,7 @@ namespace ts { const emptyArray: any[] = []; + const suppressDiagnosticCommentRegEx = /(^\s*$)|(^\s*\/\/\/?\s*(@ts-suppress)?)/; export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string { while (true) { @@ -923,10 +924,36 @@ namespace ts { const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName); const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName); - return bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile); + const diagnostics = bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile); + return isSourceFileJavaScript(sourceFile) + ? filter(diagnostics, shouldReportDiagnostic) + : diagnostics; }); } + /** + * Skip errors if previous line start with '// @ts-suppress' comment, not counting non-empty non-comment lines + */ + function shouldReportDiagnostic(diagnostic: Diagnostic) { + const { file, start } = diagnostic; + const lineStarts = getLineStarts(file); + let { line } = computeLineAndCharacterOfPosition(lineStarts, start); + while (line > 0) { + const previousLineText = file.text.slice(lineStarts[line - 1], lineStarts[line]); + const result = suppressDiagnosticCommentRegEx.exec(previousLineText); + if (!result) { + // non-empty line + return true; + } + if (result[3]) { + // @ts-suppress + return false; + } + line--; + } + return true; + } + function getJavaScriptSyntacticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] { return runWithCancellationToken(() => { const diagnostics: Diagnostic[] = []; diff --git a/tests/baselines/reference/checkJsFiles_skipDiagnostics.symbols b/tests/baselines/reference/checkJsFiles_skipDiagnostics.symbols new file mode 100644 index 0000000000..a0f2200048 --- /dev/null +++ b/tests/baselines/reference/checkJsFiles_skipDiagnostics.symbols @@ -0,0 +1,38 @@ +=== tests/cases/compiler/a.js === + +var x = 0; +>x : Symbol(x, Decl(a.js, 1, 3)) + + +/// @ts-suppress +x(); +>x : Symbol(x, Decl(a.js, 1, 3)) + +/// @ts-suppress +x(); +>x : Symbol(x, Decl(a.js, 1, 3)) + +/// @ts-suppress +x( +>x : Symbol(x, Decl(a.js, 1, 3)) + + 2, + 3); + + + +// @ts-suppress +// come comment +// some other comment + +// @anohter + +x(); +>x : Symbol(x, Decl(a.js, 1, 3)) + + + +// @ts-suppress: no call signature +x(); +>x : Symbol(x, Decl(a.js, 1, 3)) + diff --git a/tests/baselines/reference/checkJsFiles_skipDiagnostics.types b/tests/baselines/reference/checkJsFiles_skipDiagnostics.types new file mode 100644 index 0000000000..69105a3112 --- /dev/null +++ b/tests/baselines/reference/checkJsFiles_skipDiagnostics.types @@ -0,0 +1,47 @@ +=== tests/cases/compiler/a.js === + +var x = 0; +>x : number +>0 : 0 + + +/// @ts-suppress +x(); +>x() : any +>x : number + +/// @ts-suppress +x(); +>x() : any +>x : number + +/// @ts-suppress +x( +>x( 2, 3) : any +>x : number + + 2, +>2 : 2 + + 3); +>3 : 3 + + + +// @ts-suppress +// come comment +// some other comment + +// @anohter + +x(); +>x() : any +>x : number + + + +// @ts-suppress: no call signature +x(); +>x() : any +>x : number + diff --git a/tests/cases/compiler/checkJsFiles_skipDiagnostics.ts b/tests/cases/compiler/checkJsFiles_skipDiagnostics.ts new file mode 100644 index 0000000000..bcbcc815e7 --- /dev/null +++ b/tests/cases/compiler/checkJsFiles_skipDiagnostics.ts @@ -0,0 +1,33 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true + +// @fileName: a.js +var x = 0; + + +/// @ts-suppress +x(); + +/// @ts-suppress +x(); + +/// @ts-suppress +x( + 2, + 3); + + + +// @ts-suppress +// come comment +// some other comment + +// @anohter + +x(); + + + +// @ts-suppress: no call signature +x(); \ No newline at end of file From 706acdf13834bfd479b63aced65e157033353c42 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 7 Mar 2017 13:40:15 -0800 Subject: [PATCH 044/164] Add quick fix to disable error checking in a .js file --- src/compiler/diagnosticMessages.json | 10 +++ .../codefixes/disableJsDiagnostics.ts | 67 +++++++++++++++++++ src/services/codefixes/fixes.ts | 1 + .../codefixes/unusedIdentifierFixes.ts | 12 +--- src/services/tsconfig.json | 3 +- src/services/utilities.ts | 7 ++ .../codeFixDisableJsDiagnosticsInFile.ts | 11 +++ .../codeFixDisableJsDiagnosticsInFile2.ts | 15 +++++ .../codeFixDisableJsDiagnosticsInFile3.ts | 14 ++++ .../codeFixDisableJsDiagnosticsInFile4.ts | 18 +++++ .../codeFixDisableJsDiagnosticsInFile5.ts | 17 +++++ .../codeFixDisableJsDiagnosticsInFile6.ts | 17 +++++ .../codeFixDisableJsDiagnosticsInFile7.ts | 17 +++++ .../codeFixDisableJsDiagnosticsInFile8.ts | 19 ++++++ 14 files changed, 218 insertions(+), 10 deletions(-) create mode 100644 src/services/codefixes/disableJsDiagnostics.ts create mode 100644 tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile.ts create mode 100644 tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile2.ts create mode 100644 tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile3.ts create mode 100644 tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile4.ts create mode 100644 tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile5.ts create mode 100644 tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile6.ts create mode 100644 tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile7.ts create mode 100644 tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile8.ts diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 83b4cb961a..6495f6d9ac 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3355,6 +3355,16 @@ "category": "Message", "code": 90017 }, + "Disable checking for this file.": { + "category": "Message", + "code": 90018 + }, + "Suppress this error message.": { + "category": "Message", + "code": 90019 + }, + + "Octal literal types must use ES2015 syntax. Use the syntax '{0}'.": { "category": "Error", "code": 8017 diff --git a/src/services/codefixes/disableJsDiagnostics.ts b/src/services/codefixes/disableJsDiagnostics.ts new file mode 100644 index 0000000000..6e4a5f3858 --- /dev/null +++ b/src/services/codefixes/disableJsDiagnostics.ts @@ -0,0 +1,67 @@ +/* @internal */ +namespace ts.codefix { + registerCodeFix({ + errorCodes: getApplicableDiagnosticCodes(), + getCodeActions: getDisableJsDiagnosticsCodeActions + }); + + function getApplicableDiagnosticCodes(): number[] { + const allDiagnostcs = >Diagnostics; + return Object.keys(allDiagnostcs) + .filter(d => allDiagnostcs[d] && allDiagnostcs[d].category === DiagnosticCategory.Error) + .map(d => allDiagnostcs[d].code); + } + + function shouldCheckJsFile(sourceFile: SourceFile, compilerOptions: CompilerOptions) { + return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs; + } + + function getSuppressCommentLocationForLocation(sourceFile: SourceFile, position: number, newLineCharacter: string) { + let { line } = getLineAndCharacterOfPosition(sourceFile, position); + const lineStartPosition = getStartPositionOfLine(line, sourceFile); + const startPosition = getFirstNonSpaceCharacterPosition(sourceFile.text, lineStartPosition); + if (!isInComment(sourceFile, startPosition) && !isInString(sourceFile, startPosition) && !isInTemplateString(sourceFile, startPosition)) { + const token = getTouchingToken(sourceFile, startPosition); + const tokenLeadingCommnets = getLeadingCommentRangesOfNode(token, sourceFile) + if (!tokenLeadingCommnets || !tokenLeadingCommnets.length || tokenLeadingCommnets[0].pos >= startPosition) { + return { + span: { start: startPosition, length: 0 }, + newText: `// @ts-suppress${newLineCharacter}` + }; + } + } + return { + span: { start: position, length: 0 }, + newText: `${position === startPosition ? "" : newLineCharacter}// @ts-suppress${newLineCharacter}` + }; + } + + function getDisableJsDiagnosticsCodeActions(context: CodeFixContext): CodeAction[] | undefined { + const { sourceFile, program, newLineCharacter, span } = context; + + if (!isInJavaScriptFile(sourceFile) || !shouldCheckJsFile(sourceFile, program.getCompilerOptions())) { + return undefined; + } + + return [{ + description: getLocaleSpecificMessage(Diagnostics.Suppress_this_error_message), + changes: [{ + fileName: sourceFile.fileName, + textChanges: [getSuppressCommentLocationForLocation(sourceFile, span.start, newLineCharacter)] + }] + }, + { + description: getLocaleSpecificMessage(Diagnostics.Disable_checking_for_this_file), + changes: [{ + fileName: sourceFile.fileName, + textChanges: [{ + span: { + start: sourceFile.checkJsDirective ? sourceFile.checkJsDirective.pos : 0, + length: sourceFile.checkJsDirective ? sourceFile.checkJsDirective.end - sourceFile.checkJsDirective.pos : 0 + }, + newText: `// @ts-nocheck${newLineCharacter}` + }] + }] + }]; + } +} \ No newline at end of file diff --git a/src/services/codefixes/fixes.ts b/src/services/codefixes/fixes.ts index 76be34c67c..ae1643dfa3 100644 --- a/src/services/codefixes/fixes.ts +++ b/src/services/codefixes/fixes.ts @@ -7,4 +7,5 @@ /// /// /// +/// /// diff --git a/src/services/codefixes/unusedIdentifierFixes.ts b/src/services/codefixes/unusedIdentifierFixes.ts index 61d48bdc3b..6c8bd0a9db 100644 --- a/src/services/codefixes/unusedIdentifierFixes.ts +++ b/src/services/codefixes/unusedIdentifierFixes.ts @@ -105,9 +105,10 @@ namespace ts.codefix { else { // import |d,| * as ns from './file' const start = importClause.name.getStart(); - let end = findFirstNonSpaceCharPosStarting(importClause.name.end); + const text = sourceFile.text; + let end = getFirstNonSpaceCharacterPosition(text, importClause.name.end); if (sourceFile.text.charCodeAt(end) === CharacterCodes.comma) { - end = findFirstNonSpaceCharPosStarting(end + 1); + end = getFirstNonSpaceCharacterPosition(text, end + 1); } return createCodeFix("", start, end - start); @@ -166,13 +167,6 @@ namespace ts.codefix { return createCodeFix("", start, end - start); } - function findFirstNonSpaceCharPosStarting(start: number) { - while (isWhiteSpace(sourceFile.text.charCodeAt(start))) { - start += 1; - } - return start; - } - function createCodeFix(newText: string, start: number, length: number): CodeAction[] { return [{ description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Remove_declaration_for_Colon_0), { 0: token.getText() }), diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index 93f861e80a..b97b3c509f 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -90,6 +90,7 @@ "codefixes/fixes.ts", "codefixes/helpers.ts", "codefixes/importFixes.ts", - "codefixes/unusedIdentifierFixes.ts" + "codefixes/unusedIdentifierFixes.ts", + "codefixes/disableJsDiagnostics.ts" ] } \ No newline at end of file diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 7c5bf862fc..c894df121f 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1388,4 +1388,11 @@ namespace ts { // First token is the open curly, this is where we want to put the 'super' call. return constructor.body.getFirstToken(sourceFile).getEnd(); } + + export function getFirstNonSpaceCharacterPosition(text: string, position: number) { + while (isWhiteSpace(text.charCodeAt(position))) { + position += 1; + } + return position; + } } diff --git a/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile.ts b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile.ts new file mode 100644 index 0000000000..070712c252 --- /dev/null +++ b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile.ts @@ -0,0 +1,11 @@ +/// + +// @allowjs: true +// @noEmit: true + +// @Filename: a.js +////[|// @ts-check|] +////var x = ""; +////x = 1; + +verify.rangeAfterCodeFix("// @ts-nocheck", /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 1); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile2.ts b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile2.ts new file mode 100644 index 0000000000..4a55f2ba44 --- /dev/null +++ b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile2.ts @@ -0,0 +1,15 @@ +/// + +// @allowjs: true +// @noEmit: true +// @checkJs: true + +// @Filename: a.js +////[|var x = ""; +////x = 1;|] + +// Disable checking for the whole file +verify.rangeAfterCodeFix(`// @ts-nocheck +var x = ""; +x = 1;`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 1); + diff --git a/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile3.ts b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile3.ts new file mode 100644 index 0000000000..f486a7e171 --- /dev/null +++ b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile3.ts @@ -0,0 +1,14 @@ +/// + +// @allowjs: true +// @noEmit: true +// @checkJs: true + +// @Filename: a.js +////[|var x = ""; +////x = 1;|] + +// Disable checking for next line +verify.rangeAfterCodeFix(`var x = ""; +// @ts-suppress +x = 1;`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); diff --git a/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile4.ts b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile4.ts new file mode 100644 index 0000000000..cadbda2c27 --- /dev/null +++ b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile4.ts @@ -0,0 +1,18 @@ +/// + +// @allowjs: true +// @noEmit: true +// @checkJs: true + +// @Filename: a.js +////var x = ""; +//// +////[|"test \ +////"; x = 1;|] + +// Disable checking for next line +verify.rangeAfterCodeFix(`"test \\ +"; +// @ts-suppress +x = 1;`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); + diff --git a/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile5.ts b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile5.ts new file mode 100644 index 0000000000..56b9fbf20d --- /dev/null +++ b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile5.ts @@ -0,0 +1,17 @@ +/// + +// @allowjs: true +// @noEmit: true +// @checkJs: true + +// @Filename: a.js +////var x = ""; +//// +////[|/** comment */ +////x = 1;|] + +// Disable checking for next line +verify.rangeAfterCodeFix(`/** comment */ +// @ts-suppress +x = 1;`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); + diff --git a/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile6.ts b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile6.ts new file mode 100644 index 0000000000..a0497b4deb --- /dev/null +++ b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile6.ts @@ -0,0 +1,17 @@ +/// + +// @allowjs: true +// @noEmit: true +// @checkJs: true + +// @Filename: a.js +////var x = 0; +//// +////function f(_a) { +//// [|f(x());|] +////} + +// Disable checking for next line +verify.rangeAfterCodeFix(`// @ts-suppress + f(x());`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); + diff --git a/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile7.ts b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile7.ts new file mode 100644 index 0000000000..ad8377e129 --- /dev/null +++ b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile7.ts @@ -0,0 +1,17 @@ +/// + +// @allowjs: true +// @noEmit: true +// @checkJs: true + +// @Filename: a.js +////var x = 0; +//// +////function f(_a) { +//// [|x();|] +////} + +// Disable checking for next line +verify.rangeAfterCodeFix(`// @ts-suppress + x();`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); + diff --git a/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile8.ts b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile8.ts new file mode 100644 index 0000000000..8ec350479a --- /dev/null +++ b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile8.ts @@ -0,0 +1,19 @@ +/// + +// @allowjs: true +// @noEmit: true +// @checkJs: true + +// @Filename: a.js +////var x = 0; +//// +////function f(_a) { +//// /** comment for f */ +//// [|f(x());|] +////} + +// Disable checking for next line +verify.rangeAfterCodeFix(`f( + // @ts-suppress + x());`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); + From 13e80b955875248a0a55b5f1926cf1defaaa53e5 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 7 Mar 2017 13:40:15 -0800 Subject: [PATCH 045/164] Fix building webTestServer --- Jakefile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jakefile.js b/Jakefile.js index 595875dfc3..5779d75022 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -945,7 +945,7 @@ task("generate-code-coverage", ["tests", builtLocalDirectory], function () { // Browser tests var nodeServerOutFile = "tests/webTestServer.js"; var nodeServerInFile = "tests/webTestServer.ts"; -compileFile(nodeServerOutFile, [nodeServerInFile], [builtLocalDirectory, tscFile], [], /*useBuiltCompiler:*/ true, { noOutFile: true }); +compileFile(nodeServerOutFile, [nodeServerInFile], [builtLocalDirectory, tscFile], [], /*useBuiltCompiler:*/ true, { noOutFile: true, lib: "es6" }); desc("Runs browserify on run.js to produce a file suitable for running tests in the browser"); task("browserify", ["tests", builtLocalDirectory, nodeServerOutFile], function() { From 936a91d27118c4b836f7549668976bbfe7050be8 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 9 Mar 2017 16:12:58 -0800 Subject: [PATCH 046/164] Add comment --- src/services/codefixes/disableJsDiagnostics.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/services/codefixes/disableJsDiagnostics.ts b/src/services/codefixes/disableJsDiagnostics.ts index 6e4a5f3858..c18c0153a0 100644 --- a/src/services/codefixes/disableJsDiagnostics.ts +++ b/src/services/codefixes/disableJsDiagnostics.ts @@ -20,9 +20,14 @@ namespace ts.codefix { let { line } = getLineAndCharacterOfPosition(sourceFile, position); const lineStartPosition = getStartPositionOfLine(line, sourceFile); const startPosition = getFirstNonSpaceCharacterPosition(sourceFile.text, lineStartPosition); + + // First try to see if we can put the '// @ts-suppress' on the previous line. + // We need to make sure that we are not in the middle of a string literal or a comment. + // We also want to check if the previous line holds a comment for a node on the next line + // if so, we do not want to separate the node from its comment if we can. if (!isInComment(sourceFile, startPosition) && !isInString(sourceFile, startPosition) && !isInTemplateString(sourceFile, startPosition)) { const token = getTouchingToken(sourceFile, startPosition); - const tokenLeadingCommnets = getLeadingCommentRangesOfNode(token, sourceFile) + const tokenLeadingCommnets = getLeadingCommentRangesOfNode(token, sourceFile); if (!tokenLeadingCommnets || !tokenLeadingCommnets.length || tokenLeadingCommnets[0].pos >= startPosition) { return { span: { start: startPosition, length: 0 }, @@ -30,6 +35,8 @@ namespace ts.codefix { }; } } + + // If all fails, add an extra new line immediatlly before the error span. return { span: { start: position, length: 0 }, newText: `${position === startPosition ? "" : newLineCharacter}// @ts-suppress${newLineCharacter}` From fd65966a5028d3403dda934f97fe285cee427198 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Fri, 10 Mar 2017 21:18:18 -0800 Subject: [PATCH 047/164] temp --- src/compiler/checker.ts | 191 ++++++++++++++++++++++++++++++++++++++++ src/compiler/factory.ts | 37 +++++++- src/compiler/types.ts | 21 +++-- 3 files changed, 240 insertions(+), 9 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index aa7908f52c..109e6f33ea 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2388,11 +2388,198 @@ namespace ts { } } + function createTypeNode(type: Type) { + let encounteredError = false; + let checkAlias = true; + + return createTypeNodeWorker(type); + + function createTypeNodeWorker(type: Type): TypeNode { + if(!type) { + return undefined; + } + + if (checkAlias && type.aliasSymbol) { + const name = getNameOfSymbol(type.aliasSymbol); + const typeArguments = mapToTypeNodeArray(type.aliasTypeArguments); + return createTypeReferenceNode(createIdentifier(name), typeArguments); + } + checkAlias = false; + + + if(type.flags & TypeFlags.Any) { + // TODO: add other case where type ends up being `any`. + return createKeywordTypeNode(SyntaxKind.StringKeyword); + } + if(type.flags & TypeFlags.String) { + return createKeywordTypeNode(SyntaxKind.StringKeyword); + } + if(type.flags & TypeFlags.Number) { + return createKeywordTypeNode(SyntaxKind.NumberKeyword); + } + if(type.flags & (TypeFlags.Boolean | TypeFlags.StringOrNumberLiteral)) { + // TODO: check if this actually works with boolean. + return createLiteralTypeNode((type).text); + } + if(type.flags & TypeFlags.Void) { + return createKeywordTypeNode(SyntaxKind.VoidKeyword); + } + if(type.flags & TypeFlags.Undefined) { + return createKeywordTypeNode(SyntaxKind.UndefinedKeyword); + } + if(type.flags & TypeFlags.Null) { + return createKeywordTypeNode(SyntaxKind.NullKeyword); + } + if(type.flags & TypeFlags.Never) { + return createKeywordTypeNode(SyntaxKind.NeverKeyword); + } + if(type.flags & TypeFlags.Enum) { + throw new Error("not implemented"); + } + if(type.flags & TypeFlags.ESSymbol) { + throw new Error("not implemented"); + } + if(type.flags & TypeFlags.TypeParameter) { + const constraint = createTypeNodeWorker(getConstraintFromTypeParameter(type)); + const defaultParameter = createTypeNodeWorker(getDefaultFromTypeParameter(type)); + if(!type.symbol) { + encounteredError = true; + throw new Error("No symbol for type parameter so can't get name"); + } + const name = getNameOfSymbol(type.symbol); + return createTypeParameterNode(name, constraint, defaultParameter); + } + if(type.flags & TypeFlags.Union) { + throw new Error("not implemented"); + } + if(type.flags & TypeFlags.Intersection) { + throw new Error("not implemented"); + } + if(type.flags & TypeFlags.Index) { + throw new Error("not implemented"); + } + if(type.flags & TypeFlags.IndexedAccess) { + throw new Error("not implemented"); + } + + // if(type.flags & TypeFlags.Object) { + // throw new Error("not implemented"); + // } + + // TODO: should these be within the if above (check with asserts) + const objectFlags = getObjectFlags(type); + + if (objectFlags & ObjectFlags.ClassOrInterface) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + // If type is a class or interface type that wasn't hit by the isSymbolAccessible check above, + // type must be an anonymous class or interface. + return false; + } + + if (objectFlags & ObjectFlags.Reference) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + // and vice versa. + // this case includes tuple types + const typeArguments = (type as TypeReference).typeArguments || emptyArray; + return allTypesVisible(typeArguments); + } + + // keyword types + // this type node + // function type node + // constructor type node + // type reference node + // type predicate node - is Foo (for return types) + // type query node -- typeof number + // type literal node (like object literal) + // array type + // tuple type + // union type + // might need parens + // intersection type + // Type operator node (eg (ie?): keyof T) + // IndexedAccess Type Node + // mapped type node + // literal type node + + // if (inTypeAlias && type.aliasSymbol) { + // return isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/false).accessibility === SymbolAccessibility.Accessible + // && (!type.aliasTypeArguments || allTypesVisible(type.aliasTypeArguments)); + // } + // const typeSymbolAccessibility = type.symbol && isSymbolAccessible(type.symbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility; + // if (type.flags & TypeFlags.TypeParameter) { + // if (inObjectLiteral && (type as TypeParameter).isThisType) { + // return false; + // } + // const constraint = getConstraintFromTypeParameter((type)); + // return typeSymbolAccessibility === SymbolAccessibility.Accessible + // && (!constraint || isTypeAccessibleWorker(constraint, inObjectLiteral, /*inTypeAlias*/false)); + // } + // if (typeSymbolAccessibility === SymbolAccessibility.Accessible) { + // return true; + // } + // if (type.flags & (TypeFlags.Intrinsic | TypeFlags.Literal)) { + // return true; + // } + // const objectFlags = getObjectFlags(type); + // if (objectFlags & ObjectFlags.ClassOrInterface) { + // // If type is a class or interface type that wasn't hit by the isSymbolAccessible check above, + // // type must be an anonymous class or interface. + // return false; + // } + // if (objectFlags & ObjectFlags.Reference) { + // // and vice versa. + // // this case includes tuple types + // const typeArguments = (type as TypeReference).typeArguments || emptyArray; + // return allTypesVisible(typeArguments); + // } + // if (type.flags & TypeFlags.UnionOrIntersection) { + // return allTypesVisible((type as UnionOrIntersectionType).types); + // } + + if (objectFlags & ObjectFlags.Mapped) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + const typeParameter = getTypeParameterFromMappedType(type); + const constraintType = getConstraintTypeFromMappedType(type); + const templateType = getTemplateTypeFromMappedType(type); + } + + if (objectFlags & ObjectFlags.Anonymous) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + // The type is an object literal type. + if (!type.symbol) { + // Anonymous types without symbols are literals. + return true; + } + // what case is this? + const members = type.symbol.members; + let allVisible = true; + members && members.forEach((member) => { + const memberType = getTypeOfSymbolAtLocation(member, enclosingDeclaration); + allVisible = allVisible && isTypeAccessibleWorker(memberType, /*inObjectLiteral*/ true, /*inTypeAlias*/false); + }); + return allVisible; + } + + Debug.fail("Should be unreachable here"); + + /** Note that mapToTypeNodeArray(undefined) === undefined. */ + function mapToTypeNodeArray(types: Type[]): NodeArray { + return asNodeArray(types && types.map(createTypeNodeWorker)); + } + // function allTypesVisible(types: Type[]): boolean { + // return types.every(type => isTypeAccessibleWorker(type, inObjectLiteral, /*inTypeAlias*/false)); + // } + } + } + function buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]) { const globalFlagsToPass = globalFlags & TypeFormatFlags.WriteOwnNameForAnyLike; let inObjectTypeLiteral = false; return writeType(type, globalFlags); + const typeNode = createTypeNode(type, enclosingDeclaration); + function writeType(type: Type, flags: TypeFormatFlags) { const nextFlags = flags & ~TypeFormatFlags.InTypeAlias; // Write undefined/null type as any @@ -6939,6 +7126,10 @@ namespace ts { } } + // export function synthesizeTypeNode(type: Type, enclosingDeclaration: Node): TypeNode { + // throw new Error("Not implemented" + enclosingDeclaration); + // } + function instantiateList(items: T[], mapper: TypeMapper, instantiator: (item: T, mapper: TypeMapper) => T): T[] { if (items && items.length) { const result: T[] = []; diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 669c66c433..1e5395fe7b 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -213,8 +213,43 @@ namespace ts { : node; } + // Types + + export function createLiteralTypeNode(value: string | number | boolean) { + const literal = createLiteral(value); + const literalTypeNode = createSynthesizedNode(SyntaxKind.LiteralType) as LiteralTypeNode; + literalTypeNode.literal = literal; + return literalTypeNode; + } + + export function createTypeReferenceNode(typeName: string | EntityName, typeArguments?: NodeArray) { + const typeReference = createSynthesizedNode(SyntaxKind.TypeReference) as TypeReferenceNode; + typeReference.typeName = asName(typeName); + typeReference.typeName.parent + typeReference.typeArguments = typeArguments; + return typeReference; + } + + export function createTypeParameterNode(name: string | Identifier, constraint?: TypeNode, defaultParameter?: TypeNode) { + const typeParameter = createSynthesizedNode(SyntaxKind.TypeParameter) as TypeParameterDeclaration; + typeParameter.name = asName(name); + typeParameter.constraint = constraint; + typeParameter.default = defaultParameter; + + return typeParameter; + } + // Signature elements + export function createSignature(kind: SyntaxKind, parameters: NodeArray, name?: PropertyName, typeParameters?: NodeArray, returnType?: TypeNode): SignatureDeclaration { + const signature = createSynthesizedNode(kind) as SignatureDeclaration; + signature.parameters = parameters; + signature.name = name; + signature.typeParameters = typeParameters; + signature.type = returnType; + return signature; + } + export function createParameter(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression) { const node = createSynthesizedNode(SyntaxKind.Parameter); node.decorators = asNodeArray(decorators); @@ -1801,7 +1836,7 @@ namespace ts { return typeof value === "string" || typeof value === "number" ? createLiteral(value) : value; } - function asNodeArray(array: T[] | undefined): NodeArray | undefined { + export function asNodeArray(array: T[] | undefined): NodeArray | undefined { return array ? createNodeArray(array) : undefined; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 1492a106d2..52207920b4 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -849,14 +849,19 @@ namespace ts { _typeNodeBrand: any; } + export type KeywordKind = SyntaxKind.AnyKeyword + | SyntaxKind.NumberKeyword + | SyntaxKind.ObjectKeyword + | SyntaxKind.BooleanKeyword + | SyntaxKind.StringKeyword + | SyntaxKind.SymbolKeyword + | SyntaxKind.VoidKeyword + | SyntaxKind.UndefinedKeyword + | SyntaxKind.NullKeyword + | SyntaxKind.NeverKeyword; + export interface KeywordTypeNode extends TypeNode { - kind: SyntaxKind.AnyKeyword - | SyntaxKind.NumberKeyword - | SyntaxKind.ObjectKeyword - | SyntaxKind.BooleanKeyword - | SyntaxKind.StringKeyword - | SyntaxKind.SymbolKeyword - | SyntaxKind.VoidKeyword; + kind: KeywordKind; } export interface ThisTypeNode extends TypeNode { @@ -892,7 +897,7 @@ namespace ts { exprName: EntityName; } - // A TypeLiteral is the declaration node for an anonymous symbol. + /** A TypeLiteral is the declaration node for an anonymous symbol. */ export interface TypeLiteralNode extends TypeNode, Declaration { kind: SyntaxKind.TypeLiteral; members: NodeArray; From c6693983f42d570fd4b30f73c2c4506d11a6b326 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Sat, 11 Mar 2017 09:10:26 -0800 Subject: [PATCH 048/164] Revert "temp" This reverts commit fd65966a5028d3403dda934f97fe285cee427198. Accidentally pushed to the wrong branch. --- src/compiler/checker.ts | 191 ---------------------------------------- src/compiler/factory.ts | 37 +------- src/compiler/types.ts | 21 ++--- 3 files changed, 9 insertions(+), 240 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 109e6f33ea..aa7908f52c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2388,198 +2388,11 @@ namespace ts { } } - function createTypeNode(type: Type) { - let encounteredError = false; - let checkAlias = true; - - return createTypeNodeWorker(type); - - function createTypeNodeWorker(type: Type): TypeNode { - if(!type) { - return undefined; - } - - if (checkAlias && type.aliasSymbol) { - const name = getNameOfSymbol(type.aliasSymbol); - const typeArguments = mapToTypeNodeArray(type.aliasTypeArguments); - return createTypeReferenceNode(createIdentifier(name), typeArguments); - } - checkAlias = false; - - - if(type.flags & TypeFlags.Any) { - // TODO: add other case where type ends up being `any`. - return createKeywordTypeNode(SyntaxKind.StringKeyword); - } - if(type.flags & TypeFlags.String) { - return createKeywordTypeNode(SyntaxKind.StringKeyword); - } - if(type.flags & TypeFlags.Number) { - return createKeywordTypeNode(SyntaxKind.NumberKeyword); - } - if(type.flags & (TypeFlags.Boolean | TypeFlags.StringOrNumberLiteral)) { - // TODO: check if this actually works with boolean. - return createLiteralTypeNode((type).text); - } - if(type.flags & TypeFlags.Void) { - return createKeywordTypeNode(SyntaxKind.VoidKeyword); - } - if(type.flags & TypeFlags.Undefined) { - return createKeywordTypeNode(SyntaxKind.UndefinedKeyword); - } - if(type.flags & TypeFlags.Null) { - return createKeywordTypeNode(SyntaxKind.NullKeyword); - } - if(type.flags & TypeFlags.Never) { - return createKeywordTypeNode(SyntaxKind.NeverKeyword); - } - if(type.flags & TypeFlags.Enum) { - throw new Error("not implemented"); - } - if(type.flags & TypeFlags.ESSymbol) { - throw new Error("not implemented"); - } - if(type.flags & TypeFlags.TypeParameter) { - const constraint = createTypeNodeWorker(getConstraintFromTypeParameter(type)); - const defaultParameter = createTypeNodeWorker(getDefaultFromTypeParameter(type)); - if(!type.symbol) { - encounteredError = true; - throw new Error("No symbol for type parameter so can't get name"); - } - const name = getNameOfSymbol(type.symbol); - return createTypeParameterNode(name, constraint, defaultParameter); - } - if(type.flags & TypeFlags.Union) { - throw new Error("not implemented"); - } - if(type.flags & TypeFlags.Intersection) { - throw new Error("not implemented"); - } - if(type.flags & TypeFlags.Index) { - throw new Error("not implemented"); - } - if(type.flags & TypeFlags.IndexedAccess) { - throw new Error("not implemented"); - } - - // if(type.flags & TypeFlags.Object) { - // throw new Error("not implemented"); - // } - - // TODO: should these be within the if above (check with asserts) - const objectFlags = getObjectFlags(type); - - if (objectFlags & ObjectFlags.ClassOrInterface) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - // If type is a class or interface type that wasn't hit by the isSymbolAccessible check above, - // type must be an anonymous class or interface. - return false; - } - - if (objectFlags & ObjectFlags.Reference) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - // and vice versa. - // this case includes tuple types - const typeArguments = (type as TypeReference).typeArguments || emptyArray; - return allTypesVisible(typeArguments); - } - - // keyword types - // this type node - // function type node - // constructor type node - // type reference node - // type predicate node - is Foo (for return types) - // type query node -- typeof number - // type literal node (like object literal) - // array type - // tuple type - // union type - // might need parens - // intersection type - // Type operator node (eg (ie?): keyof T) - // IndexedAccess Type Node - // mapped type node - // literal type node - - // if (inTypeAlias && type.aliasSymbol) { - // return isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/false).accessibility === SymbolAccessibility.Accessible - // && (!type.aliasTypeArguments || allTypesVisible(type.aliasTypeArguments)); - // } - // const typeSymbolAccessibility = type.symbol && isSymbolAccessible(type.symbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility; - // if (type.flags & TypeFlags.TypeParameter) { - // if (inObjectLiteral && (type as TypeParameter).isThisType) { - // return false; - // } - // const constraint = getConstraintFromTypeParameter((type)); - // return typeSymbolAccessibility === SymbolAccessibility.Accessible - // && (!constraint || isTypeAccessibleWorker(constraint, inObjectLiteral, /*inTypeAlias*/false)); - // } - // if (typeSymbolAccessibility === SymbolAccessibility.Accessible) { - // return true; - // } - // if (type.flags & (TypeFlags.Intrinsic | TypeFlags.Literal)) { - // return true; - // } - // const objectFlags = getObjectFlags(type); - // if (objectFlags & ObjectFlags.ClassOrInterface) { - // // If type is a class or interface type that wasn't hit by the isSymbolAccessible check above, - // // type must be an anonymous class or interface. - // return false; - // } - // if (objectFlags & ObjectFlags.Reference) { - // // and vice versa. - // // this case includes tuple types - // const typeArguments = (type as TypeReference).typeArguments || emptyArray; - // return allTypesVisible(typeArguments); - // } - // if (type.flags & TypeFlags.UnionOrIntersection) { - // return allTypesVisible((type as UnionOrIntersectionType).types); - // } - - if (objectFlags & ObjectFlags.Mapped) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - const typeParameter = getTypeParameterFromMappedType(type); - const constraintType = getConstraintTypeFromMappedType(type); - const templateType = getTemplateTypeFromMappedType(type); - } - - if (objectFlags & ObjectFlags.Anonymous) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - // The type is an object literal type. - if (!type.symbol) { - // Anonymous types without symbols are literals. - return true; - } - // what case is this? - const members = type.symbol.members; - let allVisible = true; - members && members.forEach((member) => { - const memberType = getTypeOfSymbolAtLocation(member, enclosingDeclaration); - allVisible = allVisible && isTypeAccessibleWorker(memberType, /*inObjectLiteral*/ true, /*inTypeAlias*/false); - }); - return allVisible; - } - - Debug.fail("Should be unreachable here"); - - /** Note that mapToTypeNodeArray(undefined) === undefined. */ - function mapToTypeNodeArray(types: Type[]): NodeArray { - return asNodeArray(types && types.map(createTypeNodeWorker)); - } - // function allTypesVisible(types: Type[]): boolean { - // return types.every(type => isTypeAccessibleWorker(type, inObjectLiteral, /*inTypeAlias*/false)); - // } - } - } - function buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]) { const globalFlagsToPass = globalFlags & TypeFormatFlags.WriteOwnNameForAnyLike; let inObjectTypeLiteral = false; return writeType(type, globalFlags); - const typeNode = createTypeNode(type, enclosingDeclaration); - function writeType(type: Type, flags: TypeFormatFlags) { const nextFlags = flags & ~TypeFormatFlags.InTypeAlias; // Write undefined/null type as any @@ -7126,10 +6939,6 @@ namespace ts { } } - // export function synthesizeTypeNode(type: Type, enclosingDeclaration: Node): TypeNode { - // throw new Error("Not implemented" + enclosingDeclaration); - // } - function instantiateList(items: T[], mapper: TypeMapper, instantiator: (item: T, mapper: TypeMapper) => T): T[] { if (items && items.length) { const result: T[] = []; diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 1e5395fe7b..669c66c433 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -213,43 +213,8 @@ namespace ts { : node; } - // Types - - export function createLiteralTypeNode(value: string | number | boolean) { - const literal = createLiteral(value); - const literalTypeNode = createSynthesizedNode(SyntaxKind.LiteralType) as LiteralTypeNode; - literalTypeNode.literal = literal; - return literalTypeNode; - } - - export function createTypeReferenceNode(typeName: string | EntityName, typeArguments?: NodeArray) { - const typeReference = createSynthesizedNode(SyntaxKind.TypeReference) as TypeReferenceNode; - typeReference.typeName = asName(typeName); - typeReference.typeName.parent - typeReference.typeArguments = typeArguments; - return typeReference; - } - - export function createTypeParameterNode(name: string | Identifier, constraint?: TypeNode, defaultParameter?: TypeNode) { - const typeParameter = createSynthesizedNode(SyntaxKind.TypeParameter) as TypeParameterDeclaration; - typeParameter.name = asName(name); - typeParameter.constraint = constraint; - typeParameter.default = defaultParameter; - - return typeParameter; - } - // Signature elements - export function createSignature(kind: SyntaxKind, parameters: NodeArray, name?: PropertyName, typeParameters?: NodeArray, returnType?: TypeNode): SignatureDeclaration { - const signature = createSynthesizedNode(kind) as SignatureDeclaration; - signature.parameters = parameters; - signature.name = name; - signature.typeParameters = typeParameters; - signature.type = returnType; - return signature; - } - export function createParameter(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression) { const node = createSynthesizedNode(SyntaxKind.Parameter); node.decorators = asNodeArray(decorators); @@ -1836,7 +1801,7 @@ namespace ts { return typeof value === "string" || typeof value === "number" ? createLiteral(value) : value; } - export function asNodeArray(array: T[] | undefined): NodeArray | undefined { + function asNodeArray(array: T[] | undefined): NodeArray | undefined { return array ? createNodeArray(array) : undefined; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 52207920b4..1492a106d2 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -849,19 +849,14 @@ namespace ts { _typeNodeBrand: any; } - export type KeywordKind = SyntaxKind.AnyKeyword - | SyntaxKind.NumberKeyword - | SyntaxKind.ObjectKeyword - | SyntaxKind.BooleanKeyword - | SyntaxKind.StringKeyword - | SyntaxKind.SymbolKeyword - | SyntaxKind.VoidKeyword - | SyntaxKind.UndefinedKeyword - | SyntaxKind.NullKeyword - | SyntaxKind.NeverKeyword; - export interface KeywordTypeNode extends TypeNode { - kind: KeywordKind; + kind: SyntaxKind.AnyKeyword + | SyntaxKind.NumberKeyword + | SyntaxKind.ObjectKeyword + | SyntaxKind.BooleanKeyword + | SyntaxKind.StringKeyword + | SyntaxKind.SymbolKeyword + | SyntaxKind.VoidKeyword; } export interface ThisTypeNode extends TypeNode { @@ -897,7 +892,7 @@ namespace ts { exprName: EntityName; } - /** A TypeLiteral is the declaration node for an anonymous symbol. */ + // A TypeLiteral is the declaration node for an anonymous symbol. export interface TypeLiteralNode extends TypeNode, Declaration { kind: SyntaxKind.TypeLiteral; members: NodeArray; From fff531ca25e251942bd7c9af3716d986f9774d67 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Sat, 11 Mar 2017 15:16:28 -0800 Subject: [PATCH 049/164] more temp --- src/compiler/checker.ts | 389 +++++++++--------- src/compiler/factory.ts | 66 ++- src/compiler/types.ts | 4 +- src/services/codefixes/fixAddMissingMember.ts | 49 ++- .../fixClassSuperMustPrecedeThisAccess.ts | 2 +- src/services/utilities.ts | 4 + 6 files changed, 302 insertions(+), 212 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 109e6f33ea..3ed15f8b03 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -106,6 +106,7 @@ namespace ts { getParameterType: getTypeAtPosition, getReturnTypeOfSignature, getNonNullableType, + createTypeNode, getSymbolsInScope: (location, meaning) => { location = getParseTreeNode(location); return location ? getSymbolsInScope(location, meaning) : []; @@ -2188,6 +2189,207 @@ namespace ts { return result; } + function createTypeNode(type: Type) { + let encounteredError = false; + let checkAlias = true; + + return createTypeNodeWorker(type); + + // function createTypeDeclaration(type: Type): Declaration { + // if (!type) { + // return undefined; + // } + // throw new Error("not implemented."); + // } + + function createTypeNodeWorker(type: Type): TypeNode { + if (!type) { + return undefined; + } + + if (checkAlias && type.aliasSymbol) { + const name = getNameOfSymbol(type.aliasSymbol); + const typeArguments = mapToTypeNodeArray(type.aliasTypeArguments); + return createTypeReferenceNode(createIdentifier(name), typeArguments); + } + checkAlias = false; + + if (type.flags & TypeFlags.Any) { + // TODO: add other case where type ends up being `any`. + return createKeywordTypeNode(SyntaxKind.StringKeyword); + } + if (type.flags & TypeFlags.String) { + return createKeywordTypeNode(SyntaxKind.StringKeyword); + } + if (type.flags & TypeFlags.Number) { + return createKeywordTypeNode(SyntaxKind.NumberKeyword); + } + if (type.flags & (TypeFlags.Boolean | TypeFlags.StringOrNumberLiteral)) { + // TODO: check if this actually works with boolean. + return createLiteralTypeNode((type).text); + } + if (type.flags & TypeFlags.Void) { + return createKeywordTypeNode(SyntaxKind.VoidKeyword); + } + if (type.flags & TypeFlags.Undefined) { + return createKeywordTypeNode(SyntaxKind.UndefinedKeyword); + } + if (type.flags & TypeFlags.Null) { + return createKeywordTypeNode(SyntaxKind.NullKeyword); + } + if (type.flags & TypeFlags.Never) { + return createKeywordTypeNode(SyntaxKind.NeverKeyword); + } + if (type.flags & TypeFlags.Enum) { + throw new Error("not implemented"); + } + if (type.flags & TypeFlags.ESSymbol) { + throw new Error("not implemented"); + } + if (type.flags & TypeFlags.TypeParameter) { + throw new Error("Type Parameter declarations only handled in other worker."); + // const constraint = createTypeNodeWorker(getConstraintFromTypeParameter(type)) as TypeNode; + // const defaultParameter = createTypeNodeWorker(getDefaultFromTypeParameter(type)) as TypeNode; + // if (!type.symbol) { + // encounteredError = true; + // throw new Error("No symbol for type parameter so can't get name"); + // } + // const name = getNameOfSymbol(type.symbol); + // return createTypeParameterNode(name, constraint, defaultParameter); + } + if (type.flags & TypeFlags.Union) { + throw new Error("not implemented"); + } + if (type.flags & TypeFlags.Intersection) { + throw new Error("not implemented"); + } + if (type.flags & TypeFlags.Index) { + throw new Error("not implemented"); + } + if (type.flags & TypeFlags.IndexedAccess) { + throw new Error("not implemented"); + } + + // if(type.flags & TypeFlags.Object) { + // throw new Error("not implemented"); + // } + + // TODO: should these be within the if above (check with asserts) + const objectFlags = getObjectFlags(type); + + if (objectFlags & ObjectFlags.ClassOrInterface) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + // If type is a class or interface type that wasn't hit by the isSymbolAccessible check above, + // type must be an anonymous class or interface. + + encounteredError = true; + return undefined; + } + + if (objectFlags & ObjectFlags.Reference) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + // and vice versa. + // this case includes tuple types + // TODO: test empty tuples, see if they are coherent. + const typeArguments = (type as TypeReference).typeArguments || emptyArray; + return createTupleTypeNode(mapToTypeNodeArray(typeArguments)) + } + + // keyword types + // this type node + // function type node + // constructor type node + // type reference node + // type predicate node - is Foo (for return types) + // type query node -- typeof number + // type literal node (like object literal) + // array type + // tuple type + // union type + // might need parens + // intersection type + // Type operator node (eg (ie?): keyof T) + // IndexedAccess Type Node + // mapped type node + // literal type node + + // if (inTypeAlias && type.aliasSymbol) { + // return isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/false).accessibility === SymbolAccessibility.Accessible + // && (!type.aliasTypeArguments || allTypesVisible(type.aliasTypeArguments)); + // } + // const typeSymbolAccessibility = type.symbol && isSymbolAccessible(type.symbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility; + // if (type.flags & TypeFlags.TypeParameter) { + // if (inObjectLiteral && (type as TypeParameter).isThisType) { + // return false; + // } + // const constraint = getConstraintFromTypeParameter((type)); + // return typeSymbolAccessibility === SymbolAccessibility.Accessible + // && (!constraint || isTypeAccessibleWorker(constraint, inObjectLiteral, /*inTypeAlias*/false)); + // } + // if (typeSymbolAccessibility === SymbolAccessibility.Accessible) { + // return true; + // } + // if (type.flags & (TypeFlags.Intrinsic | TypeFlags.Literal)) { + // return true; + // } + // const objectFlags = getObjectFlags(type); + // if (objectFlags & ObjectFlags.ClassOrInterface) { + // // If type is a class or interface type that wasn't hit by the isSymbolAccessible check above, + // // type must be an anonymous class or interface. + // return false; + // } + // if (objectFlags & ObjectFlags.Reference) { + // // and vice versa. + // // this case includes tuple types + // const typeArguments = (type as TypeReference).typeArguments || emptyArray; + // return allTypesVisible(typeArguments); + // } + // if (type.flags & TypeFlags.UnionOrIntersection) { + // return allTypesVisible((type as UnionOrIntersectionType).types); + // } + + if (objectFlags & ObjectFlags.Mapped) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + // const typeParameter = getTypeParameterFromMappedType(type); + // const constraintType = getConstraintTypeFromMappedType(type); + // const templateType = getTemplateTypeFromMappedType(type); + throw new Error("Mapped types not implemented"); + } + + if (objectFlags & ObjectFlags.Anonymous) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + // The type is an object literal type. + if (!type.symbol) { + // Anonymous types without symbols are literals. + + + // mapToTypeDeclarationsArray(type) + throw new Error("object literal types not implemented."); + } + // what case is this? + throw new Error("unknown case.") + // const members = type.symbol.members; + // let allVisible = true; + // members && members.forEach((member) => { + // const memberType = getTypeOfSymbolAtLocation(member, enclosingDeclaration); + // allVisible = allVisible && isTypeAccessibleWorker(memberType, /*inObjectLiteral*/ true, /*inTypeAlias*/false); + // }); + // return allVisible; + } + + Debug.fail("Should be unreachable."); + + /** Note that mapToTypeNodeArray(undefined) === undefined. */ + function mapToTypeNodeArray(types: Type[]): NodeArray { + return asNodeArray(types && types.map(createTypeNodeWorker) as TypeNode[]); + } + + // function mapToTypeDeclarationsArray(types: Type[]): NodeArray { + // return asNodeArray(types && types.map(createTypeDeclaration)); + // } + } + } + function typePredicateToString(typePredicate: TypePredicate, enclosingDeclaration?: Declaration, flags?: TypeFormatFlags): string { const writer = getSingleLineStringWriter(); getSymbolDisplayBuilder().buildTypePredicateDisplay(typePredicate, writer, enclosingDeclaration, flags); @@ -2388,198 +2590,11 @@ namespace ts { } } - function createTypeNode(type: Type) { - let encounteredError = false; - let checkAlias = true; - - return createTypeNodeWorker(type); - - function createTypeNodeWorker(type: Type): TypeNode { - if(!type) { - return undefined; - } - - if (checkAlias && type.aliasSymbol) { - const name = getNameOfSymbol(type.aliasSymbol); - const typeArguments = mapToTypeNodeArray(type.aliasTypeArguments); - return createTypeReferenceNode(createIdentifier(name), typeArguments); - } - checkAlias = false; - - - if(type.flags & TypeFlags.Any) { - // TODO: add other case where type ends up being `any`. - return createKeywordTypeNode(SyntaxKind.StringKeyword); - } - if(type.flags & TypeFlags.String) { - return createKeywordTypeNode(SyntaxKind.StringKeyword); - } - if(type.flags & TypeFlags.Number) { - return createKeywordTypeNode(SyntaxKind.NumberKeyword); - } - if(type.flags & (TypeFlags.Boolean | TypeFlags.StringOrNumberLiteral)) { - // TODO: check if this actually works with boolean. - return createLiteralTypeNode((type).text); - } - if(type.flags & TypeFlags.Void) { - return createKeywordTypeNode(SyntaxKind.VoidKeyword); - } - if(type.flags & TypeFlags.Undefined) { - return createKeywordTypeNode(SyntaxKind.UndefinedKeyword); - } - if(type.flags & TypeFlags.Null) { - return createKeywordTypeNode(SyntaxKind.NullKeyword); - } - if(type.flags & TypeFlags.Never) { - return createKeywordTypeNode(SyntaxKind.NeverKeyword); - } - if(type.flags & TypeFlags.Enum) { - throw new Error("not implemented"); - } - if(type.flags & TypeFlags.ESSymbol) { - throw new Error("not implemented"); - } - if(type.flags & TypeFlags.TypeParameter) { - const constraint = createTypeNodeWorker(getConstraintFromTypeParameter(type)); - const defaultParameter = createTypeNodeWorker(getDefaultFromTypeParameter(type)); - if(!type.symbol) { - encounteredError = true; - throw new Error("No symbol for type parameter so can't get name"); - } - const name = getNameOfSymbol(type.symbol); - return createTypeParameterNode(name, constraint, defaultParameter); - } - if(type.flags & TypeFlags.Union) { - throw new Error("not implemented"); - } - if(type.flags & TypeFlags.Intersection) { - throw new Error("not implemented"); - } - if(type.flags & TypeFlags.Index) { - throw new Error("not implemented"); - } - if(type.flags & TypeFlags.IndexedAccess) { - throw new Error("not implemented"); - } - - // if(type.flags & TypeFlags.Object) { - // throw new Error("not implemented"); - // } - - // TODO: should these be within the if above (check with asserts) - const objectFlags = getObjectFlags(type); - - if (objectFlags & ObjectFlags.ClassOrInterface) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - // If type is a class or interface type that wasn't hit by the isSymbolAccessible check above, - // type must be an anonymous class or interface. - return false; - } - - if (objectFlags & ObjectFlags.Reference) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - // and vice versa. - // this case includes tuple types - const typeArguments = (type as TypeReference).typeArguments || emptyArray; - return allTypesVisible(typeArguments); - } - - // keyword types - // this type node - // function type node - // constructor type node - // type reference node - // type predicate node - is Foo (for return types) - // type query node -- typeof number - // type literal node (like object literal) - // array type - // tuple type - // union type - // might need parens - // intersection type - // Type operator node (eg (ie?): keyof T) - // IndexedAccess Type Node - // mapped type node - // literal type node - - // if (inTypeAlias && type.aliasSymbol) { - // return isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/false).accessibility === SymbolAccessibility.Accessible - // && (!type.aliasTypeArguments || allTypesVisible(type.aliasTypeArguments)); - // } - // const typeSymbolAccessibility = type.symbol && isSymbolAccessible(type.symbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility; - // if (type.flags & TypeFlags.TypeParameter) { - // if (inObjectLiteral && (type as TypeParameter).isThisType) { - // return false; - // } - // const constraint = getConstraintFromTypeParameter((type)); - // return typeSymbolAccessibility === SymbolAccessibility.Accessible - // && (!constraint || isTypeAccessibleWorker(constraint, inObjectLiteral, /*inTypeAlias*/false)); - // } - // if (typeSymbolAccessibility === SymbolAccessibility.Accessible) { - // return true; - // } - // if (type.flags & (TypeFlags.Intrinsic | TypeFlags.Literal)) { - // return true; - // } - // const objectFlags = getObjectFlags(type); - // if (objectFlags & ObjectFlags.ClassOrInterface) { - // // If type is a class or interface type that wasn't hit by the isSymbolAccessible check above, - // // type must be an anonymous class or interface. - // return false; - // } - // if (objectFlags & ObjectFlags.Reference) { - // // and vice versa. - // // this case includes tuple types - // const typeArguments = (type as TypeReference).typeArguments || emptyArray; - // return allTypesVisible(typeArguments); - // } - // if (type.flags & TypeFlags.UnionOrIntersection) { - // return allTypesVisible((type as UnionOrIntersectionType).types); - // } - - if (objectFlags & ObjectFlags.Mapped) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - const typeParameter = getTypeParameterFromMappedType(type); - const constraintType = getConstraintTypeFromMappedType(type); - const templateType = getTemplateTypeFromMappedType(type); - } - - if (objectFlags & ObjectFlags.Anonymous) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - // The type is an object literal type. - if (!type.symbol) { - // Anonymous types without symbols are literals. - return true; - } - // what case is this? - const members = type.symbol.members; - let allVisible = true; - members && members.forEach((member) => { - const memberType = getTypeOfSymbolAtLocation(member, enclosingDeclaration); - allVisible = allVisible && isTypeAccessibleWorker(memberType, /*inObjectLiteral*/ true, /*inTypeAlias*/false); - }); - return allVisible; - } - - Debug.fail("Should be unreachable here"); - - /** Note that mapToTypeNodeArray(undefined) === undefined. */ - function mapToTypeNodeArray(types: Type[]): NodeArray { - return asNodeArray(types && types.map(createTypeNodeWorker)); - } - // function allTypesVisible(types: Type[]): boolean { - // return types.every(type => isTypeAccessibleWorker(type, inObjectLiteral, /*inTypeAlias*/false)); - // } - } - } - function buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]) { const globalFlagsToPass = globalFlags & TypeFormatFlags.WriteOwnNameForAnyLike; let inObjectTypeLiteral = false; return writeType(type, globalFlags); - const typeNode = createTypeNode(type, enclosingDeclaration); - function writeType(type: Type, flags: TypeFormatFlags) { const nextFlags = flags & ~TypeFormatFlags.InTypeAlias; // Write undefined/null type as any diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 1e5395fe7b..3633cc657a 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -213,8 +213,28 @@ namespace ts { : node; } + // Type Elements + + export function createPropertySignature(name: PropertyName, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression): PropertySignature { + const propertySignature = createSynthesizedNode(SyntaxKind.PropertySignature) as PropertySignature; + propertySignature.name = name; + propertySignature.questionToken = questionToken; + propertySignature.type = type; + propertySignature.initializer = initializer; + return propertySignature; + } + + export function createConstructSignature() { + throw new Error("not implemented."); + } + // Types + export function createKeywordTypeNode(kind: KeywordTypeNode["kind"]): KeywordTypeNode { + return createSynthesizedNode(kind); + } + + export function createLiteralTypeNode(value: string | number | boolean) { const literal = createLiteral(value); const literalTypeNode = createSynthesizedNode(SyntaxKind.LiteralType) as LiteralTypeNode; @@ -222,7 +242,8 @@ namespace ts { return literalTypeNode; } - export function createTypeReferenceNode(typeName: string | EntityName, typeArguments?: NodeArray) { + // TODO: handle qualified names, ie EntityName's. + export function createTypeReferenceNode(typeName: string | Identifier, typeArguments?: NodeArray) { const typeReference = createSynthesizedNode(SyntaxKind.TypeReference) as TypeReferenceNode; typeReference.typeName = asName(typeName); typeReference.typeName.parent @@ -239,8 +260,34 @@ namespace ts { return typeParameter; } + export function createUnionTypeNode(types: NodeArray) { + const unionTypeNode = createSynthesizedNode(SyntaxKind.UnionType) as UnionTypeNode; + unionTypeNode.types = asNodeArray(types); + return unionTypeNode; + } + + export function createIntersectionTypeNode(types: NodeArray) { + const intersectionTypeNode = createSynthesizedNode(SyntaxKind.IntersectionType) as IntersectionTypeNode; + intersectionTypeNode.types = asNodeArray(types); + return intersectionTypeNode; + } + + export function createTypeLiteralNode(typeElements: TypeElement[]) { + const typeLiteralNode = createSynthesizedNode(SyntaxKind.LiteralType) as TypeLiteralNode; + typeLiteralNode.members = asNodeArray(typeElements); + return typeLiteralNode; + } + + export function createTupleTypeNode(types: NodeArray) { + const tupleTypeNode = createSynthesizedNode(SyntaxKind.TupleType) as TupleTypeNode; + tupleTypeNode.elementTypes = asNodeArray(types); + return tupleTypeNode; + } + + // Signature elements + /** Note, can also be used to construct index signatures. */ export function createSignature(kind: SyntaxKind, parameters: NodeArray, name?: PropertyName, typeParameters?: NodeArray, returnType?: TypeNode): SignatureDeclaration { const signature = createSynthesizedNode(kind) as SignatureDeclaration; signature.parameters = parameters; @@ -250,6 +297,19 @@ namespace ts { return signature; } + // TODO: check usage of name... + export function createIndexSignature(parameter: ParameterDeclaration, type: TypeNode, decorators?: Decorator[], modifiers?: Modifier[]): IndexSignatureDeclaration { + const indexSignature = createSignature( + SyntaxKind.IndexSignature + , asNodeArray([parameter]) + , /*name*/ undefined + , /*typeParameters*/undefined + , type) as IndexSignatureDeclaration; + indexSignature.decorators = asNodeArray(decorators); + indexSignature.modifiers = asNodeArray(modifiers); + return indexSignature; + } + export function createParameter(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression) { const node = createSynthesizedNode(SyntaxKind.Parameter); node.decorators = asNodeArray(decorators); @@ -1134,10 +1194,6 @@ namespace ts { : node; } - export function createKeywordTypeNode(kind: KeywordTypeNode["kind"]): KeywordTypeNode { - return createSynthesizedNode(kind); - } - export function createFunctionDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) { const node = createSynthesizedNode(SyntaxKind.FunctionDeclaration); node.decorators = asNodeArray(decorators); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 52207920b4..4fd4dd1780 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -673,7 +673,7 @@ namespace ts { initializer?: Expression; // Optional initializer } - export interface BindingElement extends Declaration { + export interface BindingElement extends Declaration { kind: SyntaxKind.BindingElement; parent?: BindingPattern; propertyName?: PropertyName; // Binding property name (in object binding pattern) @@ -2468,6 +2468,8 @@ namespace ts { */ /* @internal */ getParameterType(signature: Signature, parameterIndex: number): Type; getNonNullableType(type: Type): Type; + /** Note that the resulting type node cannot be checked. */ + createTypeNode(type: Type): TypeNode; getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; getSymbolAtLocation(node: Node): Symbol; diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index 6ae2ba3f51..05ff29f069 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -31,37 +31,50 @@ namespace ts.codefix { return undefined; } - let typeString = "any"; + let typeNode: TypeNode = createKeywordTypeNode(SyntaxKind.AnyKeyword); if (token.parent.parent.kind === SyntaxKind.BinaryExpression) { const binaryExpression = token.parent.parent as BinaryExpression; const checker = context.program.getTypeChecker(); const widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(binaryExpression.right))); - typeString = checker.typeToString(widenedType); + typeNode = checker.createTypeNode(widenedType) || typeNode; } - const startPos = classDeclaration.members.pos; + const openBrace = getOpenBraceOfClassLike(classDeclaration, sourceFile); - return [{ + const property = createProperty( + /*decorators*/undefined + , /*modifiers*/ undefined + , token.getText(sourceFile) + , /*questionToken*/ undefined + , typeNode + , /*initializer*/ undefined); + // TODO: make index signature. + const propertyChangeTracker = textChanges.ChangeTracker.fromCodeFixContext(context); + propertyChangeTracker.insertNodeAfter(sourceFile, openBrace, property, { insertTrailingNewLine: true }); + + const stringTypeNode = createKeywordTypeNode(SyntaxKind.StringKeyword); + const indexingParameter = createParameter( + /*decorators*/ undefined + , /*modifiers*/ undefined + , /*dotDotDotToken*/ undefined + , "name" + , /*questionToken*/ undefined + , stringTypeNode); + const indexSignature = createIndexSignature(indexingParameter, typeNode); + + // const startPos = classDeclaration.members.pos; + const indexSignatureChangeTracker = textChanges.ChangeTracker.fromCodeFixContext(context); + indexSignatureChangeTracker.insertNodeAfter(sourceFile, openBrace, indexSignature, { insertTrailingNewLine: true }); + + return [{ description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_declaration_for_missing_property_0), [token.getText()]), - changes: [{ - fileName: sourceFile.fileName, - textChanges: [{ - span: { start: startPos, length: 0 }, - newText: `${token.getFullText(sourceFile)}: ${typeString};` - }] - }] + changes: propertyChangeTracker.getChanges() }, { description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_index_signature_for_missing_property_0), [token.getText()]), - changes: [{ - fileName: sourceFile.fileName, - textChanges: [{ - span: { start: startPos, length: 0 }, - newText: `[name: string]: ${typeString};` - }] - }] + changes: indexSignatureChangeTracker.getChanges() }]; } } \ No newline at end of file diff --git a/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts b/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts index 207d039df8..63fc846f8c 100644 --- a/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts +++ b/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts @@ -16,7 +16,7 @@ namespace ts.codefix { return undefined; } - // figure out if the this access is actuall inside the supercall + // figure out if the `this` access is actually inside the supercall // i.e. super(this.a), since in that case we won't suggest a fix if (superCall.expression && superCall.expression.kind == SyntaxKind.CallExpression) { const arguments = (superCall.expression).arguments; diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 1b32b3bbad..0fed656af5 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1384,4 +1384,8 @@ namespace ts { // First token is the open curly, this is where we want to put the 'super' call. return constructor.body.getFirstToken(sourceFile); } + + export function getOpenBraceOfClassLike(declaration: ClassLikeDeclaration, sourceFile: SourceFile) { + return getTokenAtPosition(sourceFile, declaration.members.pos); + } } From bf2acf1d2cdf51fb462561f054d6dd0f01bd8aef Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Sat, 11 Mar 2017 18:58:46 -0800 Subject: [PATCH 050/164] basic end-to-end building type nodes --- src/compiler/checker.ts | 23 +++-- src/compiler/factory.ts | 99 +++++++++++++------ src/compiler/types.ts | 24 +++-- src/compiler/visitor.ts | 68 +++++++++++-- src/services/codefixes/fixAddMissingMember.ts | 5 +- src/services/utilities.ts | 2 +- 6 files changed, 159 insertions(+), 62 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3ed15f8b03..f29204f7ca 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2190,7 +2190,7 @@ namespace ts { } function createTypeNode(type: Type) { - let encounteredError = false; + // let encounteredError = false; let checkAlias = true; return createTypeNodeWorker(type); @@ -2224,9 +2224,17 @@ namespace ts { if (type.flags & TypeFlags.Number) { return createKeywordTypeNode(SyntaxKind.NumberKeyword); } - if (type.flags & (TypeFlags.Boolean | TypeFlags.StringOrNumberLiteral)) { + if(type.flags & TypeFlags.Boolean) { + // TODO: this is probably x: boolean. How do we deal with x: true ? + return createKeywordTypeNode(SyntaxKind.BooleanKeyword); + } + if (type.flags & (TypeFlags.StringLiteral)) { // TODO: check if this actually works with boolean. - return createLiteralTypeNode((type).text); + return createLiteralTypeNode((createLiteral((type).text))); + } + if (type.flags & (TypeFlags.NumberLiteral)) { + // TODO: check if this actually works with boolean. + return createLiteralTypeNode((createNumericLiteral((type).text))); } if (type.flags & TypeFlags.Void) { return createKeywordTypeNode(SyntaxKind.VoidKeyword); @@ -2279,11 +2287,10 @@ namespace ts { if (objectFlags & ObjectFlags.ClassOrInterface) { Debug.assert(!!(type.flags & TypeFlags.Object)); - // If type is a class or interface type that wasn't hit by the isSymbolAccessible check above, - // type must be an anonymous class or interface. - - encounteredError = true; - return undefined; + const name = getNameOfSymbol(type.symbol); + // TODO: handle type arguments. + // TODO: handle anonymous classes. + return createTypeReferenceNode(name); } if (objectFlags & ObjectFlags.Reference) { diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 3633cc657a..19e8ef25da 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -234,23 +234,75 @@ namespace ts { return createSynthesizedNode(kind); } - - export function createLiteralTypeNode(value: string | number | boolean) { - const literal = createLiteral(value); + export function createLiteralTypeNode(literal: Expression) { const literalTypeNode = createSynthesizedNode(SyntaxKind.LiteralType) as LiteralTypeNode; literalTypeNode.literal = literal; return literalTypeNode; } + export function updateLiteralTypeNode(node: LiteralTypeNode, literal: Expression) { + return node.literal !== literal + ? updateNode(createLiteralTypeNode(literal), node) + : node; + } + // TODO: handle qualified names, ie EntityName's. export function createTypeReferenceNode(typeName: string | Identifier, typeArguments?: NodeArray) { const typeReference = createSynthesizedNode(SyntaxKind.TypeReference) as TypeReferenceNode; typeReference.typeName = asName(typeName); - typeReference.typeName.parent typeReference.typeArguments = typeArguments; return typeReference; } + export function updateTypeReferenceNode(node: TypeReferenceNode, typeName: Identifier, typeArguments?: NodeArray) { + return node.typeName !== typeName + || node.typeArguments !== typeArguments + ? updateNode(createTypeReferenceNode(typeName, typeArguments), node) + : node; + } + + export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType, types: TypeNode[]): UnionTypeNode; + export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.IntersectionType, types: TypeNode[]): IntersectionTypeNode; + export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: TypeNode[]): UnionOrIntersectionTypeNode; + export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: TypeNode[]): UnionOrIntersectionTypeNode { + const unionTypeNode = createSynthesizedNode(kind) as UnionTypeNode | IntersectionTypeNode; + unionTypeNode.types = asNodeArray(types); + return unionTypeNode; + } + + export function updateUnionOrIntersectionTypeNode(node: UnionOrIntersectionTypeNode, kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: NodeArray) { + return node.types !== types + || node.kind !== kind + ? updateNode(createUnionOrIntersectionTypeNode(kind, types), node) + : node; + } + + export function createTypeLiteralNode(members: TypeElement[]) { + const typeLiteralNode = createSynthesizedNode(SyntaxKind.LiteralType) as TypeLiteralNode; + typeLiteralNode.members = asNodeArray(members); + return typeLiteralNode; + } + + export function updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray) { + return node.members !== members + ? updateNode(createTypeLiteralNode(members), node) + : node; + } + + export function createTupleTypeNode(elementTypes: TypeNode[]) { + const tupleTypeNode = createSynthesizedNode(SyntaxKind.TupleType) as TupleTypeNode; + tupleTypeNode.elementTypes = asNodeArray(elementTypes); + return tupleTypeNode; + } + + export function updateTypleTypeNode(node: TupleTypeNode, elementTypes: TypeNode[]) { + return node.elementTypes !== elementTypes + ? updateNode(createTupleTypeNode(elementTypes), node) + : node; + } + + // Type Declarations + export function createTypeParameterNode(name: string | Identifier, constraint?: TypeNode, defaultParameter?: TypeNode) { const typeParameter = createSynthesizedNode(SyntaxKind.TypeParameter) as TypeParameterDeclaration; typeParameter.name = asName(name); @@ -260,31 +312,6 @@ namespace ts { return typeParameter; } - export function createUnionTypeNode(types: NodeArray) { - const unionTypeNode = createSynthesizedNode(SyntaxKind.UnionType) as UnionTypeNode; - unionTypeNode.types = asNodeArray(types); - return unionTypeNode; - } - - export function createIntersectionTypeNode(types: NodeArray) { - const intersectionTypeNode = createSynthesizedNode(SyntaxKind.IntersectionType) as IntersectionTypeNode; - intersectionTypeNode.types = asNodeArray(types); - return intersectionTypeNode; - } - - export function createTypeLiteralNode(typeElements: TypeElement[]) { - const typeLiteralNode = createSynthesizedNode(SyntaxKind.LiteralType) as TypeLiteralNode; - typeLiteralNode.members = asNodeArray(typeElements); - return typeLiteralNode; - } - - export function createTupleTypeNode(types: NodeArray) { - const tupleTypeNode = createSynthesizedNode(SyntaxKind.TupleType) as TupleTypeNode; - tupleTypeNode.elementTypes = asNodeArray(types); - return tupleTypeNode; - } - - // Signature elements /** Note, can also be used to construct index signatures. */ @@ -298,10 +325,11 @@ namespace ts { } // TODO: check usage of name... - export function createIndexSignature(parameter: ParameterDeclaration, type: TypeNode, decorators?: Decorator[], modifiers?: Modifier[]): IndexSignatureDeclaration { + // TODO: create entry in visitor.ts + export function createIndexSignatureDeclaration(parameters: ParameterDeclaration[], type: TypeNode, decorators?: Decorator[], modifiers?: Modifier[]): IndexSignatureDeclaration { const indexSignature = createSignature( SyntaxKind.IndexSignature - , asNodeArray([parameter]) + , asNodeArray(parameters) , /*name*/ undefined , /*typeParameters*/undefined , type) as IndexSignatureDeclaration; @@ -310,6 +338,15 @@ namespace ts { return indexSignature; } + export function updateIndexSignatureDeclaration(node: IndexSignatureDeclaration, parameters: ParameterDeclaration[], type: TypeNode, decorators?: Decorator[], modifiers?: Modifier[]) { + return node.parameters !== parameters + || node.type !== type + || node.decorators !== decorators + || node.modifiers !== modifiers + ? updateNode(createIndexSignatureDeclaration(parameters, type, decorators, modifiers), node) + : node; + } + export function createParameter(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression) { const node = createSynthesizedNode(SyntaxKind.Parameter); node.decorators = asNodeArray(decorators); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 4fd4dd1780..463638484c 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -673,7 +673,7 @@ namespace ts { initializer?: Expression; // Optional initializer } - export interface BindingElement extends Declaration { + export interface BindingElement extends Declaration { kind: SyntaxKind.BindingElement; parent?: BindingPattern; propertyName?: PropertyName; // Binding property name (in object binding pattern) @@ -849,19 +849,17 @@ namespace ts { _typeNodeBrand: any; } - export type KeywordKind = SyntaxKind.AnyKeyword - | SyntaxKind.NumberKeyword - | SyntaxKind.ObjectKeyword - | SyntaxKind.BooleanKeyword - | SyntaxKind.StringKeyword - | SyntaxKind.SymbolKeyword - | SyntaxKind.VoidKeyword - | SyntaxKind.UndefinedKeyword - | SyntaxKind.NullKeyword - | SyntaxKind.NeverKeyword; - export interface KeywordTypeNode extends TypeNode { - kind: KeywordKind; + kind: SyntaxKind.AnyKeyword + | SyntaxKind.NumberKeyword + | SyntaxKind.ObjectKeyword + | SyntaxKind.BooleanKeyword + | SyntaxKind.StringKeyword + | SyntaxKind.SymbolKeyword + | SyntaxKind.VoidKeyword + | SyntaxKind.UndefinedKeyword + | SyntaxKind.NullKeyword + | SyntaxKind.NeverKeyword; } export interface ThisTypeNode extends TypeNode { diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 133c62e192..35119dc7fc 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -212,16 +212,12 @@ namespace ts { } const kind = node.kind; + // No need to visit nodes with no children. if ((kind > SyntaxKind.FirstToken && kind <= SyntaxKind.LastToken)) { return node; } - // We do not yet support types. - if ((kind >= SyntaxKind.TypePredicate && kind <= SyntaxKind.LiteralType)) { - return node; - } - switch (node.kind) { case SyntaxKind.SemicolonClassElement: case SyntaxKind.EmptyStatement: @@ -241,6 +237,13 @@ namespace ts { visitNode((node).expression, visitor, isExpression)); // Signature elements + case SyntaxKind.IndexSignature: + return updateIndexSignatureDeclaration(node + , nodesVisitor((node).parameters, visitor) + , visitNode((node).type, visitor) + , nodesVisitor((node).decorators, visitor, isDecorator) + , nodesVisitor((node).modifiers, visitor, isModifier)); + case SyntaxKind.Parameter: return updateParameter(node, nodesVisitor((node).decorators, visitor, isDecorator), @@ -254,7 +257,60 @@ namespace ts { return updateDecorator(node, visitNode((node).expression, visitor, isExpression)); - // Type member + // Keyword Types + + case SyntaxKind.AnyKeyword: + case SyntaxKind.NumberKeyword: + case SyntaxKind.ObjectKeyword: + case SyntaxKind.BooleanKeyword: + case SyntaxKind.StringKeyword: + case SyntaxKind.SymbolKeyword: + case SyntaxKind.VoidKeyword: + case SyntaxKind.UndefinedKeyword: + case SyntaxKind.NullKeyword: + case SyntaxKind.NeverKeyword: + case SyntaxKind.NeverKeyword: + return node; + + // Types + + case SyntaxKind.TypePredicate: + throw new Error("reached unsupported type."); + case SyntaxKind.TypeReference: + return updateTypeReferenceNode(node + , visitNode((node).typeName as Identifier, visitor) + , nodesVisitor((node).typeArguments, visitor) + ); + case SyntaxKind.FunctionType: + throw new Error("reached unsupported type."); + case SyntaxKind.ConstructorType: + throw new Error("reached unsupported type."); + case SyntaxKind.TypeQuery: + throw new Error("reached unsupported type."); + case SyntaxKind.TypeLiteral: + throw new Error("reached unsupported type."); + case SyntaxKind.ArrayType: + throw new Error("reached unsupported type."); + case SyntaxKind.TupleType: + throw new Error("reached unsupported type."); + case SyntaxKind.UnionType: + case SyntaxKind.IntersectionType: + throw new Error("reached unsupported type."); + case SyntaxKind.ParenthesizedType: + throw new Error("reached unsupported type."); + case SyntaxKind.ThisType: + throw new Error("reached unsupported type."); + case SyntaxKind.TypeOperator: + throw new Error("reached unsupported type."); + case SyntaxKind.IndexedAccessType: + throw new Error("reached unsupported type."); + case SyntaxKind.MappedType: + throw new Error("reached unsupported type."); + case SyntaxKind.LiteralType: + throw new Error("reached unsupported type."); + + // Type members + case SyntaxKind.PropertyDeclaration: return updateProperty(node, nodesVisitor((node).decorators, visitor, isDecorator), diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index 05ff29f069..79b95e4799 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -62,13 +62,12 @@ namespace ts.codefix { , "name" , /*questionToken*/ undefined , stringTypeNode); - const indexSignature = createIndexSignature(indexingParameter, typeNode); + const indexSignature = createIndexSignatureDeclaration([indexingParameter], typeNode); - // const startPos = classDeclaration.members.pos; const indexSignatureChangeTracker = textChanges.ChangeTracker.fromCodeFixContext(context); indexSignatureChangeTracker.insertNodeAfter(sourceFile, openBrace, indexSignature, { insertTrailingNewLine: true }); - return [{ + return [{ description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_declaration_for_missing_property_0), [token.getText()]), changes: propertyChangeTracker.getChanges() }, diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 0fed656af5..92b6365657 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1386,6 +1386,6 @@ namespace ts { } export function getOpenBraceOfClassLike(declaration: ClassLikeDeclaration, sourceFile: SourceFile) { - return getTokenAtPosition(sourceFile, declaration.members.pos); + return getTokenAtPosition(sourceFile, declaration.members.pos - 1); } } From d6863bea256cc8a51caf0d978a09fa73ea427cb2 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Sun, 12 Mar 2017 12:49:29 -0700 Subject: [PATCH 051/164] missing member fixes use createTypeNode --- ...sDoesntImplementInheritedAbstractMember.ts | 19 +--- .../fixClassIncorrectlyImplementsInterface.ts | 57 +++++----- src/services/codefixes/helpers.ts | 105 +++++++++++++----- 3 files changed, 112 insertions(+), 69 deletions(-) diff --git a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts index 16edce0a51..513853e461 100644 --- a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts +++ b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts @@ -19,10 +19,9 @@ namespace ts.codefix { const checker = context.program.getTypeChecker(); if (isClassLike(token.parent)) { - const classDecl = token.parent as ClassLikeDeclaration; - const startPos = classDecl.members.pos; + const classDeclaration = token.parent as ClassLikeDeclaration; - const extendsNode = getClassExtendsHeritageClauseElement(classDecl); + const extendsNode = getClassExtendsHeritageClauseElement(classDeclaration); const instantiatedExtendsType = checker.getTypeAtLocation(extendsNode); // Note that this is ultimately derived from a map indexed by symbol names, @@ -30,18 +29,12 @@ namespace ts.codefix { const extendsSymbols = checker.getPropertiesOfType(instantiatedExtendsType); const abstractAndNonPrivateExtendsSymbols = extendsSymbols.filter(symbolPointsToNonPrivateAndAbstractMember); - const insertion = getMissingMembersInsertion(classDecl, abstractAndNonPrivateExtendsSymbols, checker, context.newLineCharacter); - - if (insertion.length) { + const newNodes = createMissingMemberNodes(classDeclaration, abstractAndNonPrivateExtendsSymbols, checker); + const changes = newNodesToChanges(newNodes, getOpenBraceOfClassLike(classDeclaration, sourceFile), context); + if(changes && changes.length > 0) { return [{ description: getLocaleSpecificMessage(Diagnostics.Implement_inherited_abstract_class), - changes: [{ - fileName: sourceFile.fileName, - textChanges: [{ - span: { start: startPos, length: 0 }, - newText: insertion - }] - }] + changes }]; } } diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts index 67b2242c8d..a5bde70c01 100644 --- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts +++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts @@ -16,7 +16,7 @@ namespace ts.codefix { return undefined; } - const startPos: number = classDecl.members.pos; + const openBrace = getOpenBraceOfClassLike(classDecl, sourceFile); const classType = checker.getTypeAtLocation(classDecl) as InterfaceType; const implementedTypeNodes = getClassImplementsHeritageClauseElements(classDecl); @@ -31,43 +31,46 @@ namespace ts.codefix { const implementedTypeSymbols = checker.getPropertiesOfType(implementedType); const nonPrivateMembers = implementedTypeSymbols.filter(symbol => !(getModifierFlags(symbol.valueDeclaration) & ModifierFlags.Private)); - let insertion = getMissingIndexSignatureInsertion(implementedType, IndexKind.Number, classDecl, hasNumericIndexSignature); - insertion += getMissingIndexSignatureInsertion(implementedType, IndexKind.String, classDecl, hasStringIndexSignature); - insertion += getMissingMembersInsertion(classDecl, nonPrivateMembers, checker, context.newLineCharacter); - + let newNodes: Node[] = []; + createAndAddMissingIndexSignatureDeclaration(implementedType, IndexKind.Number, hasNumericIndexSignature, newNodes); + createAndAddMissingIndexSignatureDeclaration(implementedType, IndexKind.String, hasStringIndexSignature, newNodes); + newNodes = newNodes.concat(createMissingMemberNodes(classDecl, nonPrivateMembers, checker)); const message = formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Implement_interface_0), [implementedTypeNode.getText()]); - if (insertion) { - pushAction(result, insertion, message); + if (newNodes.length > 0) { + pushAction(result, newNodes, message); } } return result; - function getMissingIndexSignatureInsertion(type: InterfaceType, kind: IndexKind, enclosingDeclaration: ClassLikeDeclaration, hasIndexSigOfKind: boolean) { - if (!hasIndexSigOfKind) { - const IndexInfoOfKind = checker.getIndexInfoOfType(type, kind); - if (IndexInfoOfKind) { - const writer = getSingleLineStringWriter(); - checker.getSymbolDisplayBuilder().buildIndexSignatureDisplay(IndexInfoOfKind, writer, kind, enclosingDeclaration); - const result = writer.string(); - releaseStringWriter(writer); - - return result; - } + function createAndAddMissingIndexSignatureDeclaration(type: InterfaceType, kind: IndexKind, hasIndexSigOfKind: boolean, newNodes: Node[]): void { + if (hasIndexSigOfKind) { + return undefined; } - return ""; + + const indexInfoOfKind = checker.getIndexInfoOfType(type, kind); + + if (!indexInfoOfKind) { + return undefined; + } + const typeNode = checker.createTypeNode(indexInfoOfKind.type); + let name: string; + const newIndexSignatureDeclaration = createIndexSignatureDeclaration( + [createParameter( + /*decorators*/undefined + , /*modifiers*/ undefined + , /*dotDotDotToken*/ undefined + , name + , /*questionToken*/ undefined + , kind === IndexKind.String ? createKeywordTypeNode(SyntaxKind.StringKeyword) : createKeywordTypeNode(SyntaxKind.NumberKeyword))] + , typeNode); + newNodes.push(newIndexSignatureDeclaration); } - function pushAction(result: CodeAction[], insertion: string, description: string): void { + function pushAction(result: CodeAction[], newNodes: Node[], description: string): void { const newAction: CodeAction = { description: description, - changes: [{ - fileName: sourceFile.fileName, - textChanges: [{ - span: { start: startPos, length: 0 }, - newText: insertion - }] - }] + changes: newNodesToChanges(newNodes, openBrace, context) }; result.push(newAction); } diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index d20fc0129c..0af13bf41e 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -1,31 +1,53 @@ /* @internal */ namespace ts.codefix { + export function newNodesToChanges(newNodes: Node[], insertAfter: Node, context: CodeFixContext) { + const sourceFile = context.sourceFile; + if (!(newNodes)) { + // TODO: make the appropriate value flow through gracefully. + throw new Error("newNodesToChanges expects an array"); + } + + const changeTracker = textChanges.ChangeTracker.fromCodeFixContext(context); + + for (let i = newNodes.length - 1; i >= 0; i--) { + changeTracker.insertNodeAfter(sourceFile, insertAfter, newNodes[i], { insertTrailingNewLine: true }); + } + return changeTracker.getChanges(); + } + /** * Finds members of the resolved type that are missing in the class pointed to by class decl * and generates source code for the missing members. * @param possiblyMissingSymbols The collection of symbols to filter and then get insertions for. * @returns Empty string iff there are no member insertions. */ - export function getMissingMembersInsertion(classDeclaration: ClassLikeDeclaration, possiblyMissingSymbols: Symbol[], checker: TypeChecker, newlineChar: string): string { + export function createMissingMemberNodes(classDeclaration: ClassLikeDeclaration, possiblyMissingSymbols: Symbol[], checker: TypeChecker): Node[] { const classMembers = classDeclaration.symbol.members; const missingMembers = possiblyMissingSymbols.filter(symbol => !classMembers.has(symbol.getName())); - let insertion = ""; - + let newNodes: Node[] = []; for (const symbol of missingMembers) { - insertion = insertion.concat(getInsertionForMemberSymbol(symbol, classDeclaration, checker, newlineChar)); + const newNode = getNewNodeForMemberSymbol(symbol, classDeclaration, checker); + if (newNode) { + if (Array.isArray(newNode)) { + newNodes = newNodes.concat(newNode); + } + else { + newNodes.push(newNode); + } + } } - return insertion; + return newNodes; } /** * @returns Empty string iff there we can't figure out a representation for `symbol` in `enclosingDeclaration`. */ - function getInsertionForMemberSymbol(symbol: Symbol, enclosingDeclaration: ClassLikeDeclaration, checker: TypeChecker, newlineChar: string): string { + function getNewNodeForMemberSymbol(symbol: Symbol, enclosingDeclaration: ClassLikeDeclaration, checker: TypeChecker): Node[] | Node | undefined { const declarations = symbol.getDeclarations(); if (!(declarations && declarations.length)) { - return ""; + return undefined; } const declaration = declarations[0] as Declaration; @@ -39,9 +61,16 @@ namespace ts.codefix { case SyntaxKind.SetAccessor: case SyntaxKind.PropertySignature: case SyntaxKind.PropertyDeclaration: - const typeString = checker.typeToString(type, enclosingDeclaration, TypeFormatFlags.None); - return `${visibility}${name}: ${typeString};${newlineChar}`; - + const typeNode = checker.createTypeNode(type); + // TODO: add modifiers. + const property = createProperty( + /*decorators*/undefined + , /*modifiers*/ undefined + , name + , /*questionToken*/ undefined + , typeNode + , /*initializer*/ undefined); + return property; case SyntaxKind.MethodSignature: case SyntaxKind.MethodDeclaration: // The signature for the implementation appears as an entry in `signatures` iff @@ -53,18 +82,22 @@ namespace ts.codefix { // correspondence of declarations and signatures. const signatures = checker.getSignaturesOfType(type, SignatureKind.Call); if (!(signatures && signatures.length > 0)) { - return ""; + return undefined; } if (declarations.length === 1) { Debug.assert(signatures.length === 1); - const sigString = checker.signatureToString(signatures[0], enclosingDeclaration, TypeFormatFlags.SuppressAnyReturnType, SignatureKind.Call); - return getStubbedMethod(visibility, name, sigString, newlineChar); + // TODO: extract signature declaration from a signature. + // const sigString = checker.signatureToString(signatures[0], enclosingDeclaration, TypeFormatFlags.SuppressAnyReturnType, SignatureKind.Call); + // TODO: get parameters working. + // TODO: add support for type parameters. + return createStubbedMethod([visibility], name, /*typeParameters*/undefined, []); } - let result = ""; + let signatureDeclarations = []; for (let i = 0; i < signatures.length; i++) { - const sigString = checker.signatureToString(signatures[i], enclosingDeclaration, TypeFormatFlags.SuppressAnyReturnType, SignatureKind.Call); - result += `${visibility}${name}${sigString};${newlineChar}`; + // const sigString = checker.signatureToString(signatures[i], enclosingDeclaration, TypeFormatFlags.SuppressAnyReturnType, SignatureKind.Call); + // TODO: make signatures instead of methods + signatureDeclarations.push(createStubbedMethod([visibility], name, /*typeParameters*/undefined, [])); } // If there is a declaration with a body, it is the last declaration, @@ -77,12 +110,12 @@ namespace ts.codefix { Debug.assert(declarations.length === signatures.length); bodySig = createBodySignatureWithAnyTypes(signatures, enclosingDeclaration, checker); } - const sigString = checker.signatureToString(bodySig, enclosingDeclaration, TypeFormatFlags.SuppressAnyReturnType, SignatureKind.Call); - result += getStubbedMethod(visibility, name, sigString, newlineChar); - - return result; + // const sigString = checker.signatureToString(bodySig, enclosingDeclaration, TypeFormatFlags.SuppressAnyReturnType, SignatureKind.Call); + signatureDeclarations.push(createStubbedMethod([visibility], name, /*typeParameters*/undefined, [])); + + return signatureDeclarations; default: - return ""; + return undefined; } } @@ -138,22 +171,36 @@ namespace ts.codefix { } } - export function getStubbedMethod(visibility: string, name: string, sigString = "()", newlineChar: string): string { - return `${visibility}${name}${sigString}${getMethodBodyStub(newlineChar)}`; + export function createStubbedMethod(modifiers: Modifier[], name: string, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], returnType?: TypeNode) { + return createMethod( + /*decorators*/undefined + , /*modifiers*/modifiers + , /*asteriskToken*/undefined + , name + , typeParameters + , parameters + , returnType + , createStubbedMethodBody()); } - function getMethodBodyStub(newlineChar: string) { - return ` {${newlineChar}throw new Error('Method not implemented.');${newlineChar}}${newlineChar}`; + function createStubbedMethodBody() { + return createBlock( + [createThrow( + createNew( + createIdentifier('Error') + , /*typeArguments*/undefined + , [createLiteral('Method not implemented.')]))] + , /*multiline*/true); } - function getVisibilityPrefixWithSpace(flags: ModifierFlags): string { + function getVisibilityPrefixWithSpace(flags: ModifierFlags) { if (flags & ModifierFlags.Public) { - return "public "; + return createToken(SyntaxKind.PublicKeyword); } else if (flags & ModifierFlags.Protected) { - return "protected "; + return createToken(SyntaxKind.ProtectedKeyword); } - return ""; + return undefined; } const SymbolConstructor = objectAllocator.getSymbolConstructor(); From 03511c0b092a33e3e1fad2f61406760f2142c769 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Sun, 12 Mar 2017 16:36:03 -0700 Subject: [PATCH 052/164] snythesize methods in missing member fix --- src/compiler/factory.ts | 5 +- src/services/codefixes/helpers.ts | 123 ++++++++++++++++++------------ 2 files changed, 80 insertions(+), 48 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 19e8ef25da..f59eea8461 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -45,7 +45,10 @@ namespace ts { * Creates a shallow, memberwise clone of a node with no source map location. */ /* @internal */ - export function getSynthesizedClone(node: T): T { + export function getSynthesizedClone(node: T | undefined): T { + if(node === undefined) { + return undefined; + } // We don't use "clone" from core.ts here, as we need to preserve the prototype chain of // the original node. We also need to exclude specific properties and only include own- // properties (to skip members already defined on the shared prototype). diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 0af13bf41e..27195ac0be 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -28,7 +28,7 @@ namespace ts.codefix { let newNodes: Node[] = []; for (const symbol of missingMembers) { - const newNode = getNewNodeForMemberSymbol(symbol, classDeclaration, checker); + const newNode = createNewNodeForMemberSymbol(symbol, classDeclaration, checker); if (newNode) { if (Array.isArray(newNode)) { newNodes = newNodes.concat(newNode); @@ -44,7 +44,7 @@ namespace ts.codefix { /** * @returns Empty string iff there we can't figure out a representation for `symbol` in `enclosingDeclaration`. */ - function getNewNodeForMemberSymbol(symbol: Symbol, enclosingDeclaration: ClassLikeDeclaration, checker: TypeChecker): Node[] | Node | undefined { + function createNewNodeForMemberSymbol(symbol: Symbol, enclosingDeclaration: ClassLikeDeclaration, checker: TypeChecker): Node[] | Node | undefined { const declarations = symbol.getDeclarations(); if (!(declarations && declarations.length)) { return undefined; @@ -52,8 +52,7 @@ namespace ts.codefix { const declaration = declarations[0] as Declaration; const name = declaration.name ? declaration.name.getText() : undefined; - const visibility = getVisibilityPrefixWithSpace(getModifierFlags(declaration)); - + const modifiers = [createVisibilityModifier(getModifierFlags(declaration))]; const type = checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration); switch (declaration.kind) { @@ -86,43 +85,55 @@ namespace ts.codefix { } if (declarations.length === 1) { Debug.assert(signatures.length === 1); - // TODO: extract signature declaration from a signature. - // const sigString = checker.signatureToString(signatures[0], enclosingDeclaration, TypeFormatFlags.SuppressAnyReturnType, SignatureKind.Call); + // TODO: suppress any return type // TODO: get parameters working. // TODO: add support for type parameters. - return createStubbedMethod([visibility], name, /*typeParameters*/undefined, []); + const signature = signatures[0]; + const newParameterNodes = signature.getParameters().map(symbol => createParameterDeclarationFromSymbol(symbol, enclosingDeclaration, checker)); + const returnType = checker.createTypeNode(signature.resolvedReturnType); + return createStubbedMethod(modifiers, name, /*typeParameters*/undefined, newParameterNodes, returnType); } let signatureDeclarations = []; for (let i = 0; i < signatures.length; i++) { // const sigString = checker.signatureToString(signatures[i], enclosingDeclaration, TypeFormatFlags.SuppressAnyReturnType, SignatureKind.Call); // TODO: make signatures instead of methods - signatureDeclarations.push(createStubbedMethod([visibility], name, /*typeParameters*/undefined, [])); + const signature = signatures[i]; + const newParameterNodes = signature.getParameters().map(symbol => createParameterDeclarationFromSymbol(symbol, enclosingDeclaration, checker)); + const returnType = checker.createTypeNode(signature.resolvedReturnType); + signatureDeclarations.push(createMethod( + /*decorators*/ undefined + , modifiers + , /*asteriskToken*/ undefined + , name + , /*typeParameters*/undefined + , newParameterNodes + , returnType + , /*body*/undefined)); } - // If there is a declaration with a body, it is the last declaration, - // and it isn't caught by `getSignaturesOfType`. - let bodySig: Signature | undefined = undefined; if (declarations.length > signatures.length) { - bodySig = checker.getSignatureFromDeclaration(declarations[declarations.length - 1] as SignatureDeclaration); + let signature = checker.getSignatureFromDeclaration(declarations[declarations.length - 1] as SignatureDeclaration); + const newParameterNodes = signature.getParameters().map(symbol => createParameterDeclarationFromSymbol(symbol, enclosingDeclaration, checker)); + const returnType = checker.createTypeNode(signature.resolvedReturnType); + signatureDeclarations.push(createStubbedMethod(modifiers, name, /*typeParameters*/undefined, newParameterNodes, returnType)); } else { Debug.assert(declarations.length === signatures.length); - bodySig = createBodySignatureWithAnyTypes(signatures, enclosingDeclaration, checker); + const methodImplementingSignatures = createMethodImplementingSignatures(signatures, enclosingDeclaration, name, modifiers); + signatureDeclarations.push(methodImplementingSignatures); } - // const sigString = checker.signatureToString(bodySig, enclosingDeclaration, TypeFormatFlags.SuppressAnyReturnType, SignatureKind.Call); - signatureDeclarations.push(createStubbedMethod([visibility], name, /*typeParameters*/undefined, [])); - return signatureDeclarations; default: return undefined; } } - function createBodySignatureWithAnyTypes(signatures: Signature[], enclosingDeclaration: ClassLikeDeclaration, checker: TypeChecker): Signature { - const newSignatureDeclaration = createNode(SyntaxKind.CallSignature) as SignatureDeclaration; - newSignatureDeclaration.parent = enclosingDeclaration; - newSignatureDeclaration.name = signatures[0].getDeclaration().name; + // TODO: infer types of arguments? + function createMethodImplementingSignatures(signatures: Signature[], enclosingDeclaration: ClassLikeDeclaration, name: string, modifiers: Modifier[] | undefined): MethodDeclaration { + const newMethodDeclaration = createNode(SyntaxKind.CallSignature) as SignatureDeclaration; + newMethodDeclaration.parent = enclosingDeclaration; + newMethodDeclaration.name = signatures[0].getDeclaration().name; let maxNonRestArgs = -1; let maxArgsIndex = 0; @@ -133,42 +144,47 @@ namespace ts.codefix { minArgumentCount = Math.min(sig.minArgumentCount, minArgumentCount); hasRestParameter = hasRestParameter || sig.hasRestParameter; const nonRestLength = sig.parameters.length - (sig.hasRestParameter ? 1 : 0); - if (nonRestLength > maxNonRestArgs) { + if (nonRestLength >= maxNonRestArgs) { maxNonRestArgs = nonRestLength; maxArgsIndex = i; } } const maxArgsParameterSymbolNames = signatures[maxArgsIndex].getParameters().map(symbol => symbol.getName()); - const optionalToken = createToken(SyntaxKind.QuestionToken); - - newSignatureDeclaration.parameters = createNodeArray(); + const parameters = createNodeArray(); for (let i = 0; i < maxNonRestArgs; i++) { - const newParameter = createParameterDeclarationWithoutType(i, minArgumentCount, newSignatureDeclaration); - newSignatureDeclaration.parameters.push(newParameter); + const newParameter = createParameter( + /*decorators*/ undefined + , /*modifiers*/ undefined + , /*dotDotDotToken*/ undefined + , maxArgsParameterSymbolNames[i] + , /*questionToken*/ i >= minArgumentCount ? createToken(SyntaxKind.QuestionToken) : undefined + , /*type*/ undefined + , /*initializer*/ undefined); + parameters.push(newParameter); } if (hasRestParameter) { - const restParameter = createParameterDeclarationWithoutType(maxNonRestArgs, minArgumentCount, newSignatureDeclaration); - restParameter.dotDotDotToken = createToken(SyntaxKind.DotDotDotToken); - newSignatureDeclaration.parameters.push(restParameter); + const restParameter = createParameter( + /*decorators*/ undefined + , /*modifiers*/ undefined + , createToken(SyntaxKind.DotDotDotToken) + , maxArgsParameterSymbolNames[maxNonRestArgs] || "rest" + , /*questionToken*/ maxNonRestArgs >= minArgumentCount ? createToken(SyntaxKind.QuestionToken) : undefined + , /*type*/ undefined + , /*initializer*/ undefined); + parameters.push(restParameter); } - return checker.getSignatureFromDeclaration(newSignatureDeclaration); - - function createParameterDeclarationWithoutType(index: number, minArgCount: number, enclosingSignatureDeclaration: SignatureDeclaration): ParameterDeclaration { - const newParameter = createNode(SyntaxKind.Parameter) as ParameterDeclaration; - - newParameter.symbol = new SymbolConstructor(SymbolFlags.FunctionScopedVariable, maxArgsParameterSymbolNames[index] || "rest"); - newParameter.symbol.valueDeclaration = newParameter; - newParameter.symbol.declarations = [newParameter]; - newParameter.parent = enclosingSignatureDeclaration; - if (index >= minArgCount) { - newParameter.questionToken = optionalToken; - } - - return newParameter; - } + return createMethod( + /*decorators*/ undefined + , modifiers + , /*asteriskToken*/ undefined + , name + , /*typeParameters*/undefined + , parameters + , /*type*/ undefined + , /*body*/undefined); } export function createStubbedMethod(modifiers: Modifier[], name: string, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], returnType?: TypeNode) { @@ -187,13 +203,13 @@ namespace ts.codefix { return createBlock( [createThrow( createNew( - createIdentifier('Error') + createIdentifier('Error') , /*typeArguments*/undefined , [createLiteral('Method not implemented.')]))] , /*multiline*/true); } - function getVisibilityPrefixWithSpace(flags: ModifierFlags) { + function createVisibilityModifier(flags: ModifierFlags) { if (flags & ModifierFlags.Public) { return createToken(SyntaxKind.PublicKeyword); } @@ -203,5 +219,18 @@ namespace ts.codefix { return undefined; } - const SymbolConstructor = objectAllocator.getSymbolConstructor(); + function createParameterDeclarationFromSymbol(parameterSymbol: Symbol, enclosingDeclaration: ClassLikeDeclaration, checker: TypeChecker) { + const parameterDeclaration = parameterSymbol.getDeclarations()[0] as ParameterDeclaration; + const parameterType = checker.getTypeOfSymbolAtLocation(parameterSymbol, enclosingDeclaration); + const parameterTypeNode = checker.createTypeNode(parameterType); + // TODO: deep cloning of decorators/any node. + const parameterNode = createParameter( + parameterDeclaration.decorators && parameterDeclaration.decorators.map(getSynthesizedClone) + , parameterDeclaration.modifiers && parameterDeclaration.modifiers.map(getSynthesizedClone) + , parameterDeclaration.dotDotDotToken && createToken(SyntaxKind.DotDotDotToken) + , parameterDeclaration.name + , parameterDeclaration.questionToken && createToken(SyntaxKind.QuestionToken) + , parameterTypeNode); + return parameterNode; + } } \ No newline at end of file From f5f01a162f46f69d8dbb6a0e99db00f49b250503 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Sun, 12 Mar 2017 17:14:20 -0700 Subject: [PATCH 053/164] Simplify Ranges --- ...ixClassExtendAbstractMethodTypeParamsInstantiateNumber.ts | 3 +-- ...codeFixClassExtendAbstractMethodTypeParamsInstantiateU.ts | 3 +-- .../fourslash/codeFixClassExtendAbstractPrivateProperty.ts | 3 +-- tests/cases/fourslash/codeFixClassExtendAbstractProperty.ts | 3 +-- .../fourslash/codeFixClassExtendAbstractProtectedProperty.ts | 3 +-- .../fourslash/codeFixClassExtendAbstractPublicProperty.ts | 4 ++-- .../fourslash/codeFixClassImplementClassMethodViaHeritage.ts | 4 ++-- .../cases/fourslash/codeFixClassImplementDeepInheritance.ts | 3 +-- tests/cases/fourslash/codeFixClassImplementInterface36.ts | 4 +--- tests/cases/fourslash/codeFixClassImplementInterface39.ts | 3 +-- .../codeFixClassImplementInterfaceDuplicateMember1.ts | 3 +-- .../codeFixClassImplementInterfaceIndexSignaturesNumber.ts | 3 +-- ...deFixClassImplementInterfaceMethodThisAndSelfReference.ts | 3 +-- .../codeFixClassImplementInterfaceMultipleImplements1.ts | 5 ++--- .../codeFixClassImplementInterfaceMultipleImplements2.ts | 3 +-- ...ClassImplementInterfaceMultipleImplementsIntersection1.ts | 3 +-- ...ixClassImplementInterfaceMultipleMembersAndPunctuation.ts | 3 +-- .../codeFixClassImplementInterfaceNamespaceConflict.ts | 3 +-- ...mplementInterfacePropertyFromParentConstructorFunction.ts | 2 +- .../codeFixClassImplementInterfaceSomePropertiesPresent.ts | 2 +- ...deFixClassImplementInterfaceTypeParamInstantiateDeeply.ts | 2 +- ...deFixClassImplementInterfaceTypeParamInstantiateNumber.ts | 2 +- .../codeFixClassImplementInterfaceTypeParamInstantiateT.ts | 2 +- .../codeFixClassImplementInterfaceTypeParamInstantiateU.ts | 2 +- 24 files changed, 27 insertions(+), 44 deletions(-) diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateNumber.ts b/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateNumber.ts index bdf198b89e..a69852f5e9 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateNumber.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateNumber.ts @@ -4,8 +4,7 @@ //// abstract f(x: T): T; //// } //// -//// class C extends A {[| -//// |]} +//// class C extends A {[| |]} verify.rangeAfterCodeFix(`f(x: number): number{ throw new Error('Method not implemented.'); diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateU.ts b/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateU.ts index 647a533c1c..98d118214d 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateU.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateU.ts @@ -4,8 +4,7 @@ //// abstract f(x: T): T; //// } //// -//// class C extends A {[| -//// |]} +//// class C extends A {[| |]} verify.rangeAfterCodeFix(`f(x: U): U{ throw new Error('Method not implemented.'); diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractPrivateProperty.ts b/tests/cases/fourslash/codeFixClassExtendAbstractPrivateProperty.ts index d395272b36..b8f6b3d81e 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractPrivateProperty.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractPrivateProperty.ts @@ -4,8 +4,7 @@ //// private abstract x: number; //// } //// -//// class C extends A {[| -//// |]} +//// class C extends A {[| |]} // We don't know how to fix this problem. We can: // 1) Make x protected, and then insert. diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractProperty.ts b/tests/cases/fourslash/codeFixClassExtendAbstractProperty.ts index b7300acf5a..1973f452f6 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractProperty.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractProperty.ts @@ -7,8 +7,7 @@ //// abstract foo(): number; //// } //// -//// class C extends A {[| -//// |]} +//// class C extends A {[| |]} verify.rangeAfterCodeFix(` x: number; diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractProtectedProperty.ts b/tests/cases/fourslash/codeFixClassExtendAbstractProtectedProperty.ts index 6d0571fce6..d2532ef16d 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractProtectedProperty.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractProtectedProperty.ts @@ -4,8 +4,7 @@ //// protected abstract x: number; //// } //// -//// class C extends A {[| -//// |]} +//// class C extends A {[| |]} verify.rangeAfterCodeFix(` protected x: number; diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractPublicProperty.ts b/tests/cases/fourslash/codeFixClassExtendAbstractPublicProperty.ts index 917f75051f..495d661ec7 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractPublicProperty.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractPublicProperty.ts @@ -4,8 +4,8 @@ //// public abstract x: number; //// } //// -//// class C extends A {[| -//// |]} +//// class C extends A {[| |]} + verify.rangeAfterCodeFix(` public x: number; diff --git a/tests/cases/fourslash/codeFixClassImplementClassMethodViaHeritage.ts b/tests/cases/fourslash/codeFixClassImplementClassMethodViaHeritage.ts index 4365a16053..b70c2898f1 100644 --- a/tests/cases/fourslash/codeFixClassImplementClassMethodViaHeritage.ts +++ b/tests/cases/fourslash/codeFixClassImplementClassMethodViaHeritage.ts @@ -8,8 +8,8 @@ //// //// } //// -//// class C3 implements C2 {[| -//// |]f2(){} +//// class C3 implements C2 {[| |] +//// f2(){} //// } verify.rangeAfterCodeFix(`f1(): void{ diff --git a/tests/cases/fourslash/codeFixClassImplementDeepInheritance.ts b/tests/cases/fourslash/codeFixClassImplementDeepInheritance.ts index e8b199b21a..f11dc29395 100644 --- a/tests/cases/fourslash/codeFixClassImplementDeepInheritance.ts +++ b/tests/cases/fourslash/codeFixClassImplementDeepInheritance.ts @@ -24,8 +24,7 @@ //// } //// //// interface I6 extends C4 {} -//// class C5 implements I6 {[| -//// |]} +//// class C5 implements I6 {[| |]} /** diff --git a/tests/cases/fourslash/codeFixClassImplementInterface36.ts b/tests/cases/fourslash/codeFixClassImplementInterface36.ts index f9fc48991f..d96ce52390 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterface36.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterface36.ts @@ -10,9 +10,7 @@ //// //// interface I1 extends C1, C2 {} //// -//// class C3 implements I1 {[| -//// -//// |]} +//// class C3 implements I1 {[| |]} verify.rangeAfterCodeFix(`f1(){ throw new Error('Method not implemented.'); diff --git a/tests/cases/fourslash/codeFixClassImplementInterface39.ts b/tests/cases/fourslash/codeFixClassImplementInterface39.ts index f81dea4978..1df34c2e1a 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterface39.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterface39.ts @@ -9,8 +9,7 @@ //// f1(); //// } //// -//// class C1 implements N1.I1 {[| -//// |]} +//// class C1 implements N1.I1 {[| |]} verify.rangeAfterCodeFix(`f1(): string{ throw new Error('Method not implemented.'); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceDuplicateMember1.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceDuplicateMember1.ts index a2154de567..bea14ae404 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceDuplicateMember1.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceDuplicateMember1.ts @@ -7,7 +7,6 @@ //// x: number; //// } //// -//// class C implements I1,I2 {[| -//// |]} +//// class C implements I1,I2 {[| |]} verify.codeFixAvailable(); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceIndexSignaturesNumber.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceIndexSignaturesNumber.ts index 0f14344253..41bb7257e4 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceIndexSignaturesNumber.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceIndexSignaturesNumber.ts @@ -4,8 +4,7 @@ //// [x: number]: I; //// } //// -//// class C implements I {[| -//// |]} +//// class C implements I {[| |]} verify.rangeAfterCodeFix(` [x: number]: I; diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceMethodThisAndSelfReference.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceMethodThisAndSelfReference.ts index 95cc3476bf..48e33e6ef0 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceMethodThisAndSelfReference.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceMethodThisAndSelfReference.ts @@ -4,8 +4,7 @@ //// f(x: number, y: this): I //// } //// -//// class C implements I {[| -//// |]} +//// class C implements I {[| |]} verify.rangeAfterCodeFix(` f(x: number,y: this): I { diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplements1.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplements1.ts index c8d61227c4..5043a4d9c2 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplements1.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplements1.ts @@ -7,13 +7,12 @@ //// y: number; //// } //// -//// class C implements I1,I2 {[| +//// class C implements I1,I2 {[| |] //// y: number; -//// |]} +//// } verify.rangeAfterCodeFix(` x: number; -y: number; `); verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplements2.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplements2.ts index d29b23998b..ead2375168 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplements2.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplements2.ts @@ -7,13 +7,12 @@ //// y: number; //// } //// -//// class C implements I1,I2 {[| +//// class C implements I1,I2 {[| |] //// x: number; //// |]} verify.rangeAfterCodeFix(` y: number; -x: number; `); verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplementsIntersection1.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplementsIntersection1.ts index 321d41e463..cac1038eb1 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplementsIntersection1.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplementsIntersection1.ts @@ -7,7 +7,6 @@ //// x: string; //// } //// -//// class C implements I1,I2 {[| -//// |]} +//// class C implements I1,I2 {[| |]} verify.codeFixAvailable(); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleMembersAndPunctuation.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleMembersAndPunctuation.ts index beab89c06a..afc1dae551 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleMembersAndPunctuation.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleMembersAndPunctuation.ts @@ -9,8 +9,7 @@ //// h(); //// } //// -//// class C1 implements I1 {[| -//// |]} +//// class C1 implements I1 {[| |]} verify.rangeAfterCodeFix(` x: number; diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceNamespaceConflict.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceNamespaceConflict.ts index 4fea72aa48..4ca42640c2 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceNamespaceConflict.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceNamespaceConflict.ts @@ -9,8 +9,7 @@ //// f1(); //// } //// -//// class C1 implements N1.I1 {[| -//// |]} +//// class C1 implements N1.I1 {[| |]} verify.rangeAfterCodeFix(` x: number; diff --git a/tests/cases/fourslash/codeFixClassImplementInterfacePropertyFromParentConstructorFunction.ts b/tests/cases/fourslash/codeFixClassImplementInterfacePropertyFromParentConstructorFunction.ts index 2a4ca4df92..acda59513a 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfacePropertyFromParentConstructorFunction.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfacePropertyFromParentConstructorFunction.ts @@ -4,7 +4,7 @@ //// constructor(public x: number) { } //// } //// -//// class B implements A {[| |]} +//// class B implements A {[| |]} verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceSomePropertiesPresent.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceSomePropertiesPresent.ts index 6e0658019f..03807ab450 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceSomePropertiesPresent.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceSomePropertiesPresent.ts @@ -6,7 +6,7 @@ //// z: number & { __iBrand: any }; //// } //// -//// class C implements I {[| |] +//// class C implements I {[| |] //// constructor(public x: number) { } //// y: number; //// } diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateDeeply.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateDeeply.ts index f76bd5dae9..acccafe0fc 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateDeeply.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateDeeply.ts @@ -4,7 +4,7 @@ //// x: { y: T, z: T[] }; //// } //// -//// class C implements I {[| |]} +//// class C implements I {[| |]} verify.rangeAfterCodeFix(` x: { y: number; z: number[]; }; diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateNumber.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateNumber.ts index af0e7a162e..a11101c7f4 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateNumber.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateNumber.ts @@ -4,7 +4,7 @@ //// x: T; //// } //// -//// class C implements I {[| |]} +//// class C implements I {[| |]} verify.rangeAfterCodeFix(` x: number; diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateT.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateT.ts index 45fa3fd40c..298ee0704f 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateT.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateT.ts @@ -4,7 +4,7 @@ //// x: T; //// } //// -//// class C implements I {[| |]} +//// class C implements I {[| |]} verify.rangeAfterCodeFix(` x: T; diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateU.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateU.ts index 16c35f4177..3f1da116f4 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateU.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateU.ts @@ -4,7 +4,7 @@ //// x: T; //// } //// -//// class C implements I {[| |]} +//// class C implements I {[| |]} verify.rangeAfterCodeFix(` x: U; From 965d43c6a553aaeb7c849baa9410566974dfd178 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Sun, 12 Mar 2017 18:35:48 -0700 Subject: [PATCH 054/164] Print new nodes in correct order --- src/services/codefixes/helpers.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 27195ac0be..bbbe14ab33 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -10,8 +10,8 @@ namespace ts.codefix { const changeTracker = textChanges.ChangeTracker.fromCodeFixContext(context); - for (let i = newNodes.length - 1; i >= 0; i--) { - changeTracker.insertNodeAfter(sourceFile, insertAfter, newNodes[i], { insertTrailingNewLine: true }); + for (const newNode of newNodes) { + changeTracker.insertNodeAfter(sourceFile, insertAfter, newNode, { insertTrailingNewLine: true }); } return changeTracker.getChanges(); } @@ -52,7 +52,8 @@ namespace ts.codefix { const declaration = declarations[0] as Declaration; const name = declaration.name ? declaration.name.getText() : undefined; - const modifiers = [createVisibilityModifier(getModifierFlags(declaration))]; + const visibilityModifier = createVisibilityModifier(getModifierFlags(declaration)); + const modifiers = visibilityModifier ? [visibilityModifier] : undefined; const type = checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration); switch (declaration.kind) { @@ -64,7 +65,7 @@ namespace ts.codefix { // TODO: add modifiers. const property = createProperty( /*decorators*/undefined - , /*modifiers*/ undefined + , modifiers , name , /*questionToken*/ undefined , typeNode From 93cd1dc1eab6dc0f18ae9a6d7408015bbe8d5071 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Sun, 12 Mar 2017 18:47:17 -0700 Subject: [PATCH 055/164] get name for index info --- src/services/codefixes/fixAddMissingMember.ts | 2 +- .../codefixes/fixClassIncorrectlyImplementsInterface.ts | 3 +-- src/services/codefixes/helpers.ts | 4 ++++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index 79b95e4799..fe12249f17 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -59,7 +59,7 @@ namespace ts.codefix { /*decorators*/ undefined , /*modifiers*/ undefined , /*dotDotDotToken*/ undefined - , "name" + , "x" , /*questionToken*/ undefined , stringTypeNode); const indexSignature = createIndexSignatureDeclaration([indexingParameter], typeNode); diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts index a5bde70c01..f653d21e02 100644 --- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts +++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts @@ -54,13 +54,12 @@ namespace ts.codefix { return undefined; } const typeNode = checker.createTypeNode(indexInfoOfKind.type); - let name: string; const newIndexSignatureDeclaration = createIndexSignatureDeclaration( [createParameter( /*decorators*/undefined , /*modifiers*/ undefined , /*dotDotDotToken*/ undefined - , name + , getNameFromIndexInfo(indexInfoOfKind) , /*questionToken*/ undefined , kind === IndexKind.String ? createKeywordTypeNode(SyntaxKind.StringKeyword) : createKeywordTypeNode(SyntaxKind.NumberKeyword))] , typeNode); diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index bbbe14ab33..67f53fb8e5 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -234,4 +234,8 @@ namespace ts.codefix { , parameterTypeNode); return parameterNode; } + + export function getNameFromIndexInfo(info: IndexInfo) { + return info.declaration ? declarationNameToString(info.declaration.parameters[0].name) : "x" + } } \ No newline at end of file From 060317759e3b84f3c10ddc26224fba75a121a640 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Sun, 12 Mar 2017 18:48:51 -0700 Subject: [PATCH 056/164] Add type parameters --- src/compiler/factory.ts | 21 ++++++++++++++------- src/compiler/types.ts | 2 +- src/compiler/visitor.ts | 15 +++++++++++++++ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index f59eea8461..901f3a4bd1 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -306,7 +306,7 @@ namespace ts { // Type Declarations - export function createTypeParameterNode(name: string | Identifier, constraint?: TypeNode, defaultParameter?: TypeNode) { + export function createTypeParameterDeclaration(name: string | Identifier, constraint?: TypeNode, defaultParameter?: TypeNode) { const typeParameter = createSynthesizedNode(SyntaxKind.TypeParameter) as TypeParameterDeclaration; typeParameter.name = asName(name); typeParameter.constraint = constraint; @@ -315,6 +315,14 @@ namespace ts { return typeParameter; } + export function updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint?: TypeNode, defaultParameter?: TypeNode) { + return node.name !== name + || node.constraint !== constraint + || node.default !== defaultParameter + ? updateNode(createTypeParameterDeclaration(name, constraint, defaultParameter), node) + : node; + } + // Signature elements /** Note, can also be used to construct index signatures. */ @@ -330,12 +338,11 @@ namespace ts { // TODO: check usage of name... // TODO: create entry in visitor.ts export function createIndexSignatureDeclaration(parameters: ParameterDeclaration[], type: TypeNode, decorators?: Decorator[], modifiers?: Modifier[]): IndexSignatureDeclaration { - const indexSignature = createSignature( - SyntaxKind.IndexSignature - , asNodeArray(parameters) - , /*name*/ undefined - , /*typeParameters*/undefined - , type) as IndexSignatureDeclaration; + const indexSignature = createSynthesizedNode(SyntaxKind.IndexSignature) as IndexSignatureDeclaration; + // indexSignature.name = asName(name); + // type parameters + indexSignature.parameters = asNodeArray(parameters); + indexSignature.type = type; indexSignature.decorators = asNodeArray(decorators); indexSignature.modifiers = asNodeArray(modifiers); return indexSignature; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 463638484c..b9f5da0f6e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -818,7 +818,7 @@ namespace ts { body?: FunctionBody; } - // For when we encounter a semicolon in a class declaration. ES6 allows these as class elements. + /** For when we encounter a semicolon in a class declaration. ES6 allows these as class elements.*/ export interface SemicolonClassElement extends ClassElement { kind: SyntaxKind.SemicolonClassElement; } diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 35119dc7fc..91110accbb 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -309,8 +309,23 @@ namespace ts { case SyntaxKind.LiteralType: throw new Error("reached unsupported type."); + // Type Declarations + + case SyntaxKind.TypeParameter: + return updateTypeParameterDeclaration(node + , visitNode((node).name, visitor, isIdentifier) + , visitNode((node).constraint, visitor, isTypeNode) + , visitNode((node).default, visitor, isTypeNode)); + // Type members + case SyntaxKind.IndexSignature: + updateIndexSignatureDeclaration(node + , nodesVisitor((node).parameters, visitor, isParameter) + , visitNode((node).type, visitor, isTypeNode) + , nodesVisitor((node).decorators, visitor, isDecorator) + , nodesVisitor((node).modifiers, visitor, isModifier)); + case SyntaxKind.PropertyDeclaration: return updateProperty(node, nodesVisitor((node).decorators, visitor, isDecorator), From 6c72283378a3b3f02dfa380aa41a269fb5078dc6 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Sun, 12 Mar 2017 18:52:38 -0700 Subject: [PATCH 057/164] Use consistent quotes --- ...sExprClassImplementClassFunctionVoidInferred.ts | 2 +- .../fourslash/codeFixClassExtendAbstractMethod.ts | 2 +- .../codeFixClassExtendAbstractMethodThis.ts | 2 +- ...endAbstractMethodTypeParamsInstantiateNumber.ts | 2 +- ...ssExtendAbstractMethodTypeParamsInstantiateU.ts | 2 +- .../codeFixClassExtendAbstractProperty.ts | 2 +- ...deFixClassImplementClassFunctionVoidInferred.ts | 2 +- .../codeFixClassImplementClassMethodViaHeritage.ts | 2 +- ...odeFixClassImplementClassMultipleSignatures1.ts | 2 +- ...odeFixClassImplementClassMultipleSignatures2.ts | 2 +- .../fourslash/codeFixClassImplementInterface36.ts | 2 +- .../fourslash/codeFixClassImplementInterface39.ts | 2 +- ...ssImplementInterfaceComputedPropertyLiterals.ts | 4 ++-- ...nterfaceComputedPropertyNameWellKnownSymbols.ts | 14 +++++++------- ...ImplementInterfaceMethodThisAndSelfReference.ts | 2 +- ...lementInterfaceMultipleMembersAndPunctuation.ts | 6 +++--- ...FixClassImplementInterfaceMultipleSignatures.ts | 2 +- ...assImplementInterfaceMultipleSignaturesRest1.ts | 2 +- ...assImplementInterfaceMultipleSignaturesRest2.ts | 2 +- ...odeFixClassImplementInterfaceTypeParamMethod.ts | 2 +- 20 files changed, 29 insertions(+), 29 deletions(-) diff --git a/tests/cases/fourslash/codeFixClassExprClassImplementClassFunctionVoidInferred.ts b/tests/cases/fourslash/codeFixClassExprClassImplementClassFunctionVoidInferred.ts index bdf8ea3bd2..2568111fb9 100644 --- a/tests/cases/fourslash/codeFixClassExprClassImplementClassFunctionVoidInferred.ts +++ b/tests/cases/fourslash/codeFixClassExprClassImplementClassFunctionVoidInferred.ts @@ -8,6 +8,6 @@ verify.rangeAfterCodeFix(` f(): void{ - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } `); diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractMethod.ts b/tests/cases/fourslash/codeFixClassExtendAbstractMethod.ts index 344a7ee3f2..b6b408cf5f 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractMethod.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractMethod.ts @@ -15,6 +15,6 @@ verify.rangeAfterCodeFix(` f(a: string, b: number): Function; f(a: string): Function; f(a: any, b?: any) { - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } `); diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractMethodThis.ts b/tests/cases/fourslash/codeFixClassExtendAbstractMethodThis.ts index 55b3ad4b77..a462ac9812 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractMethodThis.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractMethodThis.ts @@ -8,6 +8,6 @@ verify.rangeAfterCodeFix(` f(): this { - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } `); diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateNumber.ts b/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateNumber.ts index a69852f5e9..c1a55e8803 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateNumber.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateNumber.ts @@ -7,6 +7,6 @@ //// class C extends A {[| |]} verify.rangeAfterCodeFix(`f(x: number): number{ - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } `); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateU.ts b/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateU.ts index 98d118214d..c2ec5ff803 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateU.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateU.ts @@ -7,6 +7,6 @@ //// class C extends A {[| |]} verify.rangeAfterCodeFix(`f(x: U): U{ - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } `); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractProperty.ts b/tests/cases/fourslash/codeFixClassExtendAbstractProperty.ts index 1973f452f6..83f770b555 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractProperty.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractProperty.ts @@ -14,6 +14,6 @@ verify.rangeAfterCodeFix(` y: this; z: A; foo(): number { - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } `); diff --git a/tests/cases/fourslash/codeFixClassImplementClassFunctionVoidInferred.ts b/tests/cases/fourslash/codeFixClassImplementClassFunctionVoidInferred.ts index d9b9f57d4d..b8fdace9f7 100644 --- a/tests/cases/fourslash/codeFixClassImplementClassFunctionVoidInferred.ts +++ b/tests/cases/fourslash/codeFixClassImplementClassFunctionVoidInferred.ts @@ -8,6 +8,6 @@ verify.rangeAfterCodeFix(` f(): void{ - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } `); diff --git a/tests/cases/fourslash/codeFixClassImplementClassMethodViaHeritage.ts b/tests/cases/fourslash/codeFixClassImplementClassMethodViaHeritage.ts index b70c2898f1..ede19ef570 100644 --- a/tests/cases/fourslash/codeFixClassImplementClassMethodViaHeritage.ts +++ b/tests/cases/fourslash/codeFixClassImplementClassMethodViaHeritage.ts @@ -13,6 +13,6 @@ //// } verify.rangeAfterCodeFix(`f1(): void{ - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } `); diff --git a/tests/cases/fourslash/codeFixClassImplementClassMultipleSignatures1.ts b/tests/cases/fourslash/codeFixClassImplementClassMultipleSignatures1.ts index 82ecde6c41..2e8dc316b3 100644 --- a/tests/cases/fourslash/codeFixClassImplementClassMultipleSignatures1.ts +++ b/tests/cases/fourslash/codeFixClassImplementClassMultipleSignatures1.ts @@ -9,6 +9,6 @@ verify.rangeAfterCodeFix(` method(a: number, b: string): boolean; method(a: string | number, b?: string | number): boolean | Function { - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } `); diff --git a/tests/cases/fourslash/codeFixClassImplementClassMultipleSignatures2.ts b/tests/cases/fourslash/codeFixClassImplementClassMultipleSignatures2.ts index f187e0ca0f..463b10c450 100644 --- a/tests/cases/fourslash/codeFixClassImplementClassMultipleSignatures2.ts +++ b/tests/cases/fourslash/codeFixClassImplementClassMultipleSignatures2.ts @@ -13,6 +13,6 @@ verify.rangeAfterCodeFix(` method(a: string, b: number): Function; method(a: string): Function; method(a: string | number, b?: string | number): boolean | Function { - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } `); diff --git a/tests/cases/fourslash/codeFixClassImplementInterface36.ts b/tests/cases/fourslash/codeFixClassImplementInterface36.ts index d96ce52390..5b0459ab66 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterface36.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterface36.ts @@ -13,6 +13,6 @@ //// class C3 implements I1 {[| |]} verify.rangeAfterCodeFix(`f1(){ - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } `); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixClassImplementInterface39.ts b/tests/cases/fourslash/codeFixClassImplementInterface39.ts index 1df34c2e1a..e4e1cf3608 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterface39.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterface39.ts @@ -12,6 +12,6 @@ //// class C1 implements N1.I1 {[| |]} verify.rangeAfterCodeFix(`f1(): string{ - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } `); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyLiterals.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyLiterals.ts index 341b4e5981..4a6bb20f57 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyLiterals.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyLiterals.ts @@ -11,11 +11,11 @@ verify.rangeAfterCodeFix(` ["foo"](o: any): boolean { - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } ["x"]: boolean; [1](): string { - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } [2]: boolean; `); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyNameWellKnownSymbols.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyNameWellKnownSymbols.ts index 7c1156acd7..61b4267e7f 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyNameWellKnownSymbols.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyNameWellKnownSymbols.ts @@ -22,30 +22,30 @@ verify.rangeAfterCodeFix(` [Symbol.hasInstance](o: any): boolean { - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } [Symbol.isConcatSpreadable]: boolean; [Symbol.iterator]() { - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } [Symbol.match]: boolean; [Symbol.replace](...args: {}) { - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } [Symbol.search](str: string): number { - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } [Symbol.species](): number { - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } [Symbol.split](str: string, limit?: number): {} { - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } [Symbol.toPrimitive](hint: "number"): number; [Symbol.toPrimitive](hint: "default"): number; [Symbol.toPrimitive](hint: "string"): string; [Symbol.toPrimitive](hint: any) { - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } [Symbol.toStringTag]: string; [Symbol.unscopables]: any; diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceMethodThisAndSelfReference.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceMethodThisAndSelfReference.ts index 48e33e6ef0..b8225f31e0 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceMethodThisAndSelfReference.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceMethodThisAndSelfReference.ts @@ -8,6 +8,6 @@ verify.rangeAfterCodeFix(` f(x: number,y: this): I { - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } `); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleMembersAndPunctuation.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleMembersAndPunctuation.ts index afc1dae551..66cdb1f545 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleMembersAndPunctuation.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleMembersAndPunctuation.ts @@ -16,12 +16,12 @@ x: number; y: number; z: number; f() { - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } g() { - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } h() { - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } `); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleSignatures.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleSignatures.ts index bda58b3767..583dda1305 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleSignatures.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleSignatures.ts @@ -13,6 +13,6 @@ verify.rangeAfterCodeFix(` method(a: string, b: number): Function; method(a: string): Function; method(a: any, b?: any) { - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } `); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleSignaturesRest1.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleSignaturesRest1.ts index 6e0a272a42..132c63ae0f 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleSignaturesRest1.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleSignaturesRest1.ts @@ -13,6 +13,6 @@ verify.rangeAfterCodeFix(` method(a: string, ...b: number[]): Function; method(a: string): Function; method(a: any, ...b?: any[]) { - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } `); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleSignaturesRest2.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleSignaturesRest2.ts index 7ba7ae2c98..b4e9a8ff91 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleSignaturesRest2.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleSignaturesRest2.ts @@ -13,6 +13,6 @@ verify.rangeAfterCodeFix(` method(a: string, b: number): Function; method(a: string): Function; method(a: any, b?: any, ...rest?: any[]) { - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } `); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamMethod.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamMethod.ts index 4d6afaefed..9bcd4b8845 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamMethod.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamMethod.ts @@ -7,6 +7,6 @@ //// class C implements I {[| |]} verify.rangeAfterCodeFix(`f(x: T){ - throw new Error('Method not implemented.'); + throw new Error("Method not implemented."); } `); \ No newline at end of file From 6fe59f34509e9fd99f0ae45964edac8a73e13aa0 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Sun, 12 Mar 2017 19:18:51 -0700 Subject: [PATCH 058/164] Unions and intersections --- src/compiler/checker.ts | 49 ++++++++++++++++++----------------------- src/compiler/factory.ts | 5 ++--- src/compiler/visitor.ts | 29 ++++++++++++------------ 3 files changed, 39 insertions(+), 44 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f29204f7ca..d3e1eeb08e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2190,20 +2190,34 @@ namespace ts { } function createTypeNode(type: Type) { - // let encounteredError = false; + let undefinedArgumentIsError = true; + let encounteredError = false; let checkAlias = true; return createTypeNodeWorker(type); // function createTypeDeclaration(type: Type): Declaration { // if (!type) { + // if (undefinedArgumentIsError) { encounteredError = true; } // return undefined; // } - // throw new Error("not implemented."); + // if (type.flags & TypeFlags.TypeParameter) { + // const constraint = createTypeNodeWorker(getConstraintFromTypeParameter(type)) as TypeNode; + // const defaultParameter = createTypeNodeWorker(getDefaultFromTypeParameter(type)) as TypeNode; + // if (!type.symbol) { + // encounteredError = true; + // throw new Error("No symbol for type parameter so can't get name"); + // } + // const name = getNameOfSymbol(type.symbol); + // return createTypeParameterDeclaration(name, constraint, defaultParameter); + // } + + // throw new Error("type declarations not implemented."); // } function createTypeNodeWorker(type: Type): TypeNode { if (!type) { + if (undefinedArgumentIsError) { encounteredError = true; } return undefined; } @@ -2229,11 +2243,9 @@ namespace ts { return createKeywordTypeNode(SyntaxKind.BooleanKeyword); } if (type.flags & (TypeFlags.StringLiteral)) { - // TODO: check if this actually works with boolean. return createLiteralTypeNode((createLiteral((type).text))); } if (type.flags & (TypeFlags.NumberLiteral)) { - // TODO: check if this actually works with boolean. return createLiteralTypeNode((createNumericLiteral((type).text))); } if (type.flags & TypeFlags.Void) { @@ -2249,40 +2261,27 @@ namespace ts { return createKeywordTypeNode(SyntaxKind.NeverKeyword); } if (type.flags & TypeFlags.Enum) { - throw new Error("not implemented"); + throw new Error("enum not implemented"); } if (type.flags & TypeFlags.ESSymbol) { - throw new Error("not implemented"); + throw new Error("ESSymbol not implemented"); } if (type.flags & TypeFlags.TypeParameter) { throw new Error("Type Parameter declarations only handled in other worker."); - // const constraint = createTypeNodeWorker(getConstraintFromTypeParameter(type)) as TypeNode; - // const defaultParameter = createTypeNodeWorker(getDefaultFromTypeParameter(type)) as TypeNode; - // if (!type.symbol) { - // encounteredError = true; - // throw new Error("No symbol for type parameter so can't get name"); - // } - // const name = getNameOfSymbol(type.symbol); - // return createTypeParameterNode(name, constraint, defaultParameter); } if (type.flags & TypeFlags.Union) { - throw new Error("not implemented"); + return createUnionOrIntersectionTypeNode(SyntaxKind.UnionType, mapToTypeNodeArray((type as UnionType).types)); } if (type.flags & TypeFlags.Intersection) { - throw new Error("not implemented"); + return createUnionOrIntersectionTypeNode(SyntaxKind.IntersectionType, mapToTypeNodeArray((type as UnionType).types)); } if (type.flags & TypeFlags.Index) { - throw new Error("not implemented"); + throw new Error("index not implemented"); } if (type.flags & TypeFlags.IndexedAccess) { - throw new Error("not implemented"); + throw new Error("indexed access not implemented"); } - // if(type.flags & TypeFlags.Object) { - // throw new Error("not implemented"); - // } - - // TODO: should these be within the if above (check with asserts) const objectFlags = getObjectFlags(type); if (objectFlags & ObjectFlags.ClassOrInterface) { @@ -2390,10 +2389,6 @@ namespace ts { function mapToTypeNodeArray(types: Type[]): NodeArray { return asNodeArray(types && types.map(createTypeNodeWorker) as TypeNode[]); } - - // function mapToTypeDeclarationsArray(types: Type[]): NodeArray { - // return asNodeArray(types && types.map(createTypeDeclaration)); - // } } } diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 901f3a4bd1..6e10d8bb22 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -273,10 +273,9 @@ namespace ts { return unionTypeNode; } - export function updateUnionOrIntersectionTypeNode(node: UnionOrIntersectionTypeNode, kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: NodeArray) { + export function updateUnionOrIntersectionTypeNode(node: UnionOrIntersectionTypeNode, types: NodeArray) { return node.types !== types - || node.kind !== kind - ? updateNode(createUnionOrIntersectionTypeNode(kind, types), node) + ? updateNode(createUnionOrIntersectionTypeNode(node.kind, types), node) : node; } diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 91110accbb..bd2d26b775 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -275,39 +275,40 @@ namespace ts { // Types case SyntaxKind.TypePredicate: - throw new Error("reached unsupported type."); + throw new Error("reached unsupported type in visitor."); case SyntaxKind.TypeReference: return updateTypeReferenceNode(node , visitNode((node).typeName as Identifier, visitor) , nodesVisitor((node).typeArguments, visitor) ); case SyntaxKind.FunctionType: - throw new Error("reached unsupported type."); + throw new Error("reached unsupported type in visitor."); case SyntaxKind.ConstructorType: - throw new Error("reached unsupported type."); + throw new Error("reached unsupported type in visitor."); case SyntaxKind.TypeQuery: - throw new Error("reached unsupported type."); + throw new Error("reached unsupported type in visitor."); case SyntaxKind.TypeLiteral: - throw new Error("reached unsupported type."); + throw new Error("reached unsupported type in visitor."); case SyntaxKind.ArrayType: - throw new Error("reached unsupported type."); + throw new Error("reached unsupported type in visitor."); case SyntaxKind.TupleType: - throw new Error("reached unsupported type."); + throw new Error("reached unsupported type in visitor."); case SyntaxKind.UnionType: case SyntaxKind.IntersectionType: - throw new Error("reached unsupported type."); + return updateUnionOrIntersectionTypeNode(node + , nodesVisitor((node).types, visitor, isTypeNode)); case SyntaxKind.ParenthesizedType: - throw new Error("reached unsupported type."); + throw new Error("reached unsupported type in visitor."); case SyntaxKind.ThisType: - throw new Error("reached unsupported type."); + throw new Error("reached unsupported type in visitor."); case SyntaxKind.TypeOperator: - throw new Error("reached unsupported type."); + throw new Error("reached unsupported type in visitor."); case SyntaxKind.IndexedAccessType: - throw new Error("reached unsupported type."); + throw new Error("reached unsupported type in visitor."); case SyntaxKind.MappedType: - throw new Error("reached unsupported type."); + throw new Error("reached unsupported type in visitor."); case SyntaxKind.LiteralType: - throw new Error("reached unsupported type."); + throw new Error("reached unsupported type in visitor."); // Type Declarations From f0b4efe94f7e1817b3075cd2a39d3ccd3544b4c6 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Mon, 13 Mar 2017 09:18:40 -0700 Subject: [PATCH 059/164] type literals, properties only --- src/compiler/checker.ts | 100 ++++++++++-------- src/compiler/factory.ts | 12 ++- src/compiler/types.ts | 2 +- src/compiler/visitor.ts | 25 ++++- src/services/codefixes/helpers.ts | 1 + src/services/textChanges.ts | 20 ---- ...lassExtendAbstractSomePropertiesPresent.ts | 4 +- ...FixClassImplementClassMethodViaHeritage.ts | 4 +- ...lementInterfaceComputedPropertyLiterals.ts | 2 +- 9 files changed, 97 insertions(+), 73 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d3e1eeb08e..65907536f8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2196,25 +2196,6 @@ namespace ts { return createTypeNodeWorker(type); - // function createTypeDeclaration(type: Type): Declaration { - // if (!type) { - // if (undefinedArgumentIsError) { encounteredError = true; } - // return undefined; - // } - // if (type.flags & TypeFlags.TypeParameter) { - // const constraint = createTypeNodeWorker(getConstraintFromTypeParameter(type)) as TypeNode; - // const defaultParameter = createTypeNodeWorker(getDefaultFromTypeParameter(type)) as TypeNode; - // if (!type.symbol) { - // encounteredError = true; - // throw new Error("No symbol for type parameter so can't get name"); - // } - // const name = getNameOfSymbol(type.symbol); - // return createTypeParameterDeclaration(name, constraint, defaultParameter); - // } - - // throw new Error("type declarations not implemented."); - // } - function createTypeNodeWorker(type: Type): TypeNode { if (!type) { if (undefinedArgumentIsError) { encounteredError = true; } @@ -2267,6 +2248,9 @@ namespace ts { throw new Error("ESSymbol not implemented"); } if (type.flags & TypeFlags.TypeParameter) { + if ((type).isThisType) { + return createThis(); + } throw new Error("Type Parameter declarations only handled in other worker."); } if (type.flags & TypeFlags.Union) { @@ -2332,27 +2316,12 @@ namespace ts { // return typeSymbolAccessibility === SymbolAccessibility.Accessible // && (!constraint || isTypeAccessibleWorker(constraint, inObjectLiteral, /*inTypeAlias*/false)); // } - // if (typeSymbolAccessibility === SymbolAccessibility.Accessible) { - // return true; - // } - // if (type.flags & (TypeFlags.Intrinsic | TypeFlags.Literal)) { - // return true; - // } // const objectFlags = getObjectFlags(type); // if (objectFlags & ObjectFlags.ClassOrInterface) { // // If type is a class or interface type that wasn't hit by the isSymbolAccessible check above, // // type must be an anonymous class or interface. // return false; // } - // if (objectFlags & ObjectFlags.Reference) { - // // and vice versa. - // // this case includes tuple types - // const typeArguments = (type as TypeReference).typeArguments || emptyArray; - // return allTypesVisible(typeArguments); - // } - // if (type.flags & TypeFlags.UnionOrIntersection) { - // return allTypesVisible((type as UnionOrIntersectionType).types); - // } if (objectFlags & ObjectFlags.Mapped) { Debug.assert(!!(type.flags & TypeFlags.Object)); @@ -2370,25 +2339,68 @@ namespace ts { // mapToTypeDeclarationsArray(type) - throw new Error("object literal types not implemented."); + throw new Error("unknown case."); } - // what case is this? - throw new Error("unknown case.") - // const members = type.symbol.members; - // let allVisible = true; - // members && members.forEach((member) => { - // const memberType = getTypeOfSymbolAtLocation(member, enclosingDeclaration); - // allVisible = allVisible && isTypeAccessibleWorker(memberType, /*inObjectLiteral*/ true, /*inTypeAlias*/false); - // }); - // return allVisible; + + const members = type.symbol.members; + const newMembers: TypeElement[] = []; + memberLoop: for(const key in members){ + const oldMember = members.get(key); + const name = getNameOfSymbol(oldMember); + const oldDeclaration = oldMember.declarations && oldMember.declarations[0] as TypeElement; + if(!oldDeclaration) { + continue memberLoop; + } + + const kind = oldDeclaration.kind; + + switch (kind) { + case SyntaxKind.PropertySignature: + const optional = !!oldDeclaration.questionToken; + newMembers.push(createPropertySignature( + createIdentifier(name) + , optional ? createToken(SyntaxKind.QuestionToken) : undefined + , createTypeNode(getTypeOfSymbol(oldMember)))); + case SyntaxKind.MethodSignature: + case SyntaxKind.CallSignature: + case SyntaxKind.ConstructSignature: + case SyntaxKind.IndexSignature: + default: + throw new Error("type literal constituent not implemented."); + } + } + return createTypeLiteralNode(newMembers); } Debug.fail("Should be unreachable."); + // function createTypeParameterDeclarationFromType(type: Type): TypeParameterDeclaration { + // if (!type) { + // if (undefinedArgumentIsError) { encounteredError = true; } + // return undefined; + // } + // if (type.flags & TypeFlags.TypeParameter) { + // const constraint = createTypeNodeWorker(getConstraintFromTypeParameter(type)) as TypeNode; + // const defaultParameter = createTypeNodeWorker(getDefaultFromTypeParameter(type)) as TypeNode; + // if (!type.symbol) { + // encounteredError = true; + // throw new Error("No symbol for type parameter so can't get name"); + // } + // const name = getNameOfSymbol(type.symbol); + // return createTypeParameterDeclaration(name, constraint, defaultParameter); + // } + // throw new Error("type declarations not implemented."); + // } + /** Note that mapToTypeNodeArray(undefined) === undefined. */ function mapToTypeNodeArray(types: Type[]): NodeArray { return asNodeArray(types && types.map(createTypeNodeWorker) as TypeNode[]); } + + // /** Note that mapToTypeNodeArray(undefined) === undefined. */ + // function mapToTypeParameterArray(types: Type[]): NodeArray { + // return asNodeArray(types && types.map(createTypeParameterDeclarationFromType) as TypeNode[]); + // } } } diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 6e10d8bb22..88bf5f458f 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -67,6 +67,14 @@ namespace ts { return clone; } + /* @internal */ + export function getSynthesizedDeepClone(node: T | undefined): T { + if (node === undefined) { + return undefined; + } + return getSynthesizedClone(visitEachChild(node, getSynthesizedClone, nullTransformationContext)); + } + // Literals export function createLiteral(value: string): StringLiteral; @@ -173,11 +181,11 @@ namespace ts { } export function createThis() { - return createSynthesizedNode(SyntaxKind.ThisKeyword); + return createSynthesizedNode(SyntaxKind.ThisKeyword); } export function createNull() { - return createSynthesizedNode(SyntaxKind.NullKeyword); + return createSynthesizedNode(SyntaxKind.NullKeyword); } export function createTrue() { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b9f5da0f6e..bf8916026f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4065,7 +4065,7 @@ namespace ts { export type Transformer = (node: T) => T; /** - * A function that accepts and possible transforms a node. + * A function that accepts and possibly transforms a node. */ export type Visitor = (node: Node) => VisitResult; diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index bd2d26b775..d2991b7cf0 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -3,6 +3,28 @@ /// namespace ts { + + + export const nullTransformationContext: TransformationContext = { + enableEmitNotification: noop, + enableSubstitution: noop, + endLexicalEnvironment: () => undefined, + getCompilerOptions: notImplemented, + getEmitHost: notImplemented, + getEmitResolver: notImplemented, + hoistFunctionDeclaration: noop, + hoistVariableDeclaration: noop, + isEmitNotificationEnabled: notImplemented, + isSubstitutionEnabled: notImplemented, + onEmitNode: noop, + onSubstituteNode: notImplemented, + readEmitHelpers: notImplemented, + requestEmitHelper: noop, + resumeLexicalEnvironment: noop, + startLexicalEnvironment: noop, + suspendLexicalEnvironment: noop + }; + /** * Visits a Node using the supplied visitor, possibly returning a new Node in its place. * @@ -813,7 +835,8 @@ namespace ts { visitNode((node).expression, visitor, isExpression)); default: - return node; + throw new Error("not handled"); + // return node; } } diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 67f53fb8e5..fb76e83faa 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -51,6 +51,7 @@ namespace ts.codefix { } const declaration = declarations[0] as Declaration; + // TODO: get name as identifier or computer property name, etc. const name = declaration.name ? declaration.name.getText() : undefined; const visibilityModifier = createVisibilityModifier(getModifierFlags(declaration)); const modifiers = visibilityModifier ? [visibilityModifier] : undefined; diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 5c345e6e4e..cb8c614cb2 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -341,26 +341,6 @@ namespace ts.textChanges { return skipTrivia(s, 0) === s.length; } - const nullTransformationContext: TransformationContext = { - enableEmitNotification: noop, - enableSubstitution: noop, - endLexicalEnvironment: () => undefined, - getCompilerOptions: notImplemented, - getEmitHost: notImplemented, - getEmitResolver: notImplemented, - hoistFunctionDeclaration: noop, - hoistVariableDeclaration: noop, - isEmitNotificationEnabled: notImplemented, - isSubstitutionEnabled: notImplemented, - onEmitNode: noop, - onSubstituteNode: notImplemented, - readEmitHelpers: notImplemented, - requestEmitHelper: noop, - resumeLexicalEnvironment: noop, - startLexicalEnvironment: noop, - suspendLexicalEnvironment: noop - }; - function assignPositionsToNode(node: Node): Node { const visited = visitEachChild(node, assignPositionsToNode, nullTransformationContext, assignPositionsToNodeArray); // create proxy node for non synthesized nodes diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractSomePropertiesPresent.ts b/tests/cases/fourslash/codeFixClassExtendAbstractSomePropertiesPresent.ts index b6dd679bb7..fb66a04cd5 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractSomePropertiesPresent.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractSomePropertiesPresent.ts @@ -6,8 +6,8 @@ //// abstract z: number; //// } //// -//// class C extends A {[| |] -//// constructor(public x: number) { super(); } +//// class C extends A {[| +//// |]constructor(public x: number) { super(); } //// y: number; //// } diff --git a/tests/cases/fourslash/codeFixClassImplementClassMethodViaHeritage.ts b/tests/cases/fourslash/codeFixClassImplementClassMethodViaHeritage.ts index ede19ef570..57372dd7e8 100644 --- a/tests/cases/fourslash/codeFixClassImplementClassMethodViaHeritage.ts +++ b/tests/cases/fourslash/codeFixClassImplementClassMethodViaHeritage.ts @@ -8,8 +8,8 @@ //// //// } //// -//// class C3 implements C2 {[| |] -//// f2(){} +//// class C3 implements C2 {[| +//// |]f2(){} //// } verify.rangeAfterCodeFix(`f1(): void{ diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyLiterals.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyLiterals.ts index 4a6bb20f57..7d77c5b9af 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyLiterals.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyLiterals.ts @@ -7,7 +7,7 @@ //// [2]: boolean; //// } //// -//// class C implements I {[| |]} +//// class C implements I {[| |]} verify.rangeAfterCodeFix(` ["foo"](o: any): boolean { From c46a2e7e1b6f05ce79fb2fa551edaec1b481a39c Mon Sep 17 00:00:00 2001 From: Zhengbo Li Date: Mon, 13 Mar 2017 12:45:28 -0700 Subject: [PATCH 060/164] always create new node array when assigning positions --- src/services/textChanges.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 5c345e6e4e..5b9f0f5ef4 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -380,7 +380,7 @@ namespace ts.textChanges { return visited; } // clone nodearray if necessary - const nodeArray = visited === nodes ? createNodeArray(visited) : visited; + const nodeArray = visited === nodes ? createNodeArray(visited.slice(0)) : visited; nodeArray.pos = getPos(nodes); nodeArray.end = getEnd(nodes); return nodeArray; From 1b14ed4d0ecf4b5c05a6d4f3cbb1d6f9f094dcbb Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Mon, 13 Mar 2017 16:51:43 -0700 Subject: [PATCH 061/164] update visitor/factory --- src/compiler/factory.ts | 52 ++++++++++++++++++++++++++++------------- src/compiler/visitor.ts | 19 ++++++++++----- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 88bf5f458f..14af23e95b 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -189,11 +189,11 @@ namespace ts { } export function createTrue() { - return createSynthesizedNode(SyntaxKind.TrueKeyword); + return createSynthesizedNode(SyntaxKind.TrueKeyword); } export function createFalse() { - return createSynthesizedNode(SyntaxKind.FalseKeyword); + return createSynthesizedNode(SyntaxKind.FalseKeyword); } // Names @@ -226,15 +226,6 @@ namespace ts { // Type Elements - export function createPropertySignature(name: PropertyName, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression): PropertySignature { - const propertySignature = createSynthesizedNode(SyntaxKind.PropertySignature) as PropertySignature; - propertySignature.name = name; - propertySignature.questionToken = questionToken; - propertySignature.type = type; - propertySignature.initializer = initializer; - return propertySignature; - } - export function createConstructSignature() { throw new Error("not implemented."); } @@ -258,14 +249,26 @@ namespace ts { } // TODO: handle qualified names, ie EntityName's. - export function createTypeReferenceNode(typeName: string | Identifier, typeArguments?: NodeArray) { + export function createTypeReferenceNode(typeName: string | EntityName, typeArguments?: NodeArray) { const typeReference = createSynthesizedNode(SyntaxKind.TypeReference) as TypeReferenceNode; - typeReference.typeName = asName(typeName); + + typeReference.typeName = isQualifiedName(typeName) ? typeName : asName(typeName); typeReference.typeArguments = typeArguments; return typeReference; } - export function updateTypeReferenceNode(node: TypeReferenceNode, typeName: Identifier, typeArguments?: NodeArray) { + export function createArrayTypeNode(elementType: TypeNode): ArrayTypeNode { + const arrayTypeNode = createSynthesizedNode(SyntaxKind.ArrayType) as ArrayTypeNode; + arrayTypeNode.elementType = elementType; + return arrayTypeNode; + } + + export function updateArrayTypeNode(node: ArrayTypeNode, elementType: TypeNode): ArrayTypeNode { + return node.elementType !== elementType + ? updateNode(createArrayTypeNode(elementType), node) + : node; + } + export function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments?: NodeArray) { return node.typeName !== typeName || node.typeArguments !== typeArguments ? updateNode(createTypeReferenceNode(typeName, typeArguments), node) @@ -288,7 +291,7 @@ namespace ts { } export function createTypeLiteralNode(members: TypeElement[]) { - const typeLiteralNode = createSynthesizedNode(SyntaxKind.LiteralType) as TypeLiteralNode; + const typeLiteralNode = createSynthesizedNode(SyntaxKind.TypeLiteral) as TypeLiteralNode; typeLiteralNode.members = asNodeArray(members); return typeLiteralNode; } @@ -332,7 +335,24 @@ namespace ts { // Signature elements - /** Note, can also be used to construct index signatures. */ + export function createPropertySignature(name: PropertyName, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression): PropertySignature { + const propertySignature = createSynthesizedNode(SyntaxKind.PropertySignature) as PropertySignature; + propertySignature.name = name; + propertySignature.questionToken = questionToken; + propertySignature.type = type; + propertySignature.initializer = initializer; + return propertySignature; + } + + export function updatePropertySignature(node: PropertySignature, name: PropertyName, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression) { + return node.name !== name + || node.questionToken !== questionToken + || node.type !== type + || node.initializer !== initializer + ? updateNode(createPropertySignature(name, questionToken, type, initializer), node) + : node; + } + export function createSignature(kind: SyntaxKind, parameters: NodeArray, name?: PropertyName, typeParameters?: NodeArray, returnType?: TypeNode): SignatureDeclaration { const signature = createSynthesizedNode(kind) as SignatureDeclaration; signature.parameters = parameters; diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index d2991b7cf0..547178e3b7 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -279,7 +279,7 @@ namespace ts { return updateDecorator(node, visitNode((node).expression, visitor, isExpression)); - // Keyword Types + // Keyword Types and This case SyntaxKind.AnyKeyword: case SyntaxKind.NumberKeyword: @@ -292,6 +292,7 @@ namespace ts { case SyntaxKind.NullKeyword: case SyntaxKind.NeverKeyword: case SyntaxKind.NeverKeyword: + case SyntaxKind.ThisKeyword: return node; // Types @@ -300,8 +301,8 @@ namespace ts { throw new Error("reached unsupported type in visitor."); case SyntaxKind.TypeReference: return updateTypeReferenceNode(node - , visitNode((node).typeName as Identifier, visitor) - , nodesVisitor((node).typeArguments, visitor) + , visitNode((node).typeName, visitor, isEntityName) + , nodesVisitor((node).typeArguments, visitor, isTypeNode) ); case SyntaxKind.FunctionType: throw new Error("reached unsupported type in visitor."); @@ -310,9 +311,9 @@ namespace ts { case SyntaxKind.TypeQuery: throw new Error("reached unsupported type in visitor."); case SyntaxKind.TypeLiteral: - throw new Error("reached unsupported type in visitor."); + return updateTypeLiteralNode((node), nodesVisitor((node).members, visitor)); case SyntaxKind.ArrayType: - throw new Error("reached unsupported type in visitor."); + return updateArrayTypeNode(node, visitNode((node).elementType, visitor, isTypeNode)); case SyntaxKind.TupleType: throw new Error("reached unsupported type in visitor."); case SyntaxKind.UnionType: @@ -342,8 +343,14 @@ namespace ts { // Type members + case SyntaxKind.PropertySignature: + return updatePropertySignature((node) + , visitNode((node).name, visitor, isPropertyName) + , visitNode((node).questionToken, visitor, isToken) + , visitNode((node).type, visitor, isTypeNode)); + case SyntaxKind.IndexSignature: - updateIndexSignatureDeclaration(node + return updateIndexSignatureDeclaration(node , nodesVisitor((node).parameters, visitor, isParameter) , visitNode((node).type, visitor, isTypeNode) , nodesVisitor((node).decorators, visitor, isDecorator) From 20f512cfd218ff45ea817cc7971780c94b92c119 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Mon, 13 Mar 2017 16:54:29 -0700 Subject: [PATCH 062/164] type parameters and basic object literals --- src/compiler/checker.ts | 242 +++++++++++++----- src/compiler/types.ts | 3 + src/services/codefixes/helpers.ts | 12 +- ...ImplementInterfaceSomePropertiesPresent.ts | 4 +- 4 files changed, 190 insertions(+), 71 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 509efe941d..ee999b3fe1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -107,6 +107,7 @@ namespace ts { getReturnTypeOfSignature, getNonNullableType, createTypeNode, + createTypeParameterDeclarationFromType, getSymbolsInScope: (location, meaning) => { location = getParseTreeNode(location); return location ? getSymbolsInScope(location, meaning) : []; @@ -2189,9 +2190,25 @@ namespace ts { return result; } - function createTypeNode(type: Type) { + function createTypeParameterDeclarationFromType(type: Type): TypeParameterDeclaration { + if (!(type && type.symbol && type.flags & TypeFlags.TypeParameter)) { + return undefined; + } + + const constraint = createTypeNode(getConstraintFromTypeParameter(type)) as TypeNode; + const defaultParameter = createTypeNode(getDefaultFromTypeParameter(type)) as TypeNode; + if (!type.symbol) { + return undefined; + } + + const name = symbolToString(type.symbol); + return createTypeParameterDeclaration(name, constraint, defaultParameter); + } + + function createTypeNode(type: Type): TypeNode { let undefinedArgumentIsError = true; let encounteredError = false; + let inObjectTypeLiteral = false; let checkAlias = true; return createTypeNodeWorker(type); @@ -2202,6 +2219,8 @@ namespace ts { return undefined; } + const typeString = typeToString(type); typeString; // TODO: remove. + if (checkAlias && type.aliasSymbol) { const name = getNameOfSymbol(type.aliasSymbol); const typeArguments = mapToTypeNodeArray(type.aliasTypeArguments); @@ -2211,7 +2230,7 @@ namespace ts { if (type.flags & TypeFlags.Any) { // TODO: add other case where type ends up being `any`. - return createKeywordTypeNode(SyntaxKind.StringKeyword); + return createKeywordTypeNode(SyntaxKind.AnyKeyword); } if (type.flags & TypeFlags.String) { return createKeywordTypeNode(SyntaxKind.StringKeyword); @@ -2220,15 +2239,23 @@ namespace ts { return createKeywordTypeNode(SyntaxKind.NumberKeyword); } if(type.flags & TypeFlags.Boolean) { - // TODO: this is probably x: boolean. How do we deal with x: true ? return createKeywordTypeNode(SyntaxKind.BooleanKeyword); } + if (type.flags & TypeFlags.Enum) { + throw new Error("enum not implemented"); + } if (type.flags & (TypeFlags.StringLiteral)) { return createLiteralTypeNode((createLiteral((type).text))); } if (type.flags & (TypeFlags.NumberLiteral)) { return createLiteralTypeNode((createNumericLiteral((type).text))); } + if(type.flags & TypeFlags.BooleanLiteral) { + return (type).intrinsicName === "true" ? createTrue() : createFalse(); + } + if (type.flags & TypeFlags.EnumLiteral) { + throw new Error("enum literal not implemented"); + } if (type.flags & TypeFlags.Void) { return createKeywordTypeNode(SyntaxKind.VoidKeyword); } @@ -2241,18 +2268,29 @@ namespace ts { if (type.flags & TypeFlags.Never) { return createKeywordTypeNode(SyntaxKind.NeverKeyword); } - if (type.flags & TypeFlags.Enum) { - throw new Error("enum not implemented"); - } if (type.flags & TypeFlags.ESSymbol) { throw new Error("ESSymbol not implemented"); } if (type.flags & TypeFlags.TypeParameter) { if ((type).isThisType) { + if (inObjectTypeLiteral) { + encounteredError = true; + } return createThis(); } throw new Error("Type Parameter declarations only handled in other worker."); } + + const objectFlags = getObjectFlags(type); + + if (objectFlags & ObjectFlags.Reference) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + // and vice versa. + // this case includes tuple types + // TODO: test empty tuples, see if they are coherent. + return createTypeReferenceNodeFromType(type); + } + if (type.flags & TypeFlags.Union) { return createUnionOrIntersectionTypeNode(SyntaxKind.UnionType, mapToTypeNodeArray((type as UnionType).types)); } @@ -2266,8 +2304,6 @@ namespace ts { throw new Error("indexed access not implemented"); } - const objectFlags = getObjectFlags(type); - if (objectFlags & ObjectFlags.ClassOrInterface) { Debug.assert(!!(type.flags & TypeFlags.Object)); const name = getNameOfSymbol(type.symbol); @@ -2276,15 +2312,6 @@ namespace ts { return createTypeReferenceNode(name); } - if (objectFlags & ObjectFlags.Reference) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - // and vice versa. - // this case includes tuple types - // TODO: test empty tuples, see if they are coherent. - const typeArguments = (type as TypeReference).typeArguments || emptyArray; - return createTupleTypeNode(mapToTypeNodeArray(typeArguments)) - } - // keyword types // this type node // function type node @@ -2336,67 +2363,152 @@ namespace ts { // The type is an object literal type. if (!type.symbol) { // Anonymous types without symbols are literals. - - // mapToTypeDeclarationsArray(type) throw new Error("unknown case."); } - const members = type.symbol.members; - const newMembers: TypeElement[] = []; - memberLoop: for(const key in members){ - const oldMember = members.get(key); - const name = getNameOfSymbol(oldMember); - const oldDeclaration = oldMember.declarations && oldMember.declarations[0] as TypeElement; - if(!oldDeclaration) { - continue memberLoop; - } - - const kind = oldDeclaration.kind; - - switch (kind) { - case SyntaxKind.PropertySignature: - const optional = !!oldDeclaration.questionToken; - newMembers.push(createPropertySignature( - createIdentifier(name) - , optional ? createToken(SyntaxKind.QuestionToken) : undefined - , createTypeNode(getTypeOfSymbol(oldMember)))); - case SyntaxKind.MethodSignature: - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.IndexSignature: - default: - throw new Error("type literal constituent not implemented."); - } - } - return createTypeLiteralNode(newMembers); + return createTypeLiteralNodeFromType(type); } Debug.fail("Should be unreachable."); - // function createTypeParameterDeclarationFromType(type: Type): TypeParameterDeclaration { - // if (!type) { - // if (undefinedArgumentIsError) { encounteredError = true; } - // return undefined; - // } - // if (type.flags & TypeFlags.TypeParameter) { - // const constraint = createTypeNodeWorker(getConstraintFromTypeParameter(type)) as TypeNode; - // const defaultParameter = createTypeNodeWorker(getDefaultFromTypeParameter(type)) as TypeNode; - // if (!type.symbol) { - // encounteredError = true; - // throw new Error("No symbol for type parameter so can't get name"); - // } - // const name = getNameOfSymbol(type.symbol); - // return createTypeParameterDeclaration(name, constraint, defaultParameter); - // } - // throw new Error("type declarations not implemented."); - // } - /** Note that mapToTypeNodeArray(undefined) === undefined. */ function mapToTypeNodeArray(types: Type[]): NodeArray { return asNodeArray(types && types.map(createTypeNodeWorker) as TypeNode[]); } + function createTypeReferenceNodeFromType(type: TypeReference) { + const typeArguments: Type[] = type.typeArguments || emptyArray; + if (type.target === globalArrayType) { + const elementType = createTypeNodeWorker(typeArguments[0]); + return createArrayTypeNode(elementType); + } + else if (type.target.objectFlags & ObjectFlags.Tuple) { + return createTupleTypeNode(mapToTypeNodeArray(typeArguments.slice(0, getTypeReferenceArity(type)))); + } + else { + // TODO: handle type parameters in qualified names... + const outerTypeParameters = type.target.outerTypeParameters; + let i = 0; + let qualifiedName: QualifiedName | undefined = undefined; + if (outerTypeParameters) { + const length = outerTypeParameters.length; + while (i < length) { + // Find group of type arguments for type parameters with the same declaring container. + const start = i; + const parent = getParentSymbolOfTypeParameter(outerTypeParameters[i]); + do { + i++; + } while (i < length && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent); + // When type parameters are their own type arguments for the whole group (i.e. we have + // the default outer type arguments), we don't show the group. + // TODO: figure out how to handle type arguments + if (!rangeEquals(outerTypeParameters, typeArguments, start, i)) { + const name = symbolToString(parent); + const qualifiedNamePart = createIdentifier(name); // createTypeReferenceNode(name, mapToTypeNodeArray(typeArguments.slice(start, i - start))); + if (!qualifiedName) { + qualifiedName = createQualifiedName(qualifiedNamePart, /*right*/undefined); + } + else { + Debug.assert(!qualifiedName.right); + qualifiedName.right = qualifiedNamePart; + qualifiedName = createQualifiedName(qualifiedName, /*right*/undefined); + } + } + } + } + let entityName: EntityName = undefined; + const nameIdentifier = createIdentifier(symbolToString(type.symbol)); + if (qualifiedName) { + // TODO: handle checking of type arguments for qualified names? + Debug.assert(!qualifiedName.right); + qualifiedName.right = nameIdentifier; + entityName = qualifiedName; + } + else { + entityName = nameIdentifier; + } + const typeParameterCount = (type.target.typeParameters || emptyArray).length; + const typeArgumentNodes = mapToTypeNodeArray(typeArguments.slice(i, typeParameterCount - i)); + return createTypeReferenceNode(entityName, typeArgumentNodes); + } + } + + function createTypeLiteralNodeFromType(type: ObjectType) { + // TODO: do we need to do something for mapped types here??? + const resolvedType = resolveStructuredTypeMembers(type); + const newMembers = createTypeNodesFromResolvedType(resolvedType); + return createTypeLiteralNode(newMembers); + } + + function createTypeNodesFromResolvedType(resolvedType: ResolvedType): TypeElement[] { + const typeElements: TypeElement[] = []; + for(const signature of resolvedType.callSignatures) { + signature; + throw new Error("call signatures not implemented"); + } + for (const signature of resolvedType.constructSignatures) { + signature; + throw new Error("Construct signatures not implemented"); + } + if (resolvedType.stringIndexInfo) { + typeElements.push(createIndexSignatureFromIndexInfo(resolvedType.stringIndexInfo, IndexKind.String)); + } + if (resolvedType.numberIndexInfo) { + typeElements.push(createIndexSignatureFromIndexInfo(resolvedType.stringIndexInfo, IndexKind.Number)); + } + + const members = resolvedType.members; + + members.forEach(memberSymbol => { + const oldDeclaration = memberSymbol.declarations && memberSymbol.declarations[0] as TypeElement; + if (!oldDeclaration) { + return; + } + + const kind = oldDeclaration.kind; + const memberName = symbolToString(memberSymbol); + + switch (kind) { + case SyntaxKind.PropertySignature: + const optional = !!oldDeclaration.questionToken; + const typeOfOldMember = getTypeOfSymbol(memberSymbol); + typeElements.push(createPropertySignature( + createIdentifier(memberName) + , optional ? createToken(SyntaxKind.QuestionToken) : undefined + , createTypeNode(typeOfOldMember))); + break; + case SyntaxKind.MethodSignature: + case SyntaxKind.CallSignature: + case SyntaxKind.ConstructSignature: + case SyntaxKind.IndexSignature: + throw new Error("type literal constituent not implemented."); + default: + throw new Error("Unknown case."); + } + }); + return typeElements.length ? typeElements : undefined; + } + + function createIndexSignatureFromIndexInfo(indexInfo: IndexInfo, kind: IndexKind) { + const stringTypeNode = createKeywordTypeNode(kind === IndexKind.String ? SyntaxKind.StringKeyword : SyntaxKind.NumberKeyword); + + const name = (indexInfo.declaration && indexInfo.declaration.name && getTextOfPropertyName(indexInfo.declaration.name)) || "x"; + const indexingParameter = createParameter( + /*decorators*/ undefined + , /*modifiers*/ undefined + , /*dotDotDotToken*/ undefined + , name + , /*questionToken*/ undefined + , stringTypeNode); + const typeNode = createTypeNode(indexInfo.type); + return createIndexSignatureDeclaration( + [indexingParameter] + , typeNode + , /*decoarators*/ undefined + , indexInfo.isReadonly ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined); + } + // /** Note that mapToTypeNodeArray(undefined) === undefined. */ // function mapToTypeParameterArray(types: Type[]): NodeArray { // return asNodeArray(types && types.map(createTypeParameterDeclarationFromType) as TypeNode[]); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index fd85ad9cab..e3c5525e06 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2466,8 +2466,11 @@ namespace ts { */ /* @internal */ getParameterType(signature: Signature, parameterIndex: number): Type; getNonNullableType(type: Type): Type; + /** Note that the resulting type node cannot be checked. */ createTypeNode(type: Type): TypeNode; + /** Note that the resulting type node cannot be checked. */ + createTypeParameterDeclarationFromType(type: Type): TypeParameterDeclaration; getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; getSymbolAtLocation(node: Node): Symbol; diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index fb76e83faa..8c4eb40a3e 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -91,9 +91,11 @@ namespace ts.codefix { // TODO: get parameters working. // TODO: add support for type parameters. const signature = signatures[0]; + const newTypeParameters = signature.typeParameters && signature.typeParameters.map(checker.createTypeParameterDeclarationFromType); const newParameterNodes = signature.getParameters().map(symbol => createParameterDeclarationFromSymbol(symbol, enclosingDeclaration, checker)); - const returnType = checker.createTypeNode(signature.resolvedReturnType); - return createStubbedMethod(modifiers, name, /*typeParameters*/undefined, newParameterNodes, returnType); + + const returnType = checker.createTypeNode(checker.getReturnTypeOfSignature(signature)); + return createStubbedMethod(modifiers, name, newTypeParameters, newParameterNodes, returnType); } let signatureDeclarations = []; @@ -101,6 +103,7 @@ namespace ts.codefix { // const sigString = checker.signatureToString(signatures[i], enclosingDeclaration, TypeFormatFlags.SuppressAnyReturnType, SignatureKind.Call); // TODO: make signatures instead of methods const signature = signatures[i]; + const newTypeParameters = signature.typeParameters && signature.typeParameters.map(checker.createTypeParameterDeclarationFromType); const newParameterNodes = signature.getParameters().map(symbol => createParameterDeclarationFromSymbol(symbol, enclosingDeclaration, checker)); const returnType = checker.createTypeNode(signature.resolvedReturnType); signatureDeclarations.push(createMethod( @@ -108,7 +111,7 @@ namespace ts.codefix { , modifiers , /*asteriskToken*/ undefined , name - , /*typeParameters*/undefined + , newTypeParameters , newParameterNodes , returnType , /*body*/undefined)); @@ -116,9 +119,10 @@ namespace ts.codefix { if (declarations.length > signatures.length) { let signature = checker.getSignatureFromDeclaration(declarations[declarations.length - 1] as SignatureDeclaration); + const newTypeParameters = signature.typeParameters && signature.typeParameters.map(checker.createTypeParameterDeclarationFromType); const newParameterNodes = signature.getParameters().map(symbol => createParameterDeclarationFromSymbol(symbol, enclosingDeclaration, checker)); const returnType = checker.createTypeNode(signature.resolvedReturnType); - signatureDeclarations.push(createStubbedMethod(modifiers, name, /*typeParameters*/undefined, newParameterNodes, returnType)); + signatureDeclarations.push(createStubbedMethod(modifiers, name, newTypeParameters, newParameterNodes, returnType)); } else { Debug.assert(declarations.length === signatures.length); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceSomePropertiesPresent.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceSomePropertiesPresent.ts index 03807ab450..e667783b99 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceSomePropertiesPresent.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceSomePropertiesPresent.ts @@ -6,8 +6,8 @@ //// z: number & { __iBrand: any }; //// } //// -//// class C implements I {[| |] -//// constructor(public x: number) { } +//// class C implements I {[| +//// |]constructor(public x: number) { } //// y: number; //// } From d298f960ab6dff2acb408e856c1e79ae9302986a Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Mon, 13 Mar 2017 18:09:53 -0700 Subject: [PATCH 063/164] Refactor --- src/compiler/checker.ts | 112 +++++++----------- src/compiler/factory.ts | 45 +++---- src/compiler/visitor.ts | 7 +- src/services/codefixes/fixAddMissingMember.ts | 6 +- .../fixClassIncorrectlyImplementsInterface.ts | 4 +- .../codeFixClassExtendAbstractMethod.ts | 4 + .../codeFixClassExtendAbstractProperty.ts | 4 - 7 files changed, 78 insertions(+), 104 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ee999b3fe1..ea7c01b973 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2211,7 +2211,10 @@ namespace ts { let inObjectTypeLiteral = false; let checkAlias = true; - return createTypeNodeWorker(type); + let result = createTypeNodeWorker(type); + (result).__type_source = type; + (result).__type_source_str = typeToString(type); + return result; function createTypeNodeWorker(type: Type): TypeNode { if (!type) { @@ -2221,12 +2224,6 @@ namespace ts { const typeString = typeToString(type); typeString; // TODO: remove. - if (checkAlias && type.aliasSymbol) { - const name = getNameOfSymbol(type.aliasSymbol); - const typeArguments = mapToTypeNodeArray(type.aliasTypeArguments); - return createTypeReferenceNode(createIdentifier(name), typeArguments); - } - checkAlias = false; if (type.flags & TypeFlags.Any) { // TODO: add other case where type ends up being `any`. @@ -2271,14 +2268,14 @@ namespace ts { if (type.flags & TypeFlags.ESSymbol) { throw new Error("ESSymbol not implemented"); } - if (type.flags & TypeFlags.TypeParameter) { - if ((type).isThisType) { - if (inObjectTypeLiteral) { - encounteredError = true; - } - return createThis(); + if (type.flags & TypeFlags.NonPrimitive) { + throw new Error("Non primitive not implemented"); + } + if (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType) { + if (inObjectTypeLiteral) { + encounteredError = true; } - throw new Error("Type Parameter declarations only handled in other worker."); + return createThis(); } const objectFlags = getObjectFlags(type); @@ -2291,64 +2288,35 @@ namespace ts { return createTypeReferenceNodeFromType(type); } + if (type.flags & TypeFlags.EnumLiteral) { + throw new Error("Enum literal not implemented"); + } + if (objectFlags & ObjectFlags.ClassOrInterface) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + const name = getNameOfSymbol(type.symbol); + // TODO: handle type arguments. + // TODO: handle anonymous classes. + return createTypeReferenceNode(name, /*typeParameters*/undefined); + } + if (type.flags & TypeFlags.TypeParameter) { + throw new Error("Type Parameter declarations only handled in other worker."); + } + + // accessible type aliasSymbol + // TODO: move back up later on? + if (checkAlias && type.aliasSymbol) { + const name = getNameOfSymbol(type.aliasSymbol); + const typeArgumentNodes = mapToTypeNodeArray(type.aliasTypeArguments); + return createTypeReferenceNode(createIdentifier(name), typeArgumentNodes); + } + checkAlias = false; + if (type.flags & TypeFlags.Union) { return createUnionOrIntersectionTypeNode(SyntaxKind.UnionType, mapToTypeNodeArray((type as UnionType).types)); } if (type.flags & TypeFlags.Intersection) { return createUnionOrIntersectionTypeNode(SyntaxKind.IntersectionType, mapToTypeNodeArray((type as UnionType).types)); } - if (type.flags & TypeFlags.Index) { - throw new Error("index not implemented"); - } - if (type.flags & TypeFlags.IndexedAccess) { - throw new Error("indexed access not implemented"); - } - - if (objectFlags & ObjectFlags.ClassOrInterface) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - const name = getNameOfSymbol(type.symbol); - // TODO: handle type arguments. - // TODO: handle anonymous classes. - return createTypeReferenceNode(name); - } - - // keyword types - // this type node - // function type node - // constructor type node - // type reference node - // type predicate node - is Foo (for return types) - // type query node -- typeof number - // type literal node (like object literal) - // array type - // tuple type - // union type - // might need parens - // intersection type - // Type operator node (eg (ie?): keyof T) - // IndexedAccess Type Node - // mapped type node - // literal type node - - // if (inTypeAlias && type.aliasSymbol) { - // return isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/false).accessibility === SymbolAccessibility.Accessible - // && (!type.aliasTypeArguments || allTypesVisible(type.aliasTypeArguments)); - // } - // const typeSymbolAccessibility = type.symbol && isSymbolAccessible(type.symbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility; - // if (type.flags & TypeFlags.TypeParameter) { - // if (inObjectLiteral && (type as TypeParameter).isThisType) { - // return false; - // } - // const constraint = getConstraintFromTypeParameter((type)); - // return typeSymbolAccessibility === SymbolAccessibility.Accessible - // && (!constraint || isTypeAccessibleWorker(constraint, inObjectLiteral, /*inTypeAlias*/false)); - // } - // const objectFlags = getObjectFlags(type); - // if (objectFlags & ObjectFlags.ClassOrInterface) { - // // If type is a class or interface type that wasn't hit by the isSymbolAccessible check above, - // // type must be an anonymous class or interface. - // return false; - // } if (objectFlags & ObjectFlags.Mapped) { Debug.assert(!!(type.flags & TypeFlags.Object)); @@ -2370,6 +2338,15 @@ namespace ts { return createTypeLiteralNodeFromType(type); } + // TODO: string or number literal here or above? + + if (type.flags & TypeFlags.Index) { + throw new Error("index not implemented"); + } + if (type.flags & TypeFlags.IndexedAccess) { + throw new Error("indexed access not implemented"); + } + Debug.fail("Should be unreachable."); /** Note that mapToTypeNodeArray(undefined) === undefined. */ @@ -2476,7 +2453,8 @@ namespace ts { typeElements.push(createPropertySignature( createIdentifier(memberName) , optional ? createToken(SyntaxKind.QuestionToken) : undefined - , createTypeNode(typeOfOldMember))); + , createTypeNode(typeOfOldMember) + , /*initializer*/undefined)); break; case SyntaxKind.MethodSignature: case SyntaxKind.CallSignature: diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 14af23e95b..7eb44f93bc 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -248,30 +248,30 @@ namespace ts { : node; } - // TODO: handle qualified names, ie EntityName's. - export function createTypeReferenceNode(typeName: string | EntityName, typeArguments?: NodeArray) { + export function createTypeReferenceNode(typeName: string | EntityName, typeArguments: NodeArray | undefined) { const typeReference = createSynthesizedNode(SyntaxKind.TypeReference) as TypeReferenceNode; - + typeReference.typeName = isQualifiedName(typeName) ? typeName : asName(typeName); typeReference.typeArguments = typeArguments; return typeReference; } + export function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined) { + return node.typeName !== typeName + || node.typeArguments !== typeArguments + ? updateNode(createTypeReferenceNode(typeName, typeArguments), node) + : node; + } + export function createArrayTypeNode(elementType: TypeNode): ArrayTypeNode { const arrayTypeNode = createSynthesizedNode(SyntaxKind.ArrayType) as ArrayTypeNode; arrayTypeNode.elementType = elementType; return arrayTypeNode; } - + export function updateArrayTypeNode(node: ArrayTypeNode, elementType: TypeNode): ArrayTypeNode { return node.elementType !== elementType - ? updateNode(createArrayTypeNode(elementType), node) - : node; - } - export function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments?: NodeArray) { - return node.typeName !== typeName - || node.typeArguments !== typeArguments - ? updateNode(createTypeReferenceNode(typeName, typeArguments), node) + ? updateNode(createArrayTypeNode(elementType), node) : node; } @@ -316,7 +316,7 @@ namespace ts { // Type Declarations - export function createTypeParameterDeclaration(name: string | Identifier, constraint?: TypeNode, defaultParameter?: TypeNode) { + export function createTypeParameterDeclaration(name: string | Identifier, constraint: TypeNode | undefined, defaultParameter: TypeNode | undefined) { const typeParameter = createSynthesizedNode(SyntaxKind.TypeParameter) as TypeParameterDeclaration; typeParameter.name = asName(name); typeParameter.constraint = constraint; @@ -325,7 +325,7 @@ namespace ts { return typeParameter; } - export function updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint?: TypeNode, defaultParameter?: TypeNode) { + export function updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode | undefined, defaultParameter: TypeNode | undefined) { return node.name !== name || node.constraint !== constraint || node.default !== defaultParameter @@ -335,7 +335,7 @@ namespace ts { // Signature elements - export function createPropertySignature(name: PropertyName, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression): PropertySignature { + export function createPropertySignature(name: PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertySignature { const propertySignature = createSynthesizedNode(SyntaxKind.PropertySignature) as PropertySignature; propertySignature.name = name; propertySignature.questionToken = questionToken; @@ -344,7 +344,7 @@ namespace ts { return propertySignature; } - export function updatePropertySignature(node: PropertySignature, name: PropertyName, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression) { + export function updatePropertySignature(node: PropertySignature, name: PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) { return node.name !== name || node.questionToken !== questionToken || node.type !== type @@ -353,18 +353,7 @@ namespace ts { : node; } - export function createSignature(kind: SyntaxKind, parameters: NodeArray, name?: PropertyName, typeParameters?: NodeArray, returnType?: TypeNode): SignatureDeclaration { - const signature = createSynthesizedNode(kind) as SignatureDeclaration; - signature.parameters = parameters; - signature.name = name; - signature.typeParameters = typeParameters; - signature.type = returnType; - return signature; - } - - // TODO: check usage of name... - // TODO: create entry in visitor.ts - export function createIndexSignatureDeclaration(parameters: ParameterDeclaration[], type: TypeNode, decorators?: Decorator[], modifiers?: Modifier[]): IndexSignatureDeclaration { + export function createIndexSignatureDeclaration(parameters: ParameterDeclaration[], type: TypeNode, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined): IndexSignatureDeclaration { const indexSignature = createSynthesizedNode(SyntaxKind.IndexSignature) as IndexSignatureDeclaration; // indexSignature.name = asName(name); // type parameters @@ -375,7 +364,7 @@ namespace ts { return indexSignature; } - export function updateIndexSignatureDeclaration(node: IndexSignatureDeclaration, parameters: ParameterDeclaration[], type: TypeNode, decorators?: Decorator[], modifiers?: Modifier[]) { + export function updateIndexSignatureDeclaration(node: IndexSignatureDeclaration, parameters: ParameterDeclaration[], type: TypeNode, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined) { return node.parameters !== parameters || node.type !== type || node.decorators !== decorators diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 547178e3b7..3b75e072a5 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -302,8 +302,8 @@ namespace ts { case SyntaxKind.TypeReference: return updateTypeReferenceNode(node , visitNode((node).typeName, visitor, isEntityName) - , nodesVisitor((node).typeArguments, visitor, isTypeNode) - ); + , nodesVisitor((node).typeArguments, visitor, isTypeNode)); + case SyntaxKind.FunctionType: throw new Error("reached unsupported type in visitor."); case SyntaxKind.ConstructorType: @@ -347,7 +347,8 @@ namespace ts { return updatePropertySignature((node) , visitNode((node).name, visitor, isPropertyName) , visitNode((node).questionToken, visitor, isToken) - , visitNode((node).type, visitor, isTypeNode)); + , visitNode((node).type, visitor, isTypeNode) + , visitNode((node).initializer, visitor, isExpression)); case SyntaxKind.IndexSignature: return updateIndexSignatureDeclaration(node diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index fe12249f17..2403c0adbe 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -62,7 +62,11 @@ namespace ts.codefix { , "x" , /*questionToken*/ undefined , stringTypeNode); - const indexSignature = createIndexSignatureDeclaration([indexingParameter], typeNode); + const indexSignature = createIndexSignatureDeclaration( + [indexingParameter] + , typeNode + , /*decorators*/undefined + , /*modifiers*/ undefined); const indexSignatureChangeTracker = textChanges.ChangeTracker.fromCodeFixContext(context); indexSignatureChangeTracker.insertNodeAfter(sourceFile, openBrace, indexSignature, { insertTrailingNewLine: true }); diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts index f653d21e02..220cea55d6 100644 --- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts +++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts @@ -62,7 +62,9 @@ namespace ts.codefix { , getNameFromIndexInfo(indexInfoOfKind) , /*questionToken*/ undefined , kind === IndexKind.String ? createKeywordTypeNode(SyntaxKind.StringKeyword) : createKeywordTypeNode(SyntaxKind.NumberKeyword))] - , typeNode); + , typeNode + , /*decorators*/undefined + , /*modifiers*/ undefined); newNodes.push(newIndexSignatureDeclaration); } diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractMethod.ts b/tests/cases/fourslash/codeFixClassExtendAbstractMethod.ts index b6b408cf5f..7e51e2216d 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractMethod.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractMethod.ts @@ -5,6 +5,7 @@ //// abstract f(a: number, b: string): this; //// abstract f(a: string, b: number): Function; //// abstract f(a: string): Function; +//// abstract foo(): number; //// } //// //// class C extends A {[| |]} @@ -17,4 +18,7 @@ verify.rangeAfterCodeFix(` f(a: any, b?: any) { throw new Error("Method not implemented."); } + foo(): number { + throw new Error("Method not implemented."); + } `); diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractProperty.ts b/tests/cases/fourslash/codeFixClassExtendAbstractProperty.ts index 83f770b555..701903d677 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractProperty.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractProperty.ts @@ -4,7 +4,6 @@ //// abstract x: number; //// abstract y: this; //// abstract z: A; -//// abstract foo(): number; //// } //// //// class C extends A {[| |]} @@ -13,7 +12,4 @@ verify.rangeAfterCodeFix(` x: number; y: this; z: A; - foo(): number { - throw new Error("Method not implemented."); - } `); From 27fe2df203eb552976c853b704f6682eb8e81ae2 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Mon, 13 Mar 2017 20:20:26 -0700 Subject: [PATCH 064/164] some missed token bugs --- src/compiler/checker.ts | 11 ++---- src/compiler/factory.ts | 9 +++-- src/compiler/transformers/esnext.ts | 1 + src/compiler/types.ts | 2 +- src/compiler/visitor.ts | 1 + src/services/codefixes/fixAddMissingMember.ts | 3 +- src/services/codefixes/helpers.ts | 39 +++++++++---------- src/services/textChanges.ts | 2 +- .../codeFixClassExtendAbstractGetterSetter.ts | 2 +- 9 files changed, 34 insertions(+), 36 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ea7c01b973..ca105c4113 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2361,7 +2361,7 @@ namespace ts { return createArrayTypeNode(elementType); } else if (type.target.objectFlags & ObjectFlags.Tuple) { - return createTupleTypeNode(mapToTypeNodeArray(typeArguments.slice(0, getTypeReferenceArity(type)))); + return createTupleTypeNode(typeArguments.length > 0 ? mapToTypeNodeArray(typeArguments.slice(0, getTypeReferenceArity(type))) : undefined); } else { // TODO: handle type parameters in qualified names... @@ -2406,7 +2406,7 @@ namespace ts { entityName = nameIdentifier; } const typeParameterCount = (type.target.typeParameters || emptyArray).length; - const typeArgumentNodes = mapToTypeNodeArray(typeArguments.slice(i, typeParameterCount - i)); + const typeArgumentNodes = mapToTypeNodeArray(typeArguments.length > 0 ? typeArguments.slice(i, typeParameterCount - i) : undefined); return createTypeReferenceNode(entityName, typeArgumentNodes); } } @@ -2478,7 +2478,8 @@ namespace ts { , /*dotDotDotToken*/ undefined , name , /*questionToken*/ undefined - , stringTypeNode); + , stringTypeNode + , /*initializer*/ undefined); const typeNode = createTypeNode(indexInfo.type); return createIndexSignatureDeclaration( [indexingParameter] @@ -7261,10 +7262,6 @@ namespace ts { } } - // export function synthesizeTypeNode(type: Type, enclosingDeclaration: Node): TypeNode { - // throw new Error("Not implemented" + enclosingDeclaration); - // } - function instantiateList(items: T[], mapper: TypeMapper, instantiator: (item: T, mapper: TypeMapper) => T): T[] { if (items && items.length) { const result: T[] = []; diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 7eb44f93bc..077bc34986 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -355,8 +355,6 @@ namespace ts { export function createIndexSignatureDeclaration(parameters: ParameterDeclaration[], type: TypeNode, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined): IndexSignatureDeclaration { const indexSignature = createSynthesizedNode(SyntaxKind.IndexSignature) as IndexSignatureDeclaration; - // indexSignature.name = asName(name); - // type parameters indexSignature.parameters = asNodeArray(parameters); indexSignature.type = type; indexSignature.decorators = asNodeArray(decorators); @@ -373,6 +371,8 @@ namespace ts { : node; } + // Signature elements + export function createParameter(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression) { const node = createSynthesizedNode(SyntaxKind.Parameter); node.decorators = asNodeArray(decorators); @@ -385,11 +385,12 @@ namespace ts { return node; } - export function updateParameter(node: ParameterDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: BindingName, type: TypeNode | undefined, initializer: Expression | undefined) { + export function updateParameter(node: ParameterDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.dotDotDotToken !== dotDotDotToken || node.name !== name + || node.questionToken !== questionToken || node.type !== type || node.initializer !== initializer ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, node.questionToken, type, initializer), node) @@ -438,7 +439,7 @@ namespace ts { node.asteriskToken = asteriskToken; node.name = asName(name); node.typeParameters = asNodeArray(typeParameters); - node.parameters = createNodeArray(parameters); + node.parameters = asNodeArray(parameters); node.type = type; node.body = body; return node; diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index 971dddd20e..f66bf14da5 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -475,6 +475,7 @@ namespace ts { /*modifiers*/ undefined, node.dotDotDotToken, getGeneratedNameForNode(node), + node.questionToken, /*type*/ undefined, visitNode(node.initializer, visitor, isExpression) ); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index e3c5525e06..bccf0f1c4f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -895,7 +895,7 @@ namespace ts { exprName: EntityName; } - /** A TypeLiteral is the declaration node for an anonymous symbol. */ + // A TypeLiteral is the declaration node for an anonymous symbol. export interface TypeLiteralNode extends TypeNode, Declaration { kind: SyntaxKind.TypeLiteral; members: NodeArray; diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 3b75e072a5..e64e59eba3 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -272,6 +272,7 @@ namespace ts { nodesVisitor((node).modifiers, visitor, isModifier), (node).dotDotDotToken, visitNode((node).name, visitor, isBindingName), + visitNode((node).questionToken, visitor, isToken), visitNode((node).type, visitor, isTypeNode), visitNode((node).initializer, visitor, isExpression)); diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index 2403c0adbe..61c823908d 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -61,7 +61,8 @@ namespace ts.codefix { , /*dotDotDotToken*/ undefined , "x" , /*questionToken*/ undefined - , stringTypeNode); + , stringTypeNode + , /*initializer*/ undefined); const indexSignature = createIndexSignatureDeclaration( [indexingParameter] , typeNode diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 8c4eb40a3e..2db14f81df 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -126,7 +126,7 @@ namespace ts.codefix { } else { Debug.assert(declarations.length === signatures.length); - const methodImplementingSignatures = createMethodImplementingSignatures(signatures, enclosingDeclaration, name, modifiers); + const methodImplementingSignatures = createMethodImplementingSignatures(signatures, name, modifiers); signatureDeclarations.push(methodImplementingSignatures); } return signatureDeclarations; @@ -135,11 +135,8 @@ namespace ts.codefix { } } - // TODO: infer types of arguments? - function createMethodImplementingSignatures(signatures: Signature[], enclosingDeclaration: ClassLikeDeclaration, name: string, modifiers: Modifier[] | undefined): MethodDeclaration { - const newMethodDeclaration = createNode(SyntaxKind.CallSignature) as SignatureDeclaration; - newMethodDeclaration.parent = enclosingDeclaration; - newMethodDeclaration.name = signatures[0].getDeclaration().name; + function createMethodImplementingSignatures(signatures: Signature[], name: string, modifiers: Modifier[] | undefined): MethodDeclaration { + Debug.assert(signatures && signatures.length > 0); let maxNonRestArgs = -1; let maxArgsIndex = 0; @@ -157,46 +154,45 @@ namespace ts.codefix { } const maxArgsParameterSymbolNames = signatures[maxArgsIndex].getParameters().map(symbol => symbol.getName()); - const parameters = createNodeArray(); + const parameters: ParameterDeclaration[] = []; for (let i = 0; i < maxNonRestArgs; i++) { + const anyType = createKeywordTypeNode(SyntaxKind.AnyKeyword); const newParameter = createParameter( /*decorators*/ undefined , /*modifiers*/ undefined , /*dotDotDotToken*/ undefined , maxArgsParameterSymbolNames[i] , /*questionToken*/ i >= minArgumentCount ? createToken(SyntaxKind.QuestionToken) : undefined - , /*type*/ undefined + , anyType , /*initializer*/ undefined); parameters.push(newParameter); } if (hasRestParameter) { + const anyType = createKeywordTypeNode(SyntaxKind.AnyKeyword); const restParameter = createParameter( /*decorators*/ undefined , /*modifiers*/ undefined , createToken(SyntaxKind.DotDotDotToken) , maxArgsParameterSymbolNames[maxNonRestArgs] || "rest" , /*questionToken*/ maxNonRestArgs >= minArgumentCount ? createToken(SyntaxKind.QuestionToken) : undefined - , /*type*/ undefined + , anyType , /*initializer*/ undefined); parameters.push(restParameter); } - return createMethod( - /*decorators*/ undefined - , modifiers - , /*asteriskToken*/ undefined + return createStubbedMethod( + modifiers , name , /*typeParameters*/undefined , parameters - , /*type*/ undefined - , /*body*/undefined); + , /*returnType*/ undefined); } - export function createStubbedMethod(modifiers: Modifier[], name: string, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], returnType?: TypeNode) { + export function createStubbedMethod(modifiers: Modifier[], name: string, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], returnType: TypeNode | undefined) { return createMethod( /*decorators*/undefined - , /*modifiers*/modifiers + , modifiers , /*asteriskToken*/undefined , name , typeParameters @@ -231,12 +227,13 @@ namespace ts.codefix { const parameterTypeNode = checker.createTypeNode(parameterType); // TODO: deep cloning of decorators/any node. const parameterNode = createParameter( - parameterDeclaration.decorators && parameterDeclaration.decorators.map(getSynthesizedClone) - , parameterDeclaration.modifiers && parameterDeclaration.modifiers.map(getSynthesizedClone) + parameterDeclaration.decorators && parameterDeclaration.decorators.map(getSynthesizedDeepClone) + , parameterDeclaration.modifiers && parameterDeclaration.modifiers.map(getSynthesizedDeepClone) , parameterDeclaration.dotDotDotToken && createToken(SyntaxKind.DotDotDotToken) - , parameterDeclaration.name + , getSynthesizedDeepClone(parameterDeclaration.name) , parameterDeclaration.questionToken && createToken(SyntaxKind.QuestionToken) - , parameterTypeNode); + , parameterTypeNode + , /*initializer*/ undefined); return parameterNode; } diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index cb8c614cb2..71536dc75f 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -360,7 +360,7 @@ namespace ts.textChanges { return visited; } // clone nodearray if necessary - const nodeArray = visited === nodes ? createNodeArray(visited) : visited; + const nodeArray = visited === nodes ? createNodeArray(visited.slice(0)) : visited; nodeArray.pos = getPos(nodes); nodeArray.end = getEnd(nodes); return nodeArray; diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractGetterSetter.ts b/tests/cases/fourslash/codeFixClassExtendAbstractGetterSetter.ts index 4bddfb799f..bc437c93bc 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractGetterSetter.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractGetterSetter.ts @@ -28,4 +28,4 @@ verify.rangeAfterCodeFix(` e: this; f: A; g: string; -`); \ No newline at end of file +`); From 6e86596a732c868cc709dcc5c1db21566030a373 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 13 Mar 2017 22:43:37 -0700 Subject: [PATCH 065/164] Add debugging utilities --- src/harness/fourslash.ts | 11 ++++++++++- tests/cases/fourslash/fourslash.ts | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 0df9f4f4dd..11103bf6e2 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1,4 +1,4 @@ -// +// // Copyright (c) Microsoft Corporation. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -2550,6 +2550,11 @@ namespace FourSlash { } } + public printAvailableCodeFixes() { + const codeFixes = this.getCodeFixActions(this.activeFile.fileName); + Harness.IO.log(stringify(codeFixes)); + } + // Get the text of the entire line the caret is currently at private getCurrentLineContent() { const text = this.getFileContent(this.activeFile.fileName); @@ -3738,6 +3743,10 @@ namespace FourSlashInterface { this.state.printCompletionListMembers(); } + public printAvailableCodeFixes() { + this.state.printAvailableCodeFixes(); + } + public printBreakpointLocation(pos: number) { this.state.printBreakpointLocation(pos); } diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index ab83752d93..418066fb6f 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -296,6 +296,7 @@ declare namespace FourSlashInterface { printCurrentQuickInfo(): void; printCurrentSignatureHelp(): void; printCompletionListMembers(): void; + printAvailableCodeFixes(): void; printBreakpointLocation(pos: number): void; printBreakpointAtCurrentLocation(): void; printNameOrDottedNameSpans(pos: number): void; From fd9fb8f9bce4828fc657cfb36a3a47c3283a583c Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 13 Mar 2017 22:49:54 -0700 Subject: [PATCH 066/164] Support static properties --- src/services/codefixes/fixAddMissingMember.ts | 99 ++++++++++++------- .../fourslash/codeFixAddMissingMember.ts | 14 +++ .../fourslash/codeFixAddMissingMember2.ts | 14 +++ .../fourslash/codeFixAddMissingMember3.ts | 14 +++ .../fourslash/codeFixAddMissingMember4.ts | 22 +++++ .../fourslash/codeFixAddMissingMember5.ts | 19 ++++ .../fourslash/codeFixAddMissingMember6.ts | 18 ++++ .../fourslash/codeFixAddMissingMember7.ts | 15 +++ ...xUndeclaredIndexSignatureNumericLiteral.ts | 2 +- 9 files changed, 181 insertions(+), 36 deletions(-) create mode 100644 tests/cases/fourslash/codeFixAddMissingMember.ts create mode 100644 tests/cases/fourslash/codeFixAddMissingMember2.ts create mode 100644 tests/cases/fourslash/codeFixAddMissingMember3.ts create mode 100644 tests/cases/fourslash/codeFixAddMissingMember4.ts create mode 100644 tests/cases/fourslash/codeFixAddMissingMember5.ts create mode 100644 tests/cases/fourslash/codeFixAddMissingMember6.ts create mode 100644 tests/cases/fourslash/codeFixAddMissingMember7.ts diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index fe4176a766..bc2ee6fe0f 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -1,4 +1,4 @@ -/* @internal */ +/* @internal */ namespace ts.codefix { registerCodeFix({ errorCodes: [Diagnostics.Property_0_does_not_exist_on_type_1.code], @@ -13,22 +13,27 @@ namespace ts.codefix { // this.missing = 1; // ^^^^^^^ const token = getTokenAtPosition(sourceFile, start); - if (token.kind != SyntaxKind.Identifier) { return undefined; } - const classDeclaration = getContainingClass(token); - if (!classDeclaration) { - return undefined; - } - if (!isPropertyAccessExpression(token.parent) || token.parent.expression.kind !== SyntaxKind.ThisKeyword) { return undefined; } - return isInJavaScriptFile(sourceFile) ? getActionsForAddMissingMemberInJavaScriptFile() : getActionsForAddMissingMemberInTypeScriptFile(); + const classMemberDeclaration = getThisContainer(token, /*includeArrowFunctions*/ false); + if (!isClassElement(classMemberDeclaration)) { + return undefined; + } + const classDeclaration = classMemberDeclaration.parent; + if (!classDeclaration || !isClassLike(classDeclaration)) { + return undefined; + } + + const isStatic = hasModifier(getThisContainer(token, /*includeArrowFunctions*/ false), ModifierFlags.Static); + + return isInJavaScriptFile(sourceFile) ? getActionsForAddMissingMemberInJavaScriptFile() : getActionsForAddMissingMemberInTypeScriptFile(); function getActionsForAddMissingMemberInTypeScriptFile(): CodeAction[] | undefined { let typeString = "any"; @@ -43,47 +48,71 @@ namespace ts.codefix { const startPos = classDeclaration.members.pos; - return [{ + const actions = [{ description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_declaration_for_missing_property_0), [token.getText()]), changes: [{ fileName: sourceFile.fileName, textChanges: [{ span: { start: startPos, length: 0 }, - newText: `${token.getFullText(sourceFile)}: ${typeString};` - }] - }] - }, - { - description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_index_signature_for_missing_property_0), [token.getText()]), - changes: [{ - fileName: sourceFile.fileName, - textChanges: [{ - span: { start: startPos, length: 0 }, - newText: `[name: string]: ${typeString};` + newText: `${isStatic ? "static " : ""}${token.getFullText(sourceFile)}: ${typeString};` }] }] }]; + + if (!isStatic) { + actions.push({ + description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_index_signature_for_missing_property_0), [token.getText()]), + changes: [{ + fileName: sourceFile.fileName, + textChanges: [{ + span: { start: startPos, length: 0 }, + newText: `[x: string]: ${typeString};` + }] + }] + }); + } + + return actions; } function getActionsForAddMissingMemberInJavaScriptFile(): CodeAction[] | undefined { - const classConstructor = getFirstConstructorWithBody(classDeclaration); - if (!classConstructor) { - return undefined; - } - const memberName = token.getText(); - const startPos = classConstructor.body.getEnd() - 1; - return [{ - description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Initialize_property_0_in_the_constructor), [memberName]), - changes: [{ - fileName: sourceFile.fileName, - textChanges: [{ - span: { start: startPos, length: 0 }, - newText: `this.${memberName} = undefined;` + if (isStatic) { + if (classDeclaration.kind === SyntaxKind.ClassExpression) { + return undefined; + } + + const className = classDeclaration.name.getText(); + + return [{ + description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Initialize_static_property_0), [memberName]), + changes: [{ + fileName: sourceFile.fileName, + textChanges: [{ + span: { start: classDeclaration.getEnd(), length: 0 }, + newText: `${context.newLineCharacter}${className}.${memberName} = undefined;${context.newLineCharacter}` + }] }] - }] - }]; + }]; + } + else { + const classConstructor = getFirstConstructorWithBody(classDeclaration); + if (!classConstructor) { + return undefined; + } + + return [{ + description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Initialize_property_0_in_the_constructor), [memberName]), + changes: [{ + fileName: sourceFile.fileName, + textChanges: [{ + span: { start: classConstructor.body.getEnd() - 1, length: 0 }, + newText: `this.${memberName} = undefined;${context.newLineCharacter}` + }] + }] + }]; + } } } } \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixAddMissingMember.ts b/tests/cases/fourslash/codeFixAddMissingMember.ts new file mode 100644 index 0000000000..43c0bc3b76 --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingMember.ts @@ -0,0 +1,14 @@ +/// + +////[|class C { +//// method() { +//// this.foo = 10; +//// } +////}|] + +verify.rangeAfterCodeFix(`class C { + foo: number; + method() { + this.foo = 10; + } +}`, /*includeWhiteSpace*/false, /*errorCode*/ undefined, /*index*/ 0); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixAddMissingMember2.ts b/tests/cases/fourslash/codeFixAddMissingMember2.ts new file mode 100644 index 0000000000..7b64fde8c0 --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingMember2.ts @@ -0,0 +1,14 @@ +/// + +////[|class C { +//// method() { +//// this.foo = 10; +//// } +////}|] + +verify.rangeAfterCodeFix(`class C { + [x:string]: number; + method() { + this.foo = 10; + } +}`, /*includeWhiteSpace*/false, /*errorCode*/ undefined, /*index*/ 1); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixAddMissingMember3.ts b/tests/cases/fourslash/codeFixAddMissingMember3.ts new file mode 100644 index 0000000000..5864c9c102 --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingMember3.ts @@ -0,0 +1,14 @@ +/// + +////[|class C { +//// static method() { +//// this.foo = 10; +//// } +////}|] + +verify.rangeAfterCodeFix(`class C { + static foo: number; + static method() { + this.foo = 10; + } +}`); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixAddMissingMember4.ts b/tests/cases/fourslash/codeFixAddMissingMember4.ts new file mode 100644 index 0000000000..08df9ccabc --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingMember4.ts @@ -0,0 +1,22 @@ +/// + +// @checkJs: true +// @allowJs: true + +// @Filename: a.js +////[|class C { +//// constructor() { +//// } +//// method() { +//// this.foo === 10; +//// } +////}|] + +verify.rangeAfterCodeFix(`class C { + constructor() { + this.foo = undefined; +} + method() { + this.foo === 10; + } +}`, /*includeWhiteSpace*/false, /*errorCode*/ undefined, /*index*/ 0); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixAddMissingMember5.ts b/tests/cases/fourslash/codeFixAddMissingMember5.ts new file mode 100644 index 0000000000..cbabc0ba6c --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingMember5.ts @@ -0,0 +1,19 @@ +/// + +// @checkJs: true +// @allowJs: true + +// @Filename: a.js +////[|class C { +//// static method() { +//// ()=>{ this.foo === 10 }; +//// } +////} +////|] + +verify.rangeAfterCodeFix(`class C { + static method() { + ()=>{ this.foo === 10 }; + } +} +C.foo = undefined;`, /*includeWhiteSpace*/false, /*errorCode*/ undefined, /*index*/ 0); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixAddMissingMember6.ts b/tests/cases/fourslash/codeFixAddMissingMember6.ts new file mode 100644 index 0000000000..2f3911d779 --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingMember6.ts @@ -0,0 +1,18 @@ +/// + +// @checkJs: true +// @allowJs: true + +// @Filename: a.js +////[|class C { +//// constructor() { +//// } +//// prop = ()=>{ this.foo === 10 }; +////}|] + +verify.rangeAfterCodeFix(`class C { + constructor() { + this.foo = undefined; + } + prop = ()=>{ this.foo === 10 }; +}`, /*includeWhiteSpace*/false, /*errorCode*/ undefined, /*index*/ 0); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixAddMissingMember7.ts b/tests/cases/fourslash/codeFixAddMissingMember7.ts new file mode 100644 index 0000000000..0e937a3ab6 --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingMember7.ts @@ -0,0 +1,15 @@ +/// + +// @checkJs: true +// @allowJs: true + +// @Filename: a.js +////[|class C { +//// static p = ()=>{ this.foo === 10 }; +////} +////|] + +verify.rangeAfterCodeFix(`class C { + static p = ()=>{ this.foo === 10 }; +} +C.foo = undefined;`, /*includeWhiteSpace*/false, /*errorCode*/ undefined, /*index*/ 2); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixUndeclaredIndexSignatureNumericLiteral.ts b/tests/cases/fourslash/codeFixUndeclaredIndexSignatureNumericLiteral.ts index 2e49a8184e..0a2b0ee799 100644 --- a/tests/cases/fourslash/codeFixUndeclaredIndexSignatureNumericLiteral.ts +++ b/tests/cases/fourslash/codeFixUndeclaredIndexSignatureNumericLiteral.ts @@ -8,7 +8,7 @@ verify.rangeAfterCodeFix(` class A { - [name: string]: number; + [x: string]: number; constructor() { this.x = 10; From 509b2dc18e32ec0ac399b131a2381e12ef77e6de Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 13 Mar 2017 23:03:06 -0700 Subject: [PATCH 067/164] Add disableJsDiagnostics codefixes to harnes --- src/harness/tsconfig.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json index 2162232536..9f0e30baa1 100644 --- a/src/harness/tsconfig.json +++ b/src/harness/tsconfig.json @@ -1,4 +1,4 @@ -{ +{ "extends": "../tsconfig-base", "compilerOptions": { "removeComments": false, @@ -81,6 +81,7 @@ "../services/codefixes/helpers.ts", "../services/codefixes/importFixes.ts", "../services/codefixes/unusedIdentifierFixes.ts", + "../services/codefixes/disableJsDiagnostics.ts", "harness.ts", "sourceMapRecorder.ts", From 2fd3229568dad45411c9af7e3ca1234197b29bad Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Tue, 14 Mar 2017 14:35:23 -0700 Subject: [PATCH 068/164] Various fixes * create type reference node from type parameters * expose index signature synthesis * widen types in helpers * format unions * use deep cloning --- src/compiler/checker.ts | 74 ++++++++++--------- src/compiler/types.ts | 2 + src/compiler/utilities.ts | 4 + .../fixClassIncorrectlyImplementsInterface.ts | 13 +--- src/services/codefixes/helpers.ts | 18 ++--- .../codeFixClassImplementInterface36.ts | 18 ----- ...eFixClassImplementInterfaceInNamespace.ts} | 0 ...mplementInterfaceInheritsAbstractMethod.ts | 18 +++++ ...ssImplementInterfaceMultipleImplements1.ts | 4 +- ...ssImplementInterfaceMultipleImplements2.ts | 6 +- 10 files changed, 76 insertions(+), 81 deletions(-) delete mode 100644 tests/cases/fourslash/codeFixClassImplementInterface36.ts rename tests/cases/fourslash/{codeFixClassImplementInterface39.ts => codeFixClassImplementInterfaceInNamespace.ts} (100%) create mode 100644 tests/cases/fourslash/codeFixClassImplementInterfaceInheritsAbstractMethod.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ca105c4113..e9cea047ea 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -108,6 +108,7 @@ namespace ts { getNonNullableType, createTypeNode, createTypeParameterDeclarationFromType, + createIndexSignatureFromIndexInfo, getSymbolsInScope: (location, meaning) => { location = getParseTreeNode(location); return location ? getSymbolsInScope(location, meaning) : []; @@ -2190,16 +2191,13 @@ namespace ts { return result; } - function createTypeParameterDeclarationFromType(type: Type): TypeParameterDeclaration { + function createTypeParameterDeclarationFromType(type: TypeParameter): TypeParameterDeclaration { if (!(type && type.symbol && type.flags & TypeFlags.TypeParameter)) { return undefined; } - const constraint = createTypeNode(getConstraintFromTypeParameter(type)) as TypeNode; - const defaultParameter = createTypeNode(getDefaultFromTypeParameter(type)) as TypeNode; - if (!type.symbol) { - return undefined; - } + const constraint = createTypeNode(getConstraintFromTypeParameter(type)) as TypeNode; + const defaultParameter = createTypeNode(getDefaultFromTypeParameter(type)) as TypeNode; const name = symbolToString(type.symbol); return createTypeParameterDeclaration(name, constraint, defaultParameter); @@ -2212,8 +2210,10 @@ namespace ts { let checkAlias = true; let result = createTypeNodeWorker(type); - (result).__type_source = type; - (result).__type_source_str = typeToString(type); + if (result) { + (result).__type_source = type; + (result).__type_source_str = typeToString(type); + } return result; function createTypeNodeWorker(type: Type): TypeNode { @@ -2299,7 +2299,16 @@ namespace ts { return createTypeReferenceNode(name, /*typeParameters*/undefined); } if (type.flags & TypeFlags.TypeParameter) { - throw new Error("Type Parameter declarations only handled in other worker."); + const constraint = createTypeNode(getConstraintFromTypeParameter(type)) as TypeNode; + const defaultParameter = createTypeNode(getDefaultFromTypeParameter(type)) as TypeNode; + if(constraint || defaultParameter) { + // Type parameters in type position can't have constraints or defaults. + encounteredError = true; + return undefined; + } + // TODO: get qualified name when necessary instead of string. + const name = symbolToString(type.symbol); + return createTypeReferenceNode(name, /*typeArguments*/ undefined); } // accessible type aliasSymbol @@ -2312,7 +2321,7 @@ namespace ts { checkAlias = false; if (type.flags & TypeFlags.Union) { - return createUnionOrIntersectionTypeNode(SyntaxKind.UnionType, mapToTypeNodeArray((type as UnionType).types)); + return createUnionOrIntersectionTypeNode(SyntaxKind.UnionType, mapToTypeNodeArray(formatUnionTypes((type).types))); } if (type.flags & TypeFlags.Intersection) { return createUnionOrIntersectionTypeNode(SyntaxKind.IntersectionType, mapToTypeNodeArray((type as UnionType).types)); @@ -2467,34 +2476,29 @@ namespace ts { }); return typeElements.length ? typeElements : undefined; } - - function createIndexSignatureFromIndexInfo(indexInfo: IndexInfo, kind: IndexKind) { - const stringTypeNode = createKeywordTypeNode(kind === IndexKind.String ? SyntaxKind.StringKeyword : SyntaxKind.NumberKeyword); - - const name = (indexInfo.declaration && indexInfo.declaration.name && getTextOfPropertyName(indexInfo.declaration.name)) || "x"; - const indexingParameter = createParameter( - /*decorators*/ undefined - , /*modifiers*/ undefined - , /*dotDotDotToken*/ undefined - , name - , /*questionToken*/ undefined - , stringTypeNode - , /*initializer*/ undefined); - const typeNode = createTypeNode(indexInfo.type); - return createIndexSignatureDeclaration( - [indexingParameter] - , typeNode - , /*decoarators*/ undefined - , indexInfo.isReadonly ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined); - } - - // /** Note that mapToTypeNodeArray(undefined) === undefined. */ - // function mapToTypeParameterArray(types: Type[]): NodeArray { - // return asNodeArray(types && types.map(createTypeParameterDeclarationFromType) as TypeNode[]); - // } } } + function createIndexSignatureFromIndexInfo(indexInfo: IndexInfo, kind: IndexKind): IndexSignatureDeclaration { + const indexerTypeNode = createKeywordTypeNode(kind === IndexKind.String ? SyntaxKind.StringKeyword : SyntaxKind.NumberKeyword); + + const name = getNameFromIndexInfo(indexInfo); + const indexingParameter = createParameter( + /*decorators*/ undefined + , /*modifiers*/ undefined + , /*dotDotDotToken*/ undefined + , name + , /*questionToken*/ undefined + , indexerTypeNode + , /*initializer*/ undefined); + const typeNode = createTypeNode(indexInfo.type); + return createIndexSignatureDeclaration( + [indexingParameter] + , typeNode + , /*decorators*/ undefined + , indexInfo.isReadonly ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined); + } + function typePredicateToString(typePredicate: TypePredicate, enclosingDeclaration?: Declaration, flags?: TypeFormatFlags): string { const writer = getSingleLineStringWriter(); getSymbolDisplayBuilder().buildTypePredicateDisplay(typePredicate, writer, enclosingDeclaration, flags); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index bccf0f1c4f..28c293ae53 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2471,6 +2471,8 @@ namespace ts { createTypeNode(type: Type): TypeNode; /** Note that the resulting type node cannot be checked. */ createTypeParameterDeclarationFromType(type: Type): TypeParameterDeclaration; + /** Note that the resulting type node cannot be checked. */ + createIndexSignatureFromIndexInfo(indexInfo: IndexInfo, kind: IndexKind): IndexSignatureDeclaration getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; getSymbolAtLocation(node: Node): Symbol; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 030b66813a..b4d65958f3 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -524,6 +524,10 @@ namespace ts { export function declarationNameToString(name: DeclarationName) { return getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name); } + + export function getNameFromIndexInfo(info: IndexInfo) { + return info.declaration ? declarationNameToString(info.declaration.parameters[0].name) : undefined; + } export function getTextOfPropertyName(name: PropertyName): string { switch (name.kind) { diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts index 220cea55d6..33b4a10dff 100644 --- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts +++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts @@ -53,18 +53,7 @@ namespace ts.codefix { if (!indexInfoOfKind) { return undefined; } - const typeNode = checker.createTypeNode(indexInfoOfKind.type); - const newIndexSignatureDeclaration = createIndexSignatureDeclaration( - [createParameter( - /*decorators*/undefined - , /*modifiers*/ undefined - , /*dotDotDotToken*/ undefined - , getNameFromIndexInfo(indexInfoOfKind) - , /*questionToken*/ undefined - , kind === IndexKind.String ? createKeywordTypeNode(SyntaxKind.StringKeyword) : createKeywordTypeNode(SyntaxKind.NumberKeyword))] - , typeNode - , /*decorators*/undefined - , /*modifiers*/ undefined); + const newIndexSignatureDeclaration = checker.createIndexSignatureFromIndexInfo(indexInfoOfKind, kind); newNodes.push(newIndexSignatureDeclaration); } diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 2db14f81df..c51687962b 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -52,10 +52,10 @@ namespace ts.codefix { const declaration = declarations[0] as Declaration; // TODO: get name as identifier or computer property name, etc. - const name = declaration.name ? declaration.name.getText() : undefined; + const name = declaration.name ? getSynthesizedDeepClone(declaration.name) as PropertyName : undefined; const visibilityModifier = createVisibilityModifier(getModifierFlags(declaration)); const modifiers = visibilityModifier ? [visibilityModifier] : undefined; - const type = checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration); + const type = checker.getWidenedType(checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration)); switch (declaration.kind) { case SyntaxKind.GetAccessor: @@ -94,7 +94,7 @@ namespace ts.codefix { const newTypeParameters = signature.typeParameters && signature.typeParameters.map(checker.createTypeParameterDeclarationFromType); const newParameterNodes = signature.getParameters().map(symbol => createParameterDeclarationFromSymbol(symbol, enclosingDeclaration, checker)); - const returnType = checker.createTypeNode(checker.getReturnTypeOfSignature(signature)); + const returnType = checker.createTypeNode(checker.getWidenedType(checker.getReturnTypeOfSignature(signature))); return createStubbedMethod(modifiers, name, newTypeParameters, newParameterNodes, returnType); } @@ -121,7 +121,7 @@ namespace ts.codefix { let signature = checker.getSignatureFromDeclaration(declarations[declarations.length - 1] as SignatureDeclaration); const newTypeParameters = signature.typeParameters && signature.typeParameters.map(checker.createTypeParameterDeclarationFromType); const newParameterNodes = signature.getParameters().map(symbol => createParameterDeclarationFromSymbol(symbol, enclosingDeclaration, checker)); - const returnType = checker.createTypeNode(signature.resolvedReturnType); + const returnType = checker.createTypeNode(checker.getWidenedType(checker.getReturnTypeOfSignature(signature))); signatureDeclarations.push(createStubbedMethod(modifiers, name, newTypeParameters, newParameterNodes, returnType)); } else { @@ -135,7 +135,7 @@ namespace ts.codefix { } } - function createMethodImplementingSignatures(signatures: Signature[], name: string, modifiers: Modifier[] | undefined): MethodDeclaration { + function createMethodImplementingSignatures(signatures: Signature[], name: PropertyName, modifiers: Modifier[] | undefined): MethodDeclaration { Debug.assert(signatures && signatures.length > 0); let maxNonRestArgs = -1; @@ -189,7 +189,7 @@ namespace ts.codefix { , /*returnType*/ undefined); } - export function createStubbedMethod(modifiers: Modifier[], name: string, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], returnType: TypeNode | undefined) { + export function createStubbedMethod(modifiers: Modifier[], name: PropertyName, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], returnType: TypeNode | undefined) { return createMethod( /*decorators*/undefined , modifiers @@ -223,7 +223,7 @@ namespace ts.codefix { function createParameterDeclarationFromSymbol(parameterSymbol: Symbol, enclosingDeclaration: ClassLikeDeclaration, checker: TypeChecker) { const parameterDeclaration = parameterSymbol.getDeclarations()[0] as ParameterDeclaration; - const parameterType = checker.getTypeOfSymbolAtLocation(parameterSymbol, enclosingDeclaration); + const parameterType = checker.getWidenedType(checker.getTypeOfSymbolAtLocation(parameterSymbol, enclosingDeclaration)); const parameterTypeNode = checker.createTypeNode(parameterType); // TODO: deep cloning of decorators/any node. const parameterNode = createParameter( @@ -236,8 +236,4 @@ namespace ts.codefix { , /*initializer*/ undefined); return parameterNode; } - - export function getNameFromIndexInfo(info: IndexInfo) { - return info.declaration ? declarationNameToString(info.declaration.parameters[0].name) : "x" - } } \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixClassImplementInterface36.ts b/tests/cases/fourslash/codeFixClassImplementInterface36.ts deleted file mode 100644 index 5b0459ab66..0000000000 --- a/tests/cases/fourslash/codeFixClassImplementInterface36.ts +++ /dev/null @@ -1,18 +0,0 @@ -/// - -//// abstract class C1 { -//// -//// } -//// -//// abstract class C2 { -//// abstract f1(); -//// } -//// -//// interface I1 extends C1, C2 {} -//// -//// class C3 implements I1 {[| |]} - -verify.rangeAfterCodeFix(`f1(){ - throw new Error("Method not implemented."); -} -`); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixClassImplementInterface39.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceInNamespace.ts similarity index 100% rename from tests/cases/fourslash/codeFixClassImplementInterface39.ts rename to tests/cases/fourslash/codeFixClassImplementInterfaceInNamespace.ts diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceInheritsAbstractMethod.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceInheritsAbstractMethod.ts new file mode 100644 index 0000000000..b49d42dab5 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceInheritsAbstractMethod.ts @@ -0,0 +1,18 @@ +/// + +// abstract class C1 { +// +// } +// +// abstract class C2 { +// abstract f1(); +// } +// +// interface I1 extends C1, C2 {} +// +// class C3 implements I1 {[| |]} + +verify.rangeAfterCodeFix(`f1(){ + throw new Error("Method not implemented."); +} +`); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplements1.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplements1.ts index 5043a4d9c2..13d58d0ad6 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplements1.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplements1.ts @@ -7,8 +7,8 @@ //// y: number; //// } //// -//// class C implements I1,I2 {[| |] -//// y: number; +//// class C implements I1,I2 {[| +//// |]y: number; //// } verify.rangeAfterCodeFix(` diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplements2.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplements2.ts index ead2375168..e5100b88f6 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplements2.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplements2.ts @@ -7,9 +7,9 @@ //// y: number; //// } //// -//// class C implements I1,I2 {[| |] -//// x: number; -//// |]} +//// class C implements I1,I2 {[| +//// |]x: number; +//// } verify.rangeAfterCodeFix(` y: number; From 92b3e17bc0db3daac25f29a7219de527f8c2b591 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Tue, 14 Mar 2017 15:26:30 -0700 Subject: [PATCH 069/164] Fix deep clone --- src/compiler/factory.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 077bc34986..bd46e20878 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -68,11 +68,18 @@ namespace ts { } /* @internal */ + /** + * Note this implementation is inefficient in that all nodes except leaves are cloned twice, + * First by the explicit call below and then again as part of updateNode. + * We need to clone before visiting the children because otherwise updateNode + * will overwrite the synthesized span with the original node's span. + */ export function getSynthesizedDeepClone(node: T | undefined): T { if (node === undefined) { return undefined; } - return getSynthesizedClone(visitEachChild(node, getSynthesizedClone, nullTransformationContext)); + const clone = getSynthesizedClone(node); + return visitEachChild(clone, getSynthesizedDeepClone, nullTransformationContext); } // Literals From d4bb267ee3618f03fb64c515cfa2a7a02261baac Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Tue, 14 Mar 2017 16:13:33 -0700 Subject: [PATCH 070/164] add insertNodeInListAfter functionality --- src/harness/unittests/textChanges.ts | 172 +++++++++++-- .../fixClassSuperMustPrecedeThisAccess.ts | 2 +- .../fixConstructorForDerivedNeedSuperCall.ts | 2 +- src/services/codefixes/importFixes.ts | 103 +++----- .../codefixes/unusedIdentifierFixes.ts | 2 +- src/services/formatting/formattingScanner.ts | 4 +- src/services/textChanges.ts | 242 +++++++++++++++--- .../textChanges/insertNodeInListAfter1.js | 6 + .../textChanges/insertNodeInListAfter10.js | 10 + .../textChanges/insertNodeInListAfter11.js | 11 + .../textChanges/insertNodeInListAfter12.js | 10 + .../textChanges/insertNodeInListAfter13.js | 11 + .../textChanges/insertNodeInListAfter14.js | 13 + .../textChanges/insertNodeInListAfter15.js | 13 + .../textChanges/insertNodeInListAfter16.js | 13 + .../textChanges/insertNodeInListAfter17.js | 13 + .../textChanges/insertNodeInListAfter18.js | 10 + .../textChanges/insertNodeInListAfter2.js | 6 + .../textChanges/insertNodeInListAfter3.js | 6 + .../textChanges/insertNodeInListAfter4.js | 6 + .../textChanges/insertNodeInListAfter5.js | 6 + .../textChanges/insertNodeInListAfter6.js | 9 + .../textChanges/insertNodeInListAfter7.js | 9 + .../textChanges/insertNodeInListAfter8.js | 9 + .../textChanges/insertNodeInListAfter9.js | 9 + .../importNameCodeFixExistingImport10.ts | 2 +- .../importNameCodeFixExistingImport11.ts | 3 +- .../importNameCodeFixExistingImport9.ts | 3 +- 28 files changed, 580 insertions(+), 125 deletions(-) create mode 100644 tests/baselines/reference/textChanges/insertNodeInListAfter1.js create mode 100644 tests/baselines/reference/textChanges/insertNodeInListAfter10.js create mode 100644 tests/baselines/reference/textChanges/insertNodeInListAfter11.js create mode 100644 tests/baselines/reference/textChanges/insertNodeInListAfter12.js create mode 100644 tests/baselines/reference/textChanges/insertNodeInListAfter13.js create mode 100644 tests/baselines/reference/textChanges/insertNodeInListAfter14.js create mode 100644 tests/baselines/reference/textChanges/insertNodeInListAfter15.js create mode 100644 tests/baselines/reference/textChanges/insertNodeInListAfter16.js create mode 100644 tests/baselines/reference/textChanges/insertNodeInListAfter17.js create mode 100644 tests/baselines/reference/textChanges/insertNodeInListAfter18.js create mode 100644 tests/baselines/reference/textChanges/insertNodeInListAfter2.js create mode 100644 tests/baselines/reference/textChanges/insertNodeInListAfter3.js create mode 100644 tests/baselines/reference/textChanges/insertNodeInListAfter4.js create mode 100644 tests/baselines/reference/textChanges/insertNodeInListAfter5.js create mode 100644 tests/baselines/reference/textChanges/insertNodeInListAfter6.js create mode 100644 tests/baselines/reference/textChanges/insertNodeInListAfter7.js create mode 100644 tests/baselines/reference/textChanges/insertNodeInListAfter8.js create mode 100644 tests/baselines/reference/textChanges/insertNodeInListAfter9.js diff --git a/src/harness/unittests/textChanges.ts b/src/harness/unittests/textChanges.ts index b8c9a8e873..61f6d738e5 100644 --- a/src/harness/unittests/textChanges.ts +++ b/src/harness/unittests/textChanges.ts @@ -130,7 +130,7 @@ namespace M /*body */ createBlock(statements) ); - changeTracker.insertNodeBefore(sourceFile, /*before*/findChild("M2", sourceFile), newFunction, { insertTrailingNewLine: true }); + changeTracker.insertNodeBefore(sourceFile, /*before*/findChild("M2", sourceFile), newFunction, { suffix: newLineCharacter }); // replace statements with return statement const newStatement = createReturn( @@ -139,7 +139,7 @@ namespace M /*typeArguments*/ undefined, /*argumentsArray*/ emptyArray )); - changeTracker.replaceNodeRange(sourceFile, statements[0], lastOrUndefined(statements), newStatement, { insertTrailingNewLine: true }); + changeTracker.replaceNodeRange(sourceFile, statements[0], lastOrUndefined(statements), newStatement, { suffix: newLineCharacter }); }); } { @@ -255,10 +255,10 @@ var z = 3; // comment 5 // comment 6 var a = 4; // comment 7`; runSingleFileTest("replaceRange", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.replaceRange(sourceFile, { pos: text.indexOf("var y"), end: text.indexOf("var a") }, createTestClass(), { insertTrailingNewLine: true }); + changeTracker.replaceRange(sourceFile, { pos: text.indexOf("var y"), end: text.indexOf("var a") }, createTestClass(), { suffix: newLineCharacter }); }); runSingleFileTest("replaceRangeWithForcedIndentation", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.replaceRange(sourceFile, { pos: text.indexOf("var y"), end: text.indexOf("var a") }, createTestClass(), { insertTrailingNewLine: true, indentation: 8, delta: 0 }); + changeTracker.replaceRange(sourceFile, { pos: text.indexOf("var y"), end: text.indexOf("var a") }, createTestClass(), { suffix: newLineCharacter, indentation: 8, delta: 0 }); }); runSingleFileTest("replaceRangeNoLineBreakBefore", setNewLineForOpenBraceInFunctions, `const x = 1, y = "2";`, /*validateNodes*/ false, (sourceFile, changeTracker) => { @@ -287,13 +287,13 @@ var z = 3; // comment 5 // comment 6 var a = 4; // comment 7`; runSingleFileTest("replaceNode1", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { insertTrailingNewLine: true }); + changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { suffix: newLineCharacter }); }); runSingleFileTest("replaceNode2", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, insertTrailingNewLine: true, insertLeadingNewLine: true }); + changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, suffix: newLineCharacter, prefix: newLineCharacter }); }); runSingleFileTest("replaceNode3", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { useNonAdjustedEndPosition: true, insertTrailingNewLine: true }); + changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { useNonAdjustedEndPosition: true, suffix: newLineCharacter }); }); runSingleFileTest("replaceNode4", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: true }); @@ -312,13 +312,13 @@ var z = 3; // comment 5 // comment 6 var a = 4; // comment 7`; runSingleFileTest("replaceNodeRange1", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { insertTrailingNewLine: true }); + changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { suffix: newLineCharacter }); }); runSingleFileTest("replaceNodeRange2", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, insertTrailingNewLine: true, insertLeadingNewLine: true }); + changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, suffix: newLineCharacter, prefix: newLineCharacter }); }); runSingleFileTest("replaceNodeRange3", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { useNonAdjustedEndPosition: true, insertTrailingNewLine: true }); + changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { useNonAdjustedEndPosition: true, suffix: newLineCharacter }); }); runSingleFileTest("replaceNodeRange4", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: true }); @@ -334,7 +334,7 @@ var z = 3; // comment 5 // comment 6 var a = 4; // comment 7`; runSingleFileTest("insertNodeAt1", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.insertNodeAt(sourceFile, text.indexOf("var y"), createTestClass(), { insertTrailingNewLine: true }); + changeTracker.insertNodeAt(sourceFile, text.indexOf("var y"), createTestClass(), { suffix: newLineCharacter }); }); runSingleFileTest("insertNodeAt2", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { changeTracker.insertNodeAt(sourceFile, text.indexOf("; // comment 4"), createTestVariableDeclaration("z1")); @@ -352,16 +352,16 @@ namespace M { var a = 4; // comment 7 }`; runSingleFileTest("insertNodeBefore1", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.insertNodeBefore(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { insertTrailingNewLine: true }); + changeTracker.insertNodeBefore(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { suffix: newLineCharacter }); }); runSingleFileTest("insertNodeBefore2", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.insertNodeBefore(sourceFile, findChild("M", sourceFile), createTestClass(), { insertTrailingNewLine: true }); + changeTracker.insertNodeBefore(sourceFile, findChild("M", sourceFile), createTestClass(), { suffix: newLineCharacter }); }); runSingleFileTest("insertNodeAfter1", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.insertNodeAfter(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { insertTrailingNewLine: true }); + changeTracker.insertNodeAfter(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { suffix: newLineCharacter }); }); runSingleFileTest("insertNodeAfter2", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => { - changeTracker.insertNodeAfter(sourceFile, findChild("M", sourceFile), createTestClass(), { insertLeadingNewLine: true }); + changeTracker.insertNodeAfter(sourceFile, findChild("M", sourceFile), createTestClass(), { prefix: newLineCharacter }); }); } { @@ -385,7 +385,7 @@ class A { } `; runSingleFileTest("insertNodeAfter3", noop, text1, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeAfter(sourceFile, findOpenBraceForConstructor(sourceFile), createTestSuperCall(), { insertTrailingNewLine: true }); + changeTracker.insertNodeAfter(sourceFile, findOpenBraceForConstructor(sourceFile), createTestSuperCall(), { suffix: newLineCharacter }); }); const text2 = ` class A { @@ -395,7 +395,7 @@ class A { } `; runSingleFileTest("insertNodeAfter4", noop, text2, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeAfter(sourceFile, findVariableStatementContaining("x", sourceFile), createTestSuperCall(), { insertTrailingNewLine: true }); + changeTracker.insertNodeAfter(sourceFile, findVariableStatementContaining("x", sourceFile), createTestSuperCall(), { suffix: newLineCharacter }); }); const text3 = ` class A { @@ -405,7 +405,7 @@ class A { } `; runSingleFileTest("insertNodeAfter3-block with newline", noop, text3, /*validateNodes*/ false, (sourceFile, changeTracker) => { - changeTracker.insertNodeAfter(sourceFile, findOpenBraceForConstructor(sourceFile), createTestSuperCall(), { insertTrailingNewLine: true }); + changeTracker.insertNodeAfter(sourceFile, findOpenBraceForConstructor(sourceFile), createTestSuperCall(), { suffix: newLineCharacter }); }); } { @@ -498,7 +498,7 @@ function foo(a: number,b: string,c = true) { changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile)); }); } -{ + { const text = ` function foo( a: number, @@ -516,5 +516,139 @@ function foo( changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile)); }); } + { + const text = ` +const x = 1, y = 2;`; + runSingleFileTest("insertNodeInListAfter1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1))); + }); + runSingleFileTest("insertNodeInListAfter2", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1))); + }); + } + { + const text = ` +const /*x*/ x = 1, /*y*/ y = 2;`; + runSingleFileTest("insertNodeInListAfter3", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1))); + }); + runSingleFileTest("insertNodeInListAfter4", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1))); + }); + } + { + const text = ` +const x = 1;`; + runSingleFileTest("insertNodeInListAfter5", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1))); + }); + } + { + const text = ` +const x = 1, + y = 2;`; + runSingleFileTest("insertNodeInListAfter6", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1))); + }); + runSingleFileTest("insertNodeInListAfter7", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1))); + }); + } + { + const text = ` +const /*x*/ x = 1, + /*y*/ y = 2;`; + runSingleFileTest("insertNodeInListAfter8", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1))); + }); + runSingleFileTest("insertNodeInListAfter9", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1))); + }); + } + { + const text = ` +import { + x +} from "bar"`; + runSingleFileTest("insertNodeInListAfter10", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(createIdentifier("b"), createIdentifier("a"))); + }) + } + { + const text = ` +import { + x // this is x +} from "bar"`; + runSingleFileTest("insertNodeInListAfter11", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(createIdentifier("b"), createIdentifier("a"))); + }) + } + { + const text = ` +import { + x +} from "bar"`; + runSingleFileTest("insertNodeInListAfter12", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(undefined, createIdentifier("a"))); + }) + } + { + const text = ` +import { + x // this is x +} from "bar"`; + runSingleFileTest("insertNodeInListAfter13", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(undefined, createIdentifier("a"))); + }) + } + { + const text = ` +import { + x0, + x +} from "bar"`; + runSingleFileTest("insertNodeInListAfter14", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(createIdentifier("b"), createIdentifier("a"))); + }) + } + { + const text = ` +import { + x0, + x // this is x +} from "bar"`; + runSingleFileTest("insertNodeInListAfter15", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(createIdentifier("b"), createIdentifier("a"))); + }) + } + { + const text = ` +import { + x0, + x +} from "bar"`; + runSingleFileTest("insertNodeInListAfter16", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(undefined, createIdentifier("a"))); + }) + } + { + const text = ` +import { + x0, + x // this is x +} from "bar"`; + runSingleFileTest("insertNodeInListAfter17", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(undefined, createIdentifier("a"))); + }) + } + { + const text = ` +import { + x0, x +} from "bar"`; + runSingleFileTest("insertNodeInListAfter18", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(undefined, createIdentifier("a"))); + }) + } }); } \ No newline at end of file diff --git a/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts b/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts index 207d039df8..6d7efb64c6 100644 --- a/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts +++ b/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts @@ -27,7 +27,7 @@ namespace ts.codefix { } } const changeTracker = textChanges.ChangeTracker.fromCodeFixContext(context); - changeTracker.insertNodeAfter(sourceFile, getOpenBrace(constructor, sourceFile), superCall, { insertTrailingNewLine: true }); + changeTracker.insertNodeAfter(sourceFile, getOpenBrace(constructor, sourceFile), superCall, { suffix: context.newLineCharacter }); changeTracker.deleteNode(sourceFile, superCall); return [{ diff --git a/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts b/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts index 27b655f19c..822c34842f 100644 --- a/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts +++ b/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts @@ -12,7 +12,7 @@ namespace ts.codefix { const changeTracker = textChanges.ChangeTracker.fromCodeFixContext(context); const superCall = createStatement(createCall(createSuper(), /*typeArguments*/ undefined, /*argumentsArray*/ emptyArray)); - changeTracker.insertNodeAfter(sourceFile, getOpenBrace(token.parent, sourceFile), superCall, { insertTrailingNewLine: true }); + changeTracker.insertNodeAfter(sourceFile, getOpenBrace(token.parent, sourceFile), superCall, { suffix: context.newLineCharacter }); return [{ description: getLocaleSpecificMessage(Diagnostics.Add_missing_super_call), diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 3e07efbc3d..743c13ccf3 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -130,7 +130,7 @@ namespace ts.codefix { // this is a module id -> module import declaration map const cachedImportDeclarations: (ImportDeclaration | ImportEqualsDeclaration)[][] = []; - let cachedNewImportInsertPosition: number; + let lastImportDeclaration: Node; const currentTokenMeaning = getMeaningFromLocation(token); if (context.errorCode === Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code) { @@ -138,14 +138,14 @@ namespace ts.codefix { return getCodeActionForImport(symbol, /*isDefault*/ false, /*isNamespaceImport*/ true); } - const allPotentialModules = checker.getAmbientModules(); + const candidateModules = checker.getAmbientModules(); for (const otherSourceFile of allSourceFiles) { if (otherSourceFile !== sourceFile && isExternalOrCommonJsModule(otherSourceFile)) { - allPotentialModules.push(otherSourceFile.symbol); + candidateModules.push(otherSourceFile.symbol); } } - for (const moduleSymbol of allPotentialModules) { + for (const moduleSymbol of candidateModules) { context.cancellationToken.throwIfCancellationRequested(); // check the default export @@ -277,14 +277,12 @@ namespace ts.codefix { * If the existing import declaration already has a named import list, just * insert the identifier into that list. */ - const textChange = getTextChangeForImportClause(namedImportDeclaration.importClause); + const fileTextChanges = getTextChangeForImportClause(namedImportDeclaration.importClause); const moduleSpecifierWithoutQuotes = stripQuotes(namedImportDeclaration.moduleSpecifier.getText()); actions.push(createCodeAction( Diagnostics.Add_0_to_existing_import_declaration_from_1, [name, moduleSpecifierWithoutQuotes], - textChange.newText, - textChange.span, - sourceFile.fileName, + fileTextChanges, "InsertingIntoExistingImport", moduleSpecifierWithoutQuotes )); @@ -302,49 +300,31 @@ namespace ts.codefix { return declaration.moduleReference.getText(); } - function getTextChangeForImportClause(importClause: ImportClause): TextChange { - const newImportText = isDefault ? `default as ${name}` : name; + function getTextChangeForImportClause(importClause: ImportClause): FileTextChanges[] { + //const newImportText = isDefault ? `default as ${name}` : name; const importList = importClause.namedBindings; + const newImportSpecifier = createImportSpecifier(/*propertyName*/ undefined, createIdentifier(name)); // case 1: // original text: import default from "module" // change to: import default, { name } from "module" - if (!importList && importClause.name) { - const start = importClause.name.getEnd(); - return { - newText: `, { ${newImportText} }`, - span: { start, length: 0 } - }; - } - // case 2: // original text: import {} from "module" // change to: import { name } from "module" - if (importList.elements.length === 0) { - const start = importList.getStart(); - return { - newText: `{ ${newImportText} }`, - span: { start, length: importList.getEnd() - start } - }; + if (!importList || importList.elements.length === 0) { + const newImportClause = createImportClause(importClause.name, createNamedImports([newImportSpecifier])); + return createChangeTracker().replaceNode(sourceFile, importClause, newImportClause).getChanges(); } - // case 3: - // original text: import { foo, bar } from "module" - // change to: import { foo, bar, name } from "module" - const insertPoint = importList.elements[importList.elements.length - 1].getEnd(); /** * If the import list has one import per line, preserve that. Otherwise, insert on same line as last element * import { * foo * } from "./module"; */ - const startLine = getLineOfLocalPosition(sourceFile, importList.getStart()); - const endLine = getLineOfLocalPosition(sourceFile, importList.getEnd()); - const oneImportPerLine = endLine - startLine > importList.elements.length; - - return { - newText: `,${oneImportPerLine ? context.newLineCharacter : " "}${newImportText}`, - span: { start: insertPoint, length: 0 } - }; + return createChangeTracker().insertNodeInListAfter( + sourceFile, + importList.elements[importList.elements.length - 1], + newImportSpecifier).getChanges(); } function getCodeActionForNamespaceImport(declaration: ImportDeclaration | ImportEqualsDeclaration): ImportCodeAction { @@ -370,48 +350,47 @@ namespace ts.codefix { return createCodeAction( Diagnostics.Change_0_to_1, [name, `${namespacePrefix}.${name}`], - `${namespacePrefix}.`, - { start: token.getStart(), length: 0 }, - sourceFile.fileName, + createChangeTracker().replaceNode(sourceFile, token, createPropertyAccess(createIdentifier(namespacePrefix), name)).getChanges(), "CodeChange" ); } } function getCodeActionForNewImport(moduleSpecifier?: string): ImportCodeAction { - if (!cachedNewImportInsertPosition) { + if (!lastImportDeclaration) { // insert after any existing imports - let lastModuleSpecifierEnd = -1; - for (const moduleSpecifier of sourceFile.imports) { - const end = moduleSpecifier.getEnd(); - if (!lastModuleSpecifierEnd || end > lastModuleSpecifierEnd) { - lastModuleSpecifierEnd = end; + for (let i = sourceFile.statements.length - 1; i >= 0; i--) { + const statement = sourceFile.statements[i]; + if (statement.kind === SyntaxKind.ImportEqualsDeclaration || statement.kind === SyntaxKind.ImportDeclaration) { + lastImportDeclaration = statement; + break; } } - cachedNewImportInsertPosition = lastModuleSpecifierEnd > 0 ? sourceFile.getLineEndOfPosition(lastModuleSpecifierEnd) : sourceFile.getStart(); } const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames); const moduleSpecifierWithoutQuotes = stripQuotes(moduleSpecifier || getModuleSpecifierForNewImport()); - const importStatementText = isDefault - ? `import ${name} from "${moduleSpecifierWithoutQuotes}"` + const changeTracker = createChangeTracker(); + const importClause = isDefault + ? createImportClause(createIdentifier(name), /*namedBindings*/ undefined) : isNamespaceImport - ? `import * as ${name} from "${moduleSpecifierWithoutQuotes}"` - : `import { ${name} } from "${moduleSpecifierWithoutQuotes}"`; + ? createImportClause(/*name*/ undefined, createNamespaceImport(createIdentifier(name))) + : createImportClause(/*name*/ undefined, createNamedImports([createImportSpecifier(/*propertyName*/ undefined, createIdentifier(name))])); + const importDecl = createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, importClause, createLiteral(moduleSpecifierWithoutQuotes)); + if (!lastImportDeclaration) { + changeTracker.insertNodeAt(sourceFile, sourceFile.getStart(), importDecl, { suffix: `${context.newLineCharacter}${context.newLineCharacter}` }); + } + else { + changeTracker.insertNodeAfter(sourceFile, lastImportDeclaration, importDecl, { suffix: context.newLineCharacter }); + } // if this file doesn't have any import statements, insert an import statement and then insert a new line // between the only import statement and user code. Otherwise just insert the statement because chances // are there are already a new line seperating code and import statements. - const newText = cachedNewImportInsertPosition === sourceFile.getStart() - ? `${importStatementText};${context.newLineCharacter}${context.newLineCharacter}` - : `${context.newLineCharacter}${importStatementText};`; - return createCodeAction( Diagnostics.Import_0_from_1, [name, `"${moduleSpecifierWithoutQuotes}"`], - newText, - { start: cachedNewImportInsertPosition, length: 0 }, - sourceFile.fileName, + changeTracker.getChanges(), "NewImport", moduleSpecifierWithoutQuotes ); @@ -576,17 +555,19 @@ namespace ts.codefix { } + function createChangeTracker() { + return textChanges.ChangeTracker.fromCodeFixContext(context);; + } + function createCodeAction( description: DiagnosticMessage, diagnosticArgs: string[], - newText: string, - span: TextSpan, - fileName: string, + changes: FileTextChanges[], kind: ImportCodeActionKind, moduleSpecifier?: string): ImportCodeAction { return { description: formatMessage.apply(undefined, [undefined, description].concat(diagnosticArgs)), - changes: [{ fileName, textChanges: [{ newText, span }] }], + changes, kind, moduleSpecifier }; diff --git a/src/services/codefixes/unusedIdentifierFixes.ts b/src/services/codefixes/unusedIdentifierFixes.ts index 1773427fce..f77f9723d0 100644 --- a/src/services/codefixes/unusedIdentifierFixes.ts +++ b/src/services/codefixes/unusedIdentifierFixes.ts @@ -132,7 +132,7 @@ namespace ts.codefix { else { const previousToken = getTokenAtPosition(sourceFile, namespaceImport.pos - 1); if (previousToken && previousToken.kind === SyntaxKind.CommaToken) { - const startPosition = textChanges.getAdjustedStartPosition(sourceFile, previousToken, {}, /*forDeleteOperation*/ true); + const startPosition = textChanges.getAdjustedStartPosition(sourceFile, previousToken, {}, textChanges.Position.FullStart); return deleteRange({ pos: startPosition, end: namespaceImport.end }); } return deleteRange(namespaceImport); diff --git a/src/services/formatting/formattingScanner.ts b/src/services/formatting/formattingScanner.ts index 981ae09b2b..20d190de2f 100644 --- a/src/services/formatting/formattingScanner.ts +++ b/src/services/formatting/formattingScanner.ts @@ -276,8 +276,8 @@ namespace ts.formatting { function isOnToken(): boolean { Debug.assert(scanner !== undefined); - const current = (lastTokenInfo && lastTokenInfo.token.kind) || scanner.getToken(); - const startPos = (lastTokenInfo && lastTokenInfo.token.pos) || scanner.getStartPos(); + const current = lastTokenInfo ? lastTokenInfo.token.kind : scanner.getToken(); + const startPos = lastTokenInfo ? lastTokenInfo.token.pos : scanner.getStartPos(); return startPos < endPos && current !== SyntaxKind.EndOfFileToken && !isTrivia(current); } diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 5b9f0f5ef4..174f2969a0 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -28,6 +28,28 @@ namespace ts.textChanges { useNonAdjustedEndPosition?: boolean; } + export enum Position { + FullStart, + Start + } + + function skipWhitespacesAndLineBreaks(text: string, start: number) { + return skipTrivia(text, start, /*stopAfterLineBreak*/ false, /*stopAtComments*/ true); + } + + function hasCommentsBeforeLineBreak(text: string, start: number) { + let i = start; + while (i < text.length) { + const ch = text.charCodeAt(i); + if (isWhiteSpaceSingleLine(ch)) { + i++; + continue; + } + return ch === CharacterCodes.slash; + } + return false; + } + /** * Usually node.pos points to a position immediately after the previous token. * If this position is used as a beginning of the span to remove - it might lead to removing the trailing trivia of the previous node, i.e: @@ -44,13 +66,13 @@ namespace ts.textChanges { export interface InsertNodeOptions { /** - * Set this value to true to make sure that node text of newly inserted node ends with new line + * Text to be inserted before the new node */ - insertTrailingNewLine?: boolean; + prefix?: string; /** - * Set this value to true to make sure that node text of newly inserted node starts with new line + * Text to be inserted after the new node */ - insertLeadingNewLine?: boolean; + suffix?: string; /** * Text of inserted node will be formatted with this indentation, otherwise indentation will be inferred from the old node */ @@ -66,12 +88,16 @@ namespace ts.textChanges { interface Change { readonly sourceFile: SourceFile; readonly range: TextRange; - readonly oldNode?: Node; + readonly useIndentationFromFile?: boolean; readonly node?: Node; readonly options?: ChangeNodeOptions; } - export function getAdjustedStartPosition(sourceFile: SourceFile, node: Node, options: ConfigurableStart, forDeleteOperation: boolean) { + export function getSeparatorCharacter(separator: Token) { + return tokenToString(separator.kind); + } + + export function getAdjustedStartPosition(sourceFile: SourceFile, node: Node, options: ConfigurableStart, position: Position) { if (options.useNonAdjustedStartPosition) { return node.getFullStart(); } @@ -90,12 +116,12 @@ namespace ts.textChanges { // fullstart // when b is replaced - we usually want to keep the leading trvia // when b is deleted - we delete it - return forDeleteOperation ? fullStart : start; + return position === Position.Start ? start : fullStart; } // get start position of the line following the line that contains fullstart position let adjustedStartPosition = getStartPositionOfLine(getLineOfLocalPosition(sourceFile, fullStartLine) + 1, sourceFile); // skip whitespaces/newlines - adjustedStartPosition = skipTrivia(sourceFile.text, adjustedStartPosition, /*stopAfterLineBreak*/ false, /*stopAtComments*/ true); + adjustedStartPosition = skipWhitespacesAndLineBreaks(sourceFile.text, adjustedStartPosition); return getStartPositionOfLine(getLineOfLocalPosition(sourceFile, adjustedStartPosition), sourceFile); } @@ -112,8 +138,19 @@ namespace ts.textChanges { : end; } - function isSeparator(node: Node, separator: Node): boolean { - return node.parent && (separator.kind === SyntaxKind.CommaToken || (separator.kind === SyntaxKind.SemicolonToken && node.parent.kind === SyntaxKind.ObjectLiteralExpression)); + /** + * Checks if 'candidate' argument is a legal separator in the list that contains 'node' as an element + */ + function isSeparator(node: Node, candidate: Node): candidate is Token { + return candidate && node.parent && (candidate.kind === SyntaxKind.CommaToken || (candidate.kind === SyntaxKind.SemicolonToken && node.parent.kind === SyntaxKind.ObjectLiteralExpression)); + } + + function spaces(count: number) { + let s = ""; + for (let i = 0; i < count; i++) { + s += " "; + } + return s; } export class ChangeTracker { @@ -132,7 +169,7 @@ namespace ts.textChanges { } public deleteNode(sourceFile: SourceFile, node: Node, options: ConfigurableStartEnd = {}) { - const startPosition = getAdjustedStartPosition(sourceFile, node, options, /*forDeleteOperation*/ true); + const startPosition = getAdjustedStartPosition(sourceFile, node, options, Position.FullStart); const endPosition = getAdjustedEndPosition(sourceFile, node, options); this.changes.push({ sourceFile, options, range: { pos: startPosition, end: endPosition } }); return this; @@ -144,7 +181,7 @@ namespace ts.textChanges { } public deleteNodeRange(sourceFile: SourceFile, startNode: Node, endNode: Node, options: ConfigurableStartEnd = {}) { - const startPosition = getAdjustedStartPosition(sourceFile, startNode, options, /*forDeleteOperation*/ true); + const startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.FullStart); const endPosition = getAdjustedEndPosition(sourceFile, endNode, options); this.changes.push({ sourceFile, options, range: { pos: startPosition, end: endPosition } }); return this; @@ -153,7 +190,7 @@ namespace ts.textChanges { public deleteNodeInList(sourceFile: SourceFile, node: Node) { const containingList = formatting.SmartIndenter.getContainingList(node, sourceFile); if (!containingList) { - return; + return this; } const index = containingList.indexOf(node); if (index < 0) { @@ -167,10 +204,10 @@ namespace ts.textChanges { const nextToken = getTokenAtPosition(sourceFile, node.end); if (nextToken && isSeparator(node, nextToken)) { // find first non-whitespace position in the leading trivia of the node - const startPosition = skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, node, {}, /*forDeleteOperation*/ true), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true); + const startPosition = skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, node, {}, Position.FullStart), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true); const nextElement = containingList[index + 1]; /// find first non-whitespace position in the leading trivia of the next node - const endPosition = skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, nextElement, {}, /*forDeleteOperation*/ true), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true); + const endPosition = skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, nextElement, {}, Position.FullStart), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true); // shift next node so its first non-whitespace position will be moved to the first non-whitespace position of the deleted node this.deleteRange(sourceFile, { pos: startPosition, end: endPosition }); } @@ -190,16 +227,16 @@ namespace ts.textChanges { } public replaceNode(sourceFile: SourceFile, oldNode: Node, newNode: Node, options: ChangeNodeOptions = {}) { - const startPosition = getAdjustedStartPosition(sourceFile, oldNode, options, /*forDeleteOperation*/ false); + const startPosition = getAdjustedStartPosition(sourceFile, oldNode, options, Position.Start); const endPosition = getAdjustedEndPosition(sourceFile, oldNode, options); - this.changes.push({ sourceFile, options, oldNode, node: newNode, range: { pos: startPosition, end: endPosition } }); + this.changes.push({ sourceFile, options, useIndentationFromFile: true, node: newNode, range: { pos: startPosition, end: endPosition } }); return this; } public replaceNodeRange(sourceFile: SourceFile, startNode: Node, endNode: Node, newNode: Node, options: ChangeNodeOptions = {}) { - const startPosition = getAdjustedStartPosition(sourceFile, startNode, options, /*forDeleteOperation*/ false); + const startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.Start); const endPosition = getAdjustedEndPosition(sourceFile, endNode, options); - this.changes.push({ sourceFile, options, oldNode: startNode, node: newNode, range: { pos: startPosition, end: endPosition } }); + this.changes.push({ sourceFile, options, useIndentationFromFile: true, node: newNode, range: { pos: startPosition, end: endPosition } }); return this; } @@ -209,14 +246,149 @@ namespace ts.textChanges { } public insertNodeBefore(sourceFile: SourceFile, before: Node, newNode: Node, options: InsertNodeOptions & ConfigurableStart = {}) { - const startPosition = getAdjustedStartPosition(sourceFile, before, options, /*forDeleteOperation*/ false); - this.changes.push({ sourceFile, options, oldNode: before, node: newNode, range: { pos: startPosition, end: startPosition } }); + const startPosition = getAdjustedStartPosition(sourceFile, before, options, Position.Start); + this.changes.push({ sourceFile, options, useIndentationFromFile: true, node: newNode, range: { pos: startPosition, end: startPosition } }); return this; } public insertNodeAfter(sourceFile: SourceFile, after: Node, newNode: Node, options: InsertNodeOptions & ConfigurableEnd = {}) { const endPosition = getAdjustedEndPosition(sourceFile, after, options); - this.changes.push({ sourceFile, options, oldNode: after, node: newNode, range: { pos: endPosition, end: endPosition } }); + this.changes.push({ sourceFile, options, useIndentationFromFile: true, node: newNode, range: { pos: endPosition, end: endPosition } }); + return this; + } + + public insertNodeInListAfter(sourceFile: SourceFile, after: Node, newNode: Node) { + const containingList = formatting.SmartIndenter.getContainingList(after, sourceFile); + if (!containingList) { + return this; + } + const index = containingList.indexOf(after); + if (index < 0) { + return this; + } + const end = after.getEnd(); + if (index !== containingList.length - 1) { + // any element except the last one + // use next sibling as an anchor + const nextToken = getTokenAtPosition(sourceFile, after.end); + if (nextToken && isSeparator(after, nextToken)) { + // for list + // a, b, c + // create change for adding 'e' after 'a' as + // - find start of next element after a (it is b) + // - use this start as start and end position in final change + // - build text of change by formatting the text of node + separator + whitespace trivia of b + + // in multiline case it will work as + // a, + // b, + // c, + // result - '*' denotes leading trivia that will be inserted after new text (displayed as '#') + // a,* + //***insertedtext# + //###b, + // c, + // find line and character of the next element + const lineAndCharOfNextElement = getLineAndCharacterOfPosition(sourceFile, skipWhitespacesAndLineBreaks(sourceFile.text, containingList[index + 1].getFullStart())); + // find line and character of the token that precedes next element (usually it is separator) + const lineAndCharOfNextToken = getLineAndCharacterOfPosition(sourceFile, nextToken.end); + let prefix: string; + let startPos: number; + if (lineAndCharOfNextToken.line === lineAndCharOfNextElement.line) { + // next element is located on the same line with separator: + // a,$$$$b + // ^ ^ + // | |-next element + // |-separator + // where $$$ is some leading trivia + // for a newly inserted node we'll maintain the same relative position comparing to separator and replace leading trivia with spaces + // a, x,$$$$b + // ^ ^ ^ + // | | |-next element + // | |-new inserted node padded with spaces + // |-separator + startPos = nextToken.end; + prefix = spaces(lineAndCharOfNextElement.character - lineAndCharOfNextToken.character); + } + else { + // next element is located on different line that separator + // let insert position be the beginning of the line that contains next element + startPos = getStartPositionOfLine(lineAndCharOfNextElement.line, sourceFile); + } + + this.changes.push({ + sourceFile, + range: { pos: startPos, end: containingList[index + 1].getStart(sourceFile) }, + node: newNode, + useIndentationFromFile: true, + options: { + prefix, + // write separator and leading trivia of the next element as suffix + suffix: `${tokenToString(nextToken.kind)}${sourceFile.text.substring(nextToken.end, containingList[index + 1].getStart(sourceFile))}` + } + }); + } + } + else { + const afterStart = after.getStart(sourceFile); + const afterStartLinePosition = getLineStartPositionForPosition(afterStart, sourceFile); + + let separator: SyntaxKind.CommaToken | SyntaxKind.SemicolonToken; + let multilineList = false; + + // insert element after the last element in the list that has more than one item + // pick the element preceding the after element to: + // - pick the separator + // - determine if list is a multiline + if (containingList.length === 1) { + // if list has only one element then we'll format is as multiline if node has comment in trailing trivia, or as singleline otherwise + // i.e. var x = 1 // this is x + // | new element will be inserted at this position + separator = SyntaxKind.CommaToken; + } + else { + // element has more than one element, pick separator from the list + const tokenBeforeInsertPosition = findPrecedingToken(after.pos, sourceFile); + separator = isSeparator(after, tokenBeforeInsertPosition) ? tokenBeforeInsertPosition.kind : SyntaxKind.CommaToken; + // determine if list is multiline by checking lines of after element and element that precedes it. + const afterMinusOneStartLinePosition = getLineStartPositionForPosition(containingList[index - 1].getStart(sourceFile), sourceFile); + multilineList = afterMinusOneStartLinePosition !== afterStartLinePosition; + } + if (hasCommentsBeforeLineBreak(sourceFile.text, after.end)) { + // in this case we'll always treat containing list as multiline + multilineList = true; + } + if (multilineList) { + // insert separator immediately following the 'after' node to preserve comments in trailing trivia + this.changes.push({ + sourceFile, + range: { pos: end, end }, + node: createToken(separator), + options: {} + }); + // use the same indentation as 'after' item + const indentation = formatting.SmartIndenter.findFirstNonWhitespaceColumn(afterStartLinePosition, afterStart, sourceFile, this.rulesProvider.getFormatOptions()); + // insert element before the line break on the line that contains 'after' element + let insertPos = skipTrivia(sourceFile.text, end, /*stopAfterLineBreak*/ true, /*stopAtComments*/ false); + if (insertPos !== end && isLineBreak(sourceFile.text.charCodeAt(insertPos - 1))) { + insertPos-- + } + this.changes.push({ + sourceFile, + range: { pos: insertPos, end: insertPos }, + node: newNode, + options: { indentation, prefix: this.newLineCharacter } + }); + } + else { + this.changes.push({ + sourceFile, + range: { pos: end, end }, + node: newNode, + options: { prefix: `${tokenToString(separator)} ` } + }); + } + } return this; } @@ -267,13 +439,13 @@ namespace ts.textChanges { const formatOptions = this.rulesProvider.getFormatOptions(); const pos = change.range.pos; - const posStartsLine = getLineStartPositionForPosition(pos, sourceFile) === pos; + const posStartsLine = getLineStartPositionForPosition(pos, sourceFile) === pos; const initialIndentation = change.options.indentation !== undefined ? change.options.indentation - : change.oldNode - ? formatting.SmartIndenter.getIndentation(change.range.pos, sourceFile, formatOptions, posStartsLine || change.options.insertLeadingNewLine) + : change.useIndentationFromFile + ? formatting.SmartIndenter.getIndentation(change.range.pos, sourceFile, formatOptions, posStartsLine || (change.options.prefix == this.newLineCharacter)) : 0; const delta = change.options.delta !== undefined @@ -284,15 +456,9 @@ namespace ts.textChanges { let text = applyFormatting(nonFormattedText, sourceFile, initialIndentation, delta, this.rulesProvider); // strip initial indentation (spaces or tabs) if text will be inserted in the middle of the line - text = posStartsLine ? text : text.replace(/^\s+/, ""); - - if (options.insertLeadingNewLine) { - text = this.newLineCharacter + text; - } - if (options.insertTrailingNewLine) { - text = text + this.newLineCharacter; - } - return text; + // however keep indentation if it is was forced + text = posStartsLine || change.options.indentation !== undefined ? text : text.replace(/^\s+/, ""); + return (options.prefix || "") + text + (options.suffix || ""); } private static normalize(changes: Change[]) { @@ -397,9 +563,13 @@ namespace ts.textChanges { constructor(newLine: string) { this.writer = createTextWriter(newLine); this.onEmitNode = (hint, node, printCallback) => { - setPos(node, this.lastNonTriviaPosition); + if (node) { + setPos(node, this.lastNonTriviaPosition); + } printCallback(hint, node); - setEnd(node, this.lastNonTriviaPosition); + if (node) { + setEnd(node, this.lastNonTriviaPosition); + } }; this.onBeforeEmitNodeArray = nodes => { if (nodes) { diff --git a/tests/baselines/reference/textChanges/insertNodeInListAfter1.js b/tests/baselines/reference/textChanges/insertNodeInListAfter1.js new file mode 100644 index 0000000000..9b0ed7b819 --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeInListAfter1.js @@ -0,0 +1,6 @@ +===ORIGINAL=== + +const x = 1, y = 2; +===MODIFIED=== + +const x = 1, z = 1, y = 2; \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeInListAfter10.js b/tests/baselines/reference/textChanges/insertNodeInListAfter10.js new file mode 100644 index 0000000000..300230bf51 --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeInListAfter10.js @@ -0,0 +1,10 @@ +===ORIGINAL=== + +import { + x +} from "bar" +===MODIFIED=== + +import { + x, b as a +} from "bar" \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeInListAfter11.js b/tests/baselines/reference/textChanges/insertNodeInListAfter11.js new file mode 100644 index 0000000000..f0ba43a0f3 --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeInListAfter11.js @@ -0,0 +1,11 @@ +===ORIGINAL=== + +import { + x // this is x +} from "bar" +===MODIFIED=== + +import { + x, // this is x + b as a +} from "bar" \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeInListAfter12.js b/tests/baselines/reference/textChanges/insertNodeInListAfter12.js new file mode 100644 index 0000000000..79e7bb2c8b --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeInListAfter12.js @@ -0,0 +1,10 @@ +===ORIGINAL=== + +import { + x +} from "bar" +===MODIFIED=== + +import { + x, a +} from "bar" \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeInListAfter13.js b/tests/baselines/reference/textChanges/insertNodeInListAfter13.js new file mode 100644 index 0000000000..a7ac7179ab --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeInListAfter13.js @@ -0,0 +1,11 @@ +===ORIGINAL=== + +import { + x // this is x +} from "bar" +===MODIFIED=== + +import { + x, // this is x + a +} from "bar" \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeInListAfter14.js b/tests/baselines/reference/textChanges/insertNodeInListAfter14.js new file mode 100644 index 0000000000..e44a21723b --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeInListAfter14.js @@ -0,0 +1,13 @@ +===ORIGINAL=== + +import { + x0, + x +} from "bar" +===MODIFIED=== + +import { + x0, + x, + b as a +} from "bar" \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeInListAfter15.js b/tests/baselines/reference/textChanges/insertNodeInListAfter15.js new file mode 100644 index 0000000000..a80bdc2db5 --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeInListAfter15.js @@ -0,0 +1,13 @@ +===ORIGINAL=== + +import { + x0, + x // this is x +} from "bar" +===MODIFIED=== + +import { + x0, + x, // this is x + b as a +} from "bar" \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeInListAfter16.js b/tests/baselines/reference/textChanges/insertNodeInListAfter16.js new file mode 100644 index 0000000000..07f8db919f --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeInListAfter16.js @@ -0,0 +1,13 @@ +===ORIGINAL=== + +import { + x0, + x +} from "bar" +===MODIFIED=== + +import { + x0, + x, + a +} from "bar" \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeInListAfter17.js b/tests/baselines/reference/textChanges/insertNodeInListAfter17.js new file mode 100644 index 0000000000..990139408e --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeInListAfter17.js @@ -0,0 +1,13 @@ +===ORIGINAL=== + +import { + x0, + x // this is x +} from "bar" +===MODIFIED=== + +import { + x0, + x, // this is x + a +} from "bar" \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeInListAfter18.js b/tests/baselines/reference/textChanges/insertNodeInListAfter18.js new file mode 100644 index 0000000000..b25a3f4634 --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeInListAfter18.js @@ -0,0 +1,10 @@ +===ORIGINAL=== + +import { + x0, x +} from "bar" +===MODIFIED=== + +import { + x0, x, a +} from "bar" \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeInListAfter2.js b/tests/baselines/reference/textChanges/insertNodeInListAfter2.js new file mode 100644 index 0000000000..32e8e63c0f --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeInListAfter2.js @@ -0,0 +1,6 @@ +===ORIGINAL=== + +const x = 1, y = 2; +===MODIFIED=== + +const x = 1, y = 2, z = 1; \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeInListAfter3.js b/tests/baselines/reference/textChanges/insertNodeInListAfter3.js new file mode 100644 index 0000000000..70a0b0bddc --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeInListAfter3.js @@ -0,0 +1,6 @@ +===ORIGINAL=== + +const /*x*/ x = 1, /*y*/ y = 2; +===MODIFIED=== + +const /*x*/ x = 1, z = 1, /*y*/ y = 2; \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeInListAfter4.js b/tests/baselines/reference/textChanges/insertNodeInListAfter4.js new file mode 100644 index 0000000000..4a30acd707 --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeInListAfter4.js @@ -0,0 +1,6 @@ +===ORIGINAL=== + +const /*x*/ x = 1, /*y*/ y = 2; +===MODIFIED=== + +const /*x*/ x = 1, /*y*/ y = 2, z = 1; \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeInListAfter5.js b/tests/baselines/reference/textChanges/insertNodeInListAfter5.js new file mode 100644 index 0000000000..42d5fe2ca4 --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeInListAfter5.js @@ -0,0 +1,6 @@ +===ORIGINAL=== + +const x = 1; +===MODIFIED=== + +const x = 1, z = 1; \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeInListAfter6.js b/tests/baselines/reference/textChanges/insertNodeInListAfter6.js new file mode 100644 index 0000000000..06eae7372a --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeInListAfter6.js @@ -0,0 +1,9 @@ +===ORIGINAL=== + +const x = 1, + y = 2; +===MODIFIED=== + +const x = 1, + z = 1, + y = 2; \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeInListAfter7.js b/tests/baselines/reference/textChanges/insertNodeInListAfter7.js new file mode 100644 index 0000000000..bef0150368 --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeInListAfter7.js @@ -0,0 +1,9 @@ +===ORIGINAL=== + +const x = 1, + y = 2; +===MODIFIED=== + +const x = 1, + y = 2, + z = 1; \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeInListAfter8.js b/tests/baselines/reference/textChanges/insertNodeInListAfter8.js new file mode 100644 index 0000000000..e3c44b1427 --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeInListAfter8.js @@ -0,0 +1,9 @@ +===ORIGINAL=== + +const /*x*/ x = 1, + /*y*/ y = 2; +===MODIFIED=== + +const /*x*/ x = 1, + z = 1, + /*y*/ y = 2; \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/insertNodeInListAfter9.js b/tests/baselines/reference/textChanges/insertNodeInListAfter9.js new file mode 100644 index 0000000000..510984b757 --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeInListAfter9.js @@ -0,0 +1,9 @@ +===ORIGINAL=== + +const /*x*/ x = 1, + /*y*/ y = 2; +===MODIFIED=== + +const /*x*/ x = 1, + /*y*/ y = 2, + z = 1; \ No newline at end of file diff --git a/tests/cases/fourslash/importNameCodeFixExistingImport10.ts b/tests/cases/fourslash/importNameCodeFixExistingImport10.ts index 25246e7012..8a178e7273 100644 --- a/tests/cases/fourslash/importNameCodeFixExistingImport10.ts +++ b/tests/cases/fourslash/importNameCodeFixExistingImport10.ts @@ -16,6 +16,6 @@ verify.importFixAtPosition([ `{ v1, v2, -f1 + f1 }` ]); \ No newline at end of file diff --git a/tests/cases/fourslash/importNameCodeFixExistingImport11.ts b/tests/cases/fourslash/importNameCodeFixExistingImport11.ts index 304ffb896d..8822356c13 100644 --- a/tests/cases/fourslash/importNameCodeFixExistingImport11.ts +++ b/tests/cases/fourslash/importNameCodeFixExistingImport11.ts @@ -15,6 +15,7 @@ verify.importFixAtPosition([ `{ v1, v2, - v3, f1 + v3, + f1 }` ]); \ No newline at end of file diff --git a/tests/cases/fourslash/importNameCodeFixExistingImport9.ts b/tests/cases/fourslash/importNameCodeFixExistingImport9.ts index 05d1792745..51496abff1 100644 --- a/tests/cases/fourslash/importNameCodeFixExistingImport9.ts +++ b/tests/cases/fourslash/importNameCodeFixExistingImport9.ts @@ -11,7 +11,6 @@ verify.importFixAtPosition([ `{ - v1, -f1 + v1, f1 }` ]); \ No newline at end of file From 79a4557f4c1737ee4dd4151e94f7f2c24b792e8b Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Tue, 14 Mar 2017 16:24:59 -0700 Subject: [PATCH 071/164] visit type literal and dotDotDottoken --- src/compiler/visitor.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index e64e59eba3..ba348a558b 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -270,7 +270,7 @@ namespace ts { return updateParameter(node, nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), - (node).dotDotDotToken, + visitNode((node).dotDotDotToken, visitor), visitNode((node).name, visitor, isBindingName), visitNode((node).questionToken, visitor, isToken), visitNode((node).type, visitor, isTypeNode), @@ -294,7 +294,7 @@ namespace ts { case SyntaxKind.NeverKeyword: case SyntaxKind.NeverKeyword: case SyntaxKind.ThisKeyword: - return node; + throw new Error("should be caught above"); // Types @@ -332,7 +332,8 @@ namespace ts { case SyntaxKind.MappedType: throw new Error("reached unsupported type in visitor."); case SyntaxKind.LiteralType: - throw new Error("reached unsupported type in visitor."); + return updateLiteralTypeNode(node + , visitNode((node).literal, visitor, isExpression)); // Type Declarations From e381ffaac7f0b59caa2a41f9813acf4a487664b5 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Tue, 14 Mar 2017 16:25:51 -0700 Subject: [PATCH 072/164] don't add any typenode for signature return type --- src/services/codefixes/helpers.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index c51687962b..e6f4524c71 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -94,18 +94,17 @@ namespace ts.codefix { const newTypeParameters = signature.typeParameters && signature.typeParameters.map(checker.createTypeParameterDeclarationFromType); const newParameterNodes = signature.getParameters().map(symbol => createParameterDeclarationFromSymbol(symbol, enclosingDeclaration, checker)); - const returnType = checker.createTypeNode(checker.getWidenedType(checker.getReturnTypeOfSignature(signature))); + const returnType = createTypeNodeExceptAny(checker.getReturnTypeOfSignature(signature), checker); return createStubbedMethod(modifiers, name, newTypeParameters, newParameterNodes, returnType); } let signatureDeclarations = []; for (let i = 0; i < signatures.length; i++) { - // const sigString = checker.signatureToString(signatures[i], enclosingDeclaration, TypeFormatFlags.SuppressAnyReturnType, SignatureKind.Call); // TODO: make signatures instead of methods const signature = signatures[i]; const newTypeParameters = signature.typeParameters && signature.typeParameters.map(checker.createTypeParameterDeclarationFromType); const newParameterNodes = signature.getParameters().map(symbol => createParameterDeclarationFromSymbol(symbol, enclosingDeclaration, checker)); - const returnType = checker.createTypeNode(signature.resolvedReturnType); + const returnType = createTypeNodeExceptAny(checker.getReturnTypeOfSignature(signature), checker); signatureDeclarations.push(createMethod( /*decorators*/ undefined , modifiers @@ -121,7 +120,7 @@ namespace ts.codefix { let signature = checker.getSignatureFromDeclaration(declarations[declarations.length - 1] as SignatureDeclaration); const newTypeParameters = signature.typeParameters && signature.typeParameters.map(checker.createTypeParameterDeclarationFromType); const newParameterNodes = signature.getParameters().map(symbol => createParameterDeclarationFromSymbol(symbol, enclosingDeclaration, checker)); - const returnType = checker.createTypeNode(checker.getWidenedType(checker.getReturnTypeOfSignature(signature))); + const returnType = createTypeNodeExceptAny(checker.getReturnTypeOfSignature(signature), checker); signatureDeclarations.push(createStubbedMethod(modifiers, name, newTypeParameters, newParameterNodes, returnType)); } else { @@ -236,4 +235,9 @@ namespace ts.codefix { , /*initializer*/ undefined); return parameterNode; } + + function createTypeNodeExceptAny(type: Type, checker: TypeChecker) { + const typeNode = checker.createTypeNode(type); + return typeNode && typeNode.kind !== SyntaxKind.AnyKeyword ? typeNode : undefined; + } } \ No newline at end of file From b8756597b8208844dcbf724fc69eb84589608fd2 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Tue, 14 Mar 2017 16:45:47 -0700 Subject: [PATCH 073/164] test cleanup --- ...ssImplementInterfaceIndexSignaturesNumber.ts | 1 - ...sImplementInterfaceInheritsAbstractMethod.ts | 17 ++++++----------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceIndexSignaturesNumber.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceIndexSignaturesNumber.ts index 41bb7257e4..82cc53570f 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceIndexSignaturesNumber.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceIndexSignaturesNumber.ts @@ -3,7 +3,6 @@ //// interface I { //// [x: number]: I; //// } -//// //// class C implements I {[| |]} verify.rangeAfterCodeFix(` diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceInheritsAbstractMethod.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceInheritsAbstractMethod.ts index b49d42dab5..c141592823 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceInheritsAbstractMethod.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceInheritsAbstractMethod.ts @@ -1,16 +1,11 @@ /// -// abstract class C1 { -// -// } -// -// abstract class C2 { -// abstract f1(); -// } -// -// interface I1 extends C1, C2 {} -// -// class C3 implements I1 {[| |]} +//// abstract class C1 { } +//// abstract class C2 { +//// abstract f1(); +//// } +//// interface I1 extends C1, C2 { } +//// class C3 implements I1 {[| |]} verify.rangeAfterCodeFix(`f1(){ throw new Error("Method not implemented."); From 5775d27e32034d2712902011f05c713f95698aba Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Tue, 14 Mar 2017 17:08:35 -0700 Subject: [PATCH 074/164] respect initial order of changes --- src/harness/unittests/textChanges.ts | 17 +++++++++++++++ src/services/textChanges.ts | 14 +++++++------ .../insertNodeAfterMultipleNodes.js | 21 +++++++++++++++++++ 3 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 tests/baselines/reference/textChanges/insertNodeAfterMultipleNodes.js diff --git a/src/harness/unittests/textChanges.ts b/src/harness/unittests/textChanges.ts index 61f6d738e5..8724f7aa39 100644 --- a/src/harness/unittests/textChanges.ts +++ b/src/harness/unittests/textChanges.ts @@ -650,5 +650,22 @@ import { changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(undefined, createIdentifier("a"))); }) } + { + const text = ` +class A { + x; +}`; + runSingleFileTest("insertNodeAfterMultipleNodes", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + let newNodes = []; + for (let i = 0; i < 11 /*error doesn't occur with fewer nodes*/; ++i) { + newNodes.push( + createProperty(undefined, undefined, i + "", undefined, undefined, undefined)); + } + const insertAfter = findChild("x", sourceFile); + for (const newNode of newNodes) { + changeTracker.insertNodeAfter(sourceFile, insertAfter, newNode, { suffix: newLineCharacter }); + } + }); + } }); } \ No newline at end of file diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 174f2969a0..bb310657b6 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -407,10 +407,8 @@ namespace ts.textChanges { changesPerFile.forEachValue(path => { const changesInFile = changesPerFile.get(path); const sourceFile = changesInFile[0].sourceFile; - ChangeTracker.normalize(changesInFile); - const fileTextChanges: FileTextChanges = { fileName: sourceFile.fileName, textChanges: [] }; - for (const c of changesInFile) { + for (const c of ChangeTracker.normalize(changesInFile)) { fileTextChanges.textChanges.push({ span: this.computeSpan(c, sourceFile), newText: this.computeNewText(c, sourceFile) @@ -463,11 +461,15 @@ namespace ts.textChanges { private static normalize(changes: Change[]) { // order changes by start position - changes.sort((a, b) => a.range.pos - b.range.pos); + const normalized = changes + .map((c, i) => ({ c, i })) + .sort(({ c: a, i: i1 }, { c: b, i: i2 }) => (a.range.pos - b.range.pos) || i1 - i2) + .map(({ c }) => c); // verify that end position of the change is less than start position of the next change - for (let i = 0; i < changes.length - 2; i++) { - Debug.assert(changes[i].range.end <= changes[i + 1].range.pos); + for (let i = 0; i < normalized.length - 2; i++) { + Debug.assert(normalized[i].range.end <= normalized[i + 1].range.pos); } + return normalized; } } diff --git a/tests/baselines/reference/textChanges/insertNodeAfterMultipleNodes.js b/tests/baselines/reference/textChanges/insertNodeAfterMultipleNodes.js new file mode 100644 index 0000000000..1c3bbe4d3e --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeAfterMultipleNodes.js @@ -0,0 +1,21 @@ +===ORIGINAL=== + +class A { + x; +} +===MODIFIED=== + +class A { + x; + 0; + 1; + 2; + 3; + 4; + 5; + 6; + 7; + 8; + 9; + 10; +} \ No newline at end of file From 323aa3a56c14d76c0ecd2d450572cd120269b41d Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Tue, 14 Mar 2017 17:17:16 -0700 Subject: [PATCH 075/164] add asserts for cases when containing list cannot be determined --- src/services/textChanges.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index bb310657b6..4dcb0867d9 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -190,6 +190,7 @@ namespace ts.textChanges { public deleteNodeInList(sourceFile: SourceFile, node: Node) { const containingList = formatting.SmartIndenter.getContainingList(node, sourceFile); if (!containingList) { + Debug.fail("node is not a list element"); return this; } const index = containingList.indexOf(node); @@ -260,6 +261,7 @@ namespace ts.textChanges { public insertNodeInListAfter(sourceFile: SourceFile, after: Node, newNode: Node) { const containingList = formatting.SmartIndenter.getContainingList(after, sourceFile); if (!containingList) { + Debug.fail("node is not a list element"); return this; } const index = containingList.indexOf(after); From e185ebb8d52bac8e0a344629d7cfda8e7e39c2b3 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Tue, 14 Mar 2017 18:24:00 -0700 Subject: [PATCH 076/164] simplify rest param handling --- src/compiler/checker.ts | 6 ++--- src/services/codefixes/fixAddMissingMember.ts | 4 +-- src/services/codefixes/helpers.ts | 25 +++++++++++-------- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e9cea047ea..df4bfbb845 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2340,8 +2340,8 @@ namespace ts { // The type is an object literal type. if (!type.symbol) { // Anonymous types without symbols are literals. - // mapToTypeDeclarationsArray(type) - throw new Error("unknown case."); + // TODO: handle this case correctly. + noop(); } return createTypeLiteralNodeFromType(type); @@ -2471,7 +2471,7 @@ namespace ts { case SyntaxKind.IndexSignature: throw new Error("type literal constituent not implemented."); default: - throw new Error("Unknown case."); + throw new Error("Unknown resolved member kind."); } }); return typeElements.length ? typeElements : undefined; diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index 61c823908d..ace11cda80 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -52,7 +52,7 @@ namespace ts.codefix { , /*initializer*/ undefined); // TODO: make index signature. const propertyChangeTracker = textChanges.ChangeTracker.fromCodeFixContext(context); - propertyChangeTracker.insertNodeAfter(sourceFile, openBrace, property, { insertTrailingNewLine: true }); + propertyChangeTracker.insertNodeAfter(sourceFile, openBrace, property, { suffix: context.newLineCharacter }); const stringTypeNode = createKeywordTypeNode(SyntaxKind.StringKeyword); const indexingParameter = createParameter( @@ -70,7 +70,7 @@ namespace ts.codefix { , /*modifiers*/ undefined); const indexSignatureChangeTracker = textChanges.ChangeTracker.fromCodeFixContext(context); - indexSignatureChangeTracker.insertNodeAfter(sourceFile, openBrace, indexSignature, { insertTrailingNewLine: true }); + indexSignatureChangeTracker.insertNodeAfter(sourceFile, openBrace, indexSignature, { suffix: context.newLineCharacter }); return [{ description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_declaration_for_missing_property_0), [token.getText()]), diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index e6f4524c71..da579cccb1 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -11,7 +11,7 @@ namespace ts.codefix { const changeTracker = textChanges.ChangeTracker.fromCodeFixContext(context); for (const newNode of newNodes) { - changeTracker.insertNodeAfter(sourceFile, insertAfter, newNode, { insertTrailingNewLine: true }); + changeTracker.insertNodeAfter(sourceFile, insertAfter, newNode, { suffix: context.newLineCharacter }); } return changeTracker.getChanges(); } @@ -137,20 +137,23 @@ namespace ts.codefix { function createMethodImplementingSignatures(signatures: Signature[], name: PropertyName, modifiers: Modifier[] | undefined): MethodDeclaration { Debug.assert(signatures && signatures.length > 0); - let maxNonRestArgs = -1; let maxArgsIndex = 0; + /** This is *a* signature with the maximal number of arguments, + * such that if there is a "maximal" signature without rest arguments, + * this is one of them. + */ + let maxArgsSignature = signatures[0]; let minArgumentCount = signatures[0].minArgumentCount; - let hasRestParameter = false; + let someSigHasRestParameter = false; for (let i = 0; i < signatures.length; i++) { const sig = signatures[i]; minArgumentCount = Math.min(sig.minArgumentCount, minArgumentCount); - hasRestParameter = hasRestParameter || sig.hasRestParameter; - const nonRestLength = sig.parameters.length - (sig.hasRestParameter ? 1 : 0); - if (nonRestLength >= maxNonRestArgs) { - maxNonRestArgs = nonRestLength; - maxArgsIndex = i; + someSigHasRestParameter = someSigHasRestParameter || sig.hasRestParameter; + if (sig.parameters.length >= maxArgsSignature.parameters.length && (!sig.hasRestParameter || maxArgsSignature.hasRestParameter)) { + maxArgsSignature = sig; } } + const maxNonRestArgs = maxArgsSignature.parameters.length - (maxArgsSignature.hasRestParameter ? 1 : 0); const maxArgsParameterSymbolNames = signatures[maxArgsIndex].getParameters().map(symbol => symbol.getName()); const parameters: ParameterDeclaration[] = []; @@ -167,15 +170,15 @@ namespace ts.codefix { parameters.push(newParameter); } - if (hasRestParameter) { - const anyType = createKeywordTypeNode(SyntaxKind.AnyKeyword); + if (someSigHasRestParameter) { + const anyArrayType = createArrayTypeNode(createKeywordTypeNode(SyntaxKind.AnyKeyword)); const restParameter = createParameter( /*decorators*/ undefined , /*modifiers*/ undefined , createToken(SyntaxKind.DotDotDotToken) , maxArgsParameterSymbolNames[maxNonRestArgs] || "rest" , /*questionToken*/ maxNonRestArgs >= minArgumentCount ? createToken(SyntaxKind.QuestionToken) : undefined - , anyType + , anyArrayType , /*initializer*/ undefined); parameters.push(restParameter); } From c687add579382a0910e985a36f88434312097dcc Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Tue, 14 Mar 2017 22:36:38 -0700 Subject: [PATCH 077/164] add tests to add and remove members in class --- src/harness/unittests/textChanges.ts | 42 +++++++++++++++++++ .../textChanges/deleteNodeAfterInClass1.js | 12 ++++++ .../textChanges/deleteNodeAfterInClass2.js | 12 ++++++ .../textChanges/insertNodeAfterInClass1.js | 12 ++++++ .../textChanges/insertNodeAfterInClass2.js | 12 ++++++ 5 files changed, 90 insertions(+) create mode 100644 tests/baselines/reference/textChanges/deleteNodeAfterInClass1.js create mode 100644 tests/baselines/reference/textChanges/deleteNodeAfterInClass2.js create mode 100644 tests/baselines/reference/textChanges/insertNodeAfterInClass1.js create mode 100644 tests/baselines/reference/textChanges/insertNodeAfterInClass2.js diff --git a/src/harness/unittests/textChanges.ts b/src/harness/unittests/textChanges.ts index 8724f7aa39..b2fc1ae577 100644 --- a/src/harness/unittests/textChanges.ts +++ b/src/harness/unittests/textChanges.ts @@ -667,5 +667,47 @@ class A { } }); } + { + const text = ` +class A { + x +} +`; + runSingleFileTest("insertNodeAfterInClass1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeAfter(sourceFile, findChild("x", sourceFile), createProperty(undefined, undefined, "a", undefined, createKeywordTypeNode(SyntaxKind.BooleanKeyword), undefined), { suffix: newLineCharacter }); + }); + } + { + const text = ` +class A { + x; +} +`; + runSingleFileTest("insertNodeAfterInClass2", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.insertNodeAfter(sourceFile, findChild("x", sourceFile), createProperty(undefined, undefined, "a", undefined, createKeywordTypeNode(SyntaxKind.BooleanKeyword), undefined), { suffix: newLineCharacter }); + }); + } + { + const text = ` +class A { + x; + y = 1; +} +`; + runSingleFileTest("deleteNodeAfterInClass1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNode(sourceFile, findChild("x", sourceFile)); + }); + } + { + const text = ` +class A { + x + y = 1; +} +`; + runSingleFileTest("deleteNodeAfterInClass2", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + changeTracker.deleteNode(sourceFile, findChild("x", sourceFile)); + }); + } }); } \ No newline at end of file diff --git a/tests/baselines/reference/textChanges/deleteNodeAfterInClass1.js b/tests/baselines/reference/textChanges/deleteNodeAfterInClass1.js new file mode 100644 index 0000000000..d8d54153ea --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeAfterInClass1.js @@ -0,0 +1,12 @@ +===ORIGINAL=== + +class A { + x; + y = 1; +} + +===MODIFIED=== + +class A { + y = 1; +} diff --git a/tests/baselines/reference/textChanges/deleteNodeAfterInClass2.js b/tests/baselines/reference/textChanges/deleteNodeAfterInClass2.js new file mode 100644 index 0000000000..8d18d82021 --- /dev/null +++ b/tests/baselines/reference/textChanges/deleteNodeAfterInClass2.js @@ -0,0 +1,12 @@ +===ORIGINAL=== + +class A { + x + y = 1; +} + +===MODIFIED=== + +class A { + y = 1; +} diff --git a/tests/baselines/reference/textChanges/insertNodeAfterInClass1.js b/tests/baselines/reference/textChanges/insertNodeAfterInClass1.js new file mode 100644 index 0000000000..87206e588f --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeAfterInClass1.js @@ -0,0 +1,12 @@ +===ORIGINAL=== + +class A { + x +} + +===MODIFIED=== + +class A { + x + a: boolean; +} diff --git a/tests/baselines/reference/textChanges/insertNodeAfterInClass2.js b/tests/baselines/reference/textChanges/insertNodeAfterInClass2.js new file mode 100644 index 0000000000..1d583d8ac9 --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeAfterInClass2.js @@ -0,0 +1,12 @@ +===ORIGINAL=== + +class A { + x; +} + +===MODIFIED=== + +class A { + x; + a: boolean; +} From 758e1ff8b7ee7b87f0d0e55b2e2a446d70eec6d8 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Wed, 15 Mar 2017 09:06:59 -0700 Subject: [PATCH 078/164] temp --- src/compiler/checker.ts | 11 ++--------- src/services/codefixes/helpers.ts | 2 +- .../codeFixUndeclaredIndexSignatureNumericLiteral.ts | 2 +- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index df4bfbb845..bc718e4c1d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2293,25 +2293,18 @@ namespace ts { } if (objectFlags & ObjectFlags.ClassOrInterface) { Debug.assert(!!(type.flags & TypeFlags.Object)); + // TODO: Detect whether class is named and fail if not. const name = getNameOfSymbol(type.symbol); // TODO: handle type arguments. - // TODO: handle anonymous classes. return createTypeReferenceNode(name, /*typeParameters*/undefined); } if (type.flags & TypeFlags.TypeParameter) { - const constraint = createTypeNode(getConstraintFromTypeParameter(type)) as TypeNode; - const defaultParameter = createTypeNode(getDefaultFromTypeParameter(type)) as TypeNode; - if(constraint || defaultParameter) { - // Type parameters in type position can't have constraints or defaults. - encounteredError = true; - return undefined; - } // TODO: get qualified name when necessary instead of string. const name = symbolToString(type.symbol); + // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. return createTypeReferenceNode(name, /*typeArguments*/ undefined); } - // accessible type aliasSymbol // TODO: move back up later on? if (checkAlias && type.aliasSymbol) { const name = getNameOfSymbol(type.aliasSymbol); diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index da579cccb1..37ea8bab1a 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -225,7 +225,7 @@ namespace ts.codefix { function createParameterDeclarationFromSymbol(parameterSymbol: Symbol, enclosingDeclaration: ClassLikeDeclaration, checker: TypeChecker) { const parameterDeclaration = parameterSymbol.getDeclarations()[0] as ParameterDeclaration; - const parameterType = checker.getWidenedType(checker.getTypeOfSymbolAtLocation(parameterSymbol, enclosingDeclaration)); + const parameterType = checker.getTypeOfSymbolAtLocation(parameterSymbol, enclosingDeclaration); const parameterTypeNode = checker.createTypeNode(parameterType); // TODO: deep cloning of decorators/any node. const parameterNode = createParameter( diff --git a/tests/cases/fourslash/codeFixUndeclaredIndexSignatureNumericLiteral.ts b/tests/cases/fourslash/codeFixUndeclaredIndexSignatureNumericLiteral.ts index 2e49a8184e..0a2b0ee799 100644 --- a/tests/cases/fourslash/codeFixUndeclaredIndexSignatureNumericLiteral.ts +++ b/tests/cases/fourslash/codeFixUndeclaredIndexSignatureNumericLiteral.ts @@ -8,7 +8,7 @@ verify.rangeAfterCodeFix(` class A { - [name: string]: number; + [x: string]: number; constructor() { this.x = 10; From 798062944ba3add53e264b3b77c5c9cf55e18523 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 15 Mar 2017 12:27:47 -0700 Subject: [PATCH 079/164] Code review comments --- src/services/codefixes/fixAddMissingMember.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index bc2ee6fe0f..765ffa818b 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -31,7 +31,7 @@ namespace ts.codefix { return undefined; } - const isStatic = hasModifier(getThisContainer(token, /*includeArrowFunctions*/ false), ModifierFlags.Static); + const isStatic = hasModifier(classMemberDeclaration, ModifierFlags.Static); return isInJavaScriptFile(sourceFile) ? getActionsForAddMissingMemberInJavaScriptFile() : getActionsForAddMissingMemberInTypeScriptFile(); @@ -54,7 +54,7 @@ namespace ts.codefix { fileName: sourceFile.fileName, textChanges: [{ span: { start: startPos, length: 0 }, - newText: `${isStatic ? "static " : ""}${token.getFullText(sourceFile)}: ${typeString};` + newText: `${isStatic ? "static " : ""}${token.getText(sourceFile)}: ${typeString};` }] }] }]; From 3b57b5d4d570beccd2d87df9812dc90941897c21 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 15 Mar 2017 15:17:33 -0700 Subject: [PATCH 080/164] Refactor checking for checkJs value in a common helper --- src/compiler/core.ts | 6 +++++- src/compiler/program.ts | 5 ++--- src/services/codefixes/disableJsDiagnostics.ts | 8 ++------ 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index c380a39611..14aeb35dc8 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1,4 +1,4 @@ -/// +/// /// namespace ts { @@ -2360,4 +2360,8 @@ namespace ts { return Extension.Jsx; } } + + export function isCheckJsEnabledForFile(sourceFile: SourceFile, compilerOptions: CompilerOptions) { + return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs; + } } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index bdc8f76cf6..8f1bd4ba36 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1,4 +1,4 @@ -/// +/// /// /// @@ -918,8 +918,7 @@ namespace ts { Debug.assert(!!sourceFile.bindDiagnostics); const bindDiagnostics = sourceFile.bindDiagnostics; // For JavaScript files, we don't want to report semantic errors unless explicitly requested. - const includeCheckDiagnostics = !isSourceFileJavaScript(sourceFile) || - (sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : options.checkJs); + const includeCheckDiagnostics = !isSourceFileJavaScript(sourceFile) || isCheckJsEnabledForFile(sourceFile, options); const checkDiagnostics = includeCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : []; const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName); const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName); diff --git a/src/services/codefixes/disableJsDiagnostics.ts b/src/services/codefixes/disableJsDiagnostics.ts index c18c0153a0..621555cf84 100644 --- a/src/services/codefixes/disableJsDiagnostics.ts +++ b/src/services/codefixes/disableJsDiagnostics.ts @@ -1,4 +1,4 @@ -/* @internal */ +/* @internal */ namespace ts.codefix { registerCodeFix({ errorCodes: getApplicableDiagnosticCodes(), @@ -12,10 +12,6 @@ namespace ts.codefix { .map(d => allDiagnostcs[d].code); } - function shouldCheckJsFile(sourceFile: SourceFile, compilerOptions: CompilerOptions) { - return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs; - } - function getSuppressCommentLocationForLocation(sourceFile: SourceFile, position: number, newLineCharacter: string) { let { line } = getLineAndCharacterOfPosition(sourceFile, position); const lineStartPosition = getStartPositionOfLine(line, sourceFile); @@ -46,7 +42,7 @@ namespace ts.codefix { function getDisableJsDiagnosticsCodeActions(context: CodeFixContext): CodeAction[] | undefined { const { sourceFile, program, newLineCharacter, span } = context; - if (!isInJavaScriptFile(sourceFile) || !shouldCheckJsFile(sourceFile, program.getCompilerOptions())) { + if (!isInJavaScriptFile(sourceFile) || !isCheckJsEnabledForFile(sourceFile, program.getCompilerOptions())) { return undefined; } From f2654c65d958b5cf4a47bcde2c0de5b093ca78b8 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 15 Mar 2017 15:40:01 -0700 Subject: [PATCH 081/164] Remove compileOnSave from compiler option --- src/compiler/commandLineParser.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index b07bdcc9fe..724c580ace 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -479,14 +479,12 @@ namespace ts { category: Diagnostics.Advanced_Options, description: Diagnostics.Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files }, - { name: "charset", type: "string", category: Diagnostics.Advanced_Options, description: Diagnostics.The_character_set_of_the_input_files }, - compileOnSaveCommandLineOption, { name: "emitBOM", type: "boolean", From efa3093eced433e7c58b93b0777440cdc468c4de Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 15 Mar 2017 16:08:32 -0700 Subject: [PATCH 082/164] Print comments in a diffrent column --- src/compiler/commandLineParser.ts | 62 ++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 724c580ace..f5cddf0e65 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -980,7 +980,12 @@ namespace ts { } } + function makePadding(paddingLength: number): string { + return Array(paddingLength + 1).join(" "); + } + function writeConfigurations() { + // Filter applicable options to place in the file const categorizedOptions = reduceLeft( filter(optionDeclarations, o => o.category !== Diagnostics.CommandLine_Options && o.category !== Diagnostics.Advanced_Options), (memo, value) => { @@ -990,44 +995,59 @@ namespace ts { } return memo; }, >{}); - const knownKesyCount = getOwnKeys(configurations.compilerOptions).length; - const newLine = "\n"; - const tab = " "; - - let result = ""; + // Serialize all options and thier descriptions + let marginLength = 0; let seenKnownKeys = 0; - result += `{${newLine}`; - result += `${tab}"compilerOptions": {${newLine}`; + const nameColumn: string[] = []; + const descriptionColumn: string[] = []; + const knownKesyCount = getOwnKeys(configurations.compilerOptions).length; for (const category in categorizedOptions) { - result += `${tab}${tab}// ${category}${newLine}`; - result += `${newLine}`; + if (nameColumn.length !== 0) { + nameColumn.push(""); + descriptionColumn.push(""); + } + nameColumn.push(`/* ${category} */`); + descriptionColumn.push(""); for (const option of categorizedOptions[category]) { - result += `${tab}${tab}// ${option.description && getLocaleSpecificMessage(option.description) || option.name}${newLine}`; + let optionName; if (configurations.compilerOptions[option.name]) { - result += `${tab}${tab}"${option.name}": ${JSON.stringify(configurations.compilerOptions[option.name])}${(seenKnownKeys += 1) === knownKesyCount ? "" : ","}${newLine}`; + optionName = `"${option.name}": ${JSON.stringify(configurations.compilerOptions[option.name])}${(seenKnownKeys += 1) === knownKesyCount ? "" : ","}`; } else { - result += `${tab}${tab}// "${option.name}": ${JSON.stringify(getDefaultValueForOption(option))},${newLine}`; + optionName = `// "${option.name}": ${JSON.stringify(getDefaultValueForOption(option))},`; } - result += `${newLine}`; + nameColumn.push(optionName); + descriptionColumn.push(`/* ${option.description && getLocaleSpecificMessage(option.description) || option.name} */`); + marginLength = Math.max(optionName.length, marginLength); } - result += `${newLine}`; + } + + // Write the output + const tab = makePadding(2); + const result: string[] = []; + result.push(`{`); + result.push(`${tab}"compilerOptions": {`); + // Print out each row, aligning all the descriptions on the same column. + for (let i = 0; i < nameColumn.length; i++) { + const optionName = nameColumn[i]; + const description = descriptionColumn[i]; + result.push(tab + tab + optionName + makePadding(marginLength - optionName.length + 2) + description); } if (configurations.files && configurations.files.length) { - result += `${tab}},${newLine}`; - result += `${tab}"files": [${newLine}`; + result.push(`${tab}},`); + result.push(`${tab}"files": [`); for (let i = 0; i < configurations.files.length; i++) { - result += `${tab}${tab}${JSON.stringify(configurations.files[i])}${i === configurations.files.length - 1 ? "" : ","}${newLine}`; + result.push(`${tab}${tab}${JSON.stringify(configurations.files[i])}${i === configurations.files.length - 1 ? "" : ","}`); } - result += `${tab}]${newLine}`; + result.push(`${tab}]`); } else { - result += `${tab}}${newLine}`; + result.push(`${tab}}`); } - result += `}${newLine}`; + result.push(`}`); - return result; + return result.join(sys.newLine); } } From 5bbd8f809a7765f231e1b5a0e4e3f653993a1c57 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 15 Mar 2017 16:15:59 -0700 Subject: [PATCH 083/164] rename catogories, and reorder options --- src/compiler/commandLineParser.ts | 48 ++++++++++++++-------------- src/compiler/diagnosticMessages.json | 4 +-- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index f5cddf0e65..1e6a89d444 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -238,68 +238,70 @@ namespace ts { description: Diagnostics.Unconditionally_emit_imports_for_unresolved_files }, - // Strict Checks + // Strict Type Checks { name: "strict", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.Strict_Checks, + category: Diagnostics.Strict_Type_Checks, description: Diagnostics.Enable_all_strict_type_checks }, { name: "noImplicitAny", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.Strict_Checks, + category: Diagnostics.Strict_Type_Checks, description: Diagnostics.Raise_error_on_expressions_and_declarations_with_an_implied_any_type, }, { name: "strictNullChecks", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.Strict_Checks, + category: Diagnostics.Strict_Type_Checks, description: Diagnostics.Enable_strict_null_checks }, { name: "noImplicitThis", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.Strict_Checks, + category: Diagnostics.Strict_Type_Checks, description: Diagnostics.Raise_error_on_this_expressions_with_an_implied_any_type, }, + { + name: "alwaysStrict", + type: "boolean", + showInSimplifiedHelpView: true, + category: Diagnostics.Strict_Type_Checks, + description: Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file + }, + + // Additional Checks { name: "noUnusedLocals", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.Strict_Checks, + category: Diagnostics.Additional_Checks, description: Diagnostics.Report_errors_on_unused_locals, }, { name: "noUnusedParameters", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.Strict_Checks, + category: Diagnostics.Additional_Checks, description: Diagnostics.Report_errors_on_unused_parameters, }, - { - name: "alwaysStrict", - type: "boolean", - showInSimplifiedHelpView: true, - category: Diagnostics.Strict_Checks, - description: Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file - }, { name: "noImplicitReturns", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.Strict_Checks, + category: Diagnostics.Additional_Checks, description: Diagnostics.Report_error_when_not_all_code_paths_in_function_return_a_value }, { name: "noFallthroughCasesInSwitch", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.Strict_Checks, + category: Diagnostics.Additional_Checks, description: Diagnostics.Report_errors_for_fallthrough_cases_in_switch_statement }, @@ -404,14 +406,6 @@ namespace ts { description: Diagnostics.Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set }, - // JSX - { - name: "jsxFactory", - type: "string", - category: Diagnostics.JSX_Options, - description: Diagnostics.Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h - }, - // Experimental { name: "experimentalDecorators", @@ -427,6 +421,12 @@ namespace ts { }, // Advanced + { + name: "jsxFactory", + type: "string", + category: Diagnostics.Advanced_Options, + description: Diagnostics.Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h + }, { name: "diagnostics", type: "boolean", diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 6546408fdc..e833d77651 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3137,7 +3137,7 @@ "category": "Message", "code": 6172 }, - "Strict Checks": { + "Strict Type Checks": { "category": "Message", "code": 6173 }, @@ -3149,7 +3149,7 @@ "category": "Message", "code": 6175 }, - "JSX Options": { + "Additional Checks": { "category": "Message", "code": 6176 }, From 5016141b94b0578ad3e9f0395d4a1e5a7ba444b5 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 15 Mar 2017 16:41:39 -0700 Subject: [PATCH 084/164] Remove `sourceMap:false` from default compiler optios now that we have all options generated --- src/compiler/commandLineParser.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 1e6a89d444..6c8c8bb1b2 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -665,8 +665,7 @@ namespace ts { export const defaultInitCompilerOptions: CompilerOptions = { module: ModuleKind.CommonJS, target: ScriptTarget.ES5, - strict: true, - sourceMap: false, + strict: true }; let optionNameMapCache: OptionNameMap; @@ -1011,7 +1010,7 @@ namespace ts { descriptionColumn.push(""); for (const option of categorizedOptions[category]) { let optionName; - if (configurations.compilerOptions[option.name]) { + if (hasProperty(configurations.compilerOptions, option.name)) { optionName = `"${option.name}": ${JSON.stringify(configurations.compilerOptions[option.name])}${(seenKnownKeys += 1) === knownKesyCount ? "" : ","}`; } else { From b6ccad4b54e362fff37e45d29fc75e4df52fb6d4 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 15 Mar 2017 17:21:07 -0700 Subject: [PATCH 085/164] Fix bad merge --- src/compiler/commandLineParser.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 6c8c8bb1b2..bc9d090edd 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -119,6 +119,7 @@ namespace ts { "es7": "lib.es2016.d.ts", "es2016": "lib.es2016.d.ts", "es2017": "lib.es2017.d.ts", + "esnext": "lib.esnext.d.ts", // Host only "dom": "lib.dom.d.ts", "dom.iterable": "lib.dom.iterable.d.ts", From 0112a38ec9460dbcd51e77e2124f074d2090bfd3 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 15 Mar 2017 17:21:28 -0700 Subject: [PATCH 086/164] Accept baselines --- .../tsconfig.json | 185 +++++------------ .../tsconfig.json | 185 +++++------------ .../tsconfig.json | 185 +++++------------ .../tsconfig.json | 195 +++++------------- .../tsconfig.json | 185 +++++------------ .../tsconfig.json | 185 +++++------------ .../tsconfig.json | 185 +++++------------ .../tsconfig.json | 185 +++++------------ 8 files changed, 421 insertions(+), 1069 deletions(-) diff --git a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json index 452c031408..13e3bdb0f4 100644 --- a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json @@ -1,133 +1,52 @@ -{ - "compilerOptions": { - // Basic Options - - // Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. - "target": "es5", - - // Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. - "module": "commonjs", - - // Specify library files to be included in the compilation: - // "lib": [], - - // Allow javascript files to be compiled. - // "allowJs": true, - - // Specify JSX code generation: 'preserve', 'react-native', or 'react'. - // "jsx": "preserve", - - // Generates corresponding '.d.ts' file. - // "declaration": true, - - // Generates corresponding '.map' file. - // "sourceMap": true, - - // Concatenate and emit output to single file. - // "outFile": "./", - - // Redirect output structure to the directory. - // "outDir": "./", - - // Specify the root directory of input files. Use to control the output directory structure with --outDir. - // "rootDir": "./", - - // Do not emit comments to output. - // "removeComments": true, - - // Do not emit outputs. - // "noEmit": true, - - // Import emit helpers from 'tslib'. - // "importHelpers": true, - - // Unconditionally emit imports for unresolved files. - // "isolatedModules": true, - - - // Strict Checks - - // Enable all strict type checks. - "strict": true, - - // Raise error on expressions and declarations with an implied 'any' type. - // "noImplicitAny": true, - - // Enable strict null checks. - // "strictNullChecks": true, - - // Raise error on 'this' expressions with an implied 'any' type. - // "noImplicitThis": true, - - // Report errors on unused locals. - // "noUnusedLocals": true, - - // Report errors on unused parameters. - // "noUnusedParameters": true, - - // Parse in strict mode and emit "use strict" for each source file. - // "alwaysStrict": true, - - // Report error when not all code paths in function return a value. - // "noImplicitReturns": true, - - // Report errors for fallthrough cases in switch statement. - // "noFallthroughCasesInSwitch": true, - - - // Module Resolution Options - - // Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). - // "moduleResolution": "node", - - // Base directory to resolve non-absolute module names. - // "baseUrl": "./", - - // List of path mapping entries for module names to locations relative to the 'baseUrl'. - // "paths": {}, - - // List of root folders whose combined content represent the structure of the project at runtime. - // "rootDirs": [], - - // List of folders to include type definitions from. - // "typeRoots": [], - - // Type declaration files to be included in compilation. - // "types": [], - - // Allow default imports from modules with no default export. This does not affect code emit, just typechecking. - // "allowSyntheticDefaultImports": true, - - - // SourceMap Options - - // Specify the location where debugger should locate TypeScript files instead of source locations. - // "sourceRoot": "./", - - // Specify the location where debugger should locate map files instead of generated locations. - // "mapRoot": "./", - - // Emit a single file with source maps instead of having a separate file. - // "inlineSourceMap": true, - - // Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. - // "inlineSources": true, - - - // JSX Options - - // Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'. - // "jsxFactory": "", - - - // Experimental Options - - // Enables experimental support for ES7 decorators. - // "experimentalDecorators": true, - - // Enables experimental support for emitting type metadata for decorators. - // "emitDecoratorMetadata": true, - - - } -} +{ + "compilerOptions": { + /* Basic Options */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ + // "lib": [], /* Specify library files to be included in the compilation: */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ + // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + + /* Strict Type Checks */ + "strict": true /* Enable all strict type checks. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + + /* SourceMap Options */ + // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + } +} \ No newline at end of file diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json index f4c45f1674..39dd00c200 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json @@ -1,133 +1,52 @@ -{ - "compilerOptions": { - // Basic Options - - // Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. - "target": "es5", - - // Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. - "module": "commonjs", - - // Specify library files to be included in the compilation: - // "lib": [], - - // Allow javascript files to be compiled. - // "allowJs": true, - - // Specify JSX code generation: 'preserve', 'react-native', or 'react'. - // "jsx": "preserve", - - // Generates corresponding '.d.ts' file. - // "declaration": true, - - // Generates corresponding '.map' file. - // "sourceMap": true, - - // Concatenate and emit output to single file. - // "outFile": "./", - - // Redirect output structure to the directory. - // "outDir": "./", - - // Specify the root directory of input files. Use to control the output directory structure with --outDir. - // "rootDir": "./", - - // Do not emit comments to output. - // "removeComments": true, - - // Do not emit outputs. - // "noEmit": true, - - // Import emit helpers from 'tslib'. - // "importHelpers": true, - - // Unconditionally emit imports for unresolved files. - // "isolatedModules": true, - - - // Strict Checks - - // Enable all strict type checks. - "strict": true, - - // Raise error on expressions and declarations with an implied 'any' type. - // "noImplicitAny": true, - - // Enable strict null checks. - // "strictNullChecks": true, - - // Raise error on 'this' expressions with an implied 'any' type. - // "noImplicitThis": true, - - // Report errors on unused locals. - "noUnusedLocals": true, - - // Report errors on unused parameters. - // "noUnusedParameters": true, - - // Parse in strict mode and emit "use strict" for each source file. - // "alwaysStrict": true, - - // Report error when not all code paths in function return a value. - // "noImplicitReturns": true, - - // Report errors for fallthrough cases in switch statement. - // "noFallthroughCasesInSwitch": true, - - - // Module Resolution Options - - // Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). - // "moduleResolution": "node", - - // Base directory to resolve non-absolute module names. - // "baseUrl": "./", - - // List of path mapping entries for module names to locations relative to the 'baseUrl'. - // "paths": {}, - - // List of root folders whose combined content represent the structure of the project at runtime. - // "rootDirs": [], - - // List of folders to include type definitions from. - // "typeRoots": [], - - // Type declaration files to be included in compilation. - // "types": [], - - // Allow default imports from modules with no default export. This does not affect code emit, just typechecking. - // "allowSyntheticDefaultImports": true, - - - // SourceMap Options - - // Specify the location where debugger should locate TypeScript files instead of source locations. - // "sourceRoot": "./", - - // Specify the location where debugger should locate map files instead of generated locations. - // "mapRoot": "./", - - // Emit a single file with source maps instead of having a separate file. - // "inlineSourceMap": true, - - // Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. - // "inlineSources": true, - - - // JSX Options - - // Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'. - // "jsxFactory": "", - - - // Experimental Options - - // Enables experimental support for ES7 decorators. - // "experimentalDecorators": true, - - // Enables experimental support for emitting type metadata for decorators. - // "emitDecoratorMetadata": true, - - - } -} +{ + "compilerOptions": { + /* Basic Options */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ + // "lib": [], /* Specify library files to be included in the compilation: */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ + // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + + /* Strict Type Checks */ + "strict": true, /* Enable all strict type checks. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + "noUnusedLocals": true /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + + /* SourceMap Options */ + // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + } +} \ No newline at end of file diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json index e02e2cf1ca..401ae3185f 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json @@ -1,133 +1,52 @@ -{ - "compilerOptions": { - // Basic Options - - // Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. - "target": "es5", - - // Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. - "module": "commonjs", - - // Specify library files to be included in the compilation: - // "lib": [], - - // Allow javascript files to be compiled. - // "allowJs": true, - - // Specify JSX code generation: 'preserve', 'react-native', or 'react'. - "jsx": "react", - - // Generates corresponding '.d.ts' file. - // "declaration": true, - - // Generates corresponding '.map' file. - // "sourceMap": true, - - // Concatenate and emit output to single file. - // "outFile": "./", - - // Redirect output structure to the directory. - // "outDir": "./", - - // Specify the root directory of input files. Use to control the output directory structure with --outDir. - // "rootDir": "./", - - // Do not emit comments to output. - // "removeComments": true, - - // Do not emit outputs. - // "noEmit": true, - - // Import emit helpers from 'tslib'. - // "importHelpers": true, - - // Unconditionally emit imports for unresolved files. - // "isolatedModules": true, - - - // Strict Checks - - // Enable all strict type checks. - "strict": true, - - // Raise error on expressions and declarations with an implied 'any' type. - // "noImplicitAny": true, - - // Enable strict null checks. - // "strictNullChecks": true, - - // Raise error on 'this' expressions with an implied 'any' type. - // "noImplicitThis": true, - - // Report errors on unused locals. - // "noUnusedLocals": true, - - // Report errors on unused parameters. - // "noUnusedParameters": true, - - // Parse in strict mode and emit "use strict" for each source file. - // "alwaysStrict": true, - - // Report error when not all code paths in function return a value. - // "noImplicitReturns": true, - - // Report errors for fallthrough cases in switch statement. - // "noFallthroughCasesInSwitch": true, - - - // Module Resolution Options - - // Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). - // "moduleResolution": "node", - - // Base directory to resolve non-absolute module names. - // "baseUrl": "./", - - // List of path mapping entries for module names to locations relative to the 'baseUrl'. - // "paths": {}, - - // List of root folders whose combined content represent the structure of the project at runtime. - // "rootDirs": [], - - // List of folders to include type definitions from. - // "typeRoots": [], - - // Type declaration files to be included in compilation. - // "types": [], - - // Allow default imports from modules with no default export. This does not affect code emit, just typechecking. - // "allowSyntheticDefaultImports": true, - - - // SourceMap Options - - // Specify the location where debugger should locate TypeScript files instead of source locations. - // "sourceRoot": "./", - - // Specify the location where debugger should locate map files instead of generated locations. - // "mapRoot": "./", - - // Emit a single file with source maps instead of having a separate file. - // "inlineSourceMap": true, - - // Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. - // "inlineSources": true, - - - // JSX Options - - // Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'. - // "jsxFactory": "", - - - // Experimental Options - - // Enables experimental support for ES7 decorators. - // "experimentalDecorators": true, - - // Enables experimental support for emitting type metadata for decorators. - // "emitDecoratorMetadata": true, - - - } -} +{ + "compilerOptions": { + /* Basic Options */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ + // "lib": [], /* Specify library files to be included in the compilation: */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + "jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ + // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + + /* Strict Type Checks */ + "strict": true /* Enable all strict type checks. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + + /* SourceMap Options */ + // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + } +} \ No newline at end of file diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json index f413bdd2a6..9e99149547 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json @@ -1,138 +1,57 @@ -{ - "compilerOptions": { - // Basic Options - - // Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. - "target": "es5", - - // Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. - "module": "commonjs", - - // Specify library files to be included in the compilation: - // "lib": [], - - // Allow javascript files to be compiled. - // "allowJs": true, - - // Specify JSX code generation: 'preserve', 'react-native', or 'react'. - // "jsx": "preserve", - - // Generates corresponding '.d.ts' file. - // "declaration": true, - - // Generates corresponding '.map' file. - // "sourceMap": true, - - // Concatenate and emit output to single file. - // "outFile": "./", - - // Redirect output structure to the directory. - // "outDir": "./", - - // Specify the root directory of input files. Use to control the output directory structure with --outDir. - // "rootDir": "./", - - // Do not emit comments to output. - // "removeComments": true, - - // Do not emit outputs. - // "noEmit": true, - - // Import emit helpers from 'tslib'. - // "importHelpers": true, - - // Unconditionally emit imports for unresolved files. - // "isolatedModules": true, - - - // Strict Checks - - // Enable all strict type checks. - "strict": true, - - // Raise error on expressions and declarations with an implied 'any' type. - // "noImplicitAny": true, - - // Enable strict null checks. - // "strictNullChecks": true, - - // Raise error on 'this' expressions with an implied 'any' type. - // "noImplicitThis": true, - - // Report errors on unused locals. - // "noUnusedLocals": true, - - // Report errors on unused parameters. - // "noUnusedParameters": true, - - // Parse in strict mode and emit "use strict" for each source file. - // "alwaysStrict": true, - - // Report error when not all code paths in function return a value. - // "noImplicitReturns": true, - - // Report errors for fallthrough cases in switch statement. - // "noFallthroughCasesInSwitch": true, - - - // Module Resolution Options - - // Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). - // "moduleResolution": "node", - - // Base directory to resolve non-absolute module names. - // "baseUrl": "./", - - // List of path mapping entries for module names to locations relative to the 'baseUrl'. - // "paths": {}, - - // List of root folders whose combined content represent the structure of the project at runtime. - // "rootDirs": [], - - // List of folders to include type definitions from. - // "typeRoots": [], - - // Type declaration files to be included in compilation. - // "types": [], - - // Allow default imports from modules with no default export. This does not affect code emit, just typechecking. - // "allowSyntheticDefaultImports": true, - - - // SourceMap Options - - // Specify the location where debugger should locate TypeScript files instead of source locations. - // "sourceRoot": "./", - - // Specify the location where debugger should locate map files instead of generated locations. - // "mapRoot": "./", - - // Emit a single file with source maps instead of having a separate file. - // "inlineSourceMap": true, - - // Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. - // "inlineSources": true, - - - // JSX Options - - // Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'. - // "jsxFactory": "", - - - // Experimental Options - - // Enables experimental support for ES7 decorators. - // "experimentalDecorators": true, - - // Enables experimental support for emitting type metadata for decorators. - // "emitDecoratorMetadata": true, - - - }, - "files": [ - "file0.st", - "file1.ts", - "file2.ts" - ] -} +{ + "compilerOptions": { + /* Basic Options */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ + // "lib": [], /* Specify library files to be included in the compilation: */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ + // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + + /* Strict Type Checks */ + "strict": true /* Enable all strict type checks. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + + /* SourceMap Options */ + // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + }, + "files": [ + "file0.st", + "file1.ts", + "file2.ts" + ] +} \ No newline at end of file diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json index 09b72cfa42..976f8c984e 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json @@ -1,133 +1,52 @@ -{ - "compilerOptions": { - // Basic Options - - // Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. - "target": "es5", - - // Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. - "module": "commonjs", - - // Specify library files to be included in the compilation: - "lib": ["es5","es2015.promise"], - - // Allow javascript files to be compiled. - // "allowJs": true, - - // Specify JSX code generation: 'preserve', 'react-native', or 'react'. - // "jsx": "preserve", - - // Generates corresponding '.d.ts' file. - // "declaration": true, - - // Generates corresponding '.map' file. - // "sourceMap": true, - - // Concatenate and emit output to single file. - // "outFile": "./", - - // Redirect output structure to the directory. - // "outDir": "./", - - // Specify the root directory of input files. Use to control the output directory structure with --outDir. - // "rootDir": "./", - - // Do not emit comments to output. - // "removeComments": true, - - // Do not emit outputs. - // "noEmit": true, - - // Import emit helpers from 'tslib'. - // "importHelpers": true, - - // Unconditionally emit imports for unresolved files. - // "isolatedModules": true, - - - // Strict Checks - - // Enable all strict type checks. - "strict": true, - - // Raise error on expressions and declarations with an implied 'any' type. - // "noImplicitAny": true, - - // Enable strict null checks. - // "strictNullChecks": true, - - // Raise error on 'this' expressions with an implied 'any' type. - // "noImplicitThis": true, - - // Report errors on unused locals. - // "noUnusedLocals": true, - - // Report errors on unused parameters. - // "noUnusedParameters": true, - - // Parse in strict mode and emit "use strict" for each source file. - // "alwaysStrict": true, - - // Report error when not all code paths in function return a value. - // "noImplicitReturns": true, - - // Report errors for fallthrough cases in switch statement. - // "noFallthroughCasesInSwitch": true, - - - // Module Resolution Options - - // Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). - // "moduleResolution": "node", - - // Base directory to resolve non-absolute module names. - // "baseUrl": "./", - - // List of path mapping entries for module names to locations relative to the 'baseUrl'. - // "paths": {}, - - // List of root folders whose combined content represent the structure of the project at runtime. - // "rootDirs": [], - - // List of folders to include type definitions from. - // "typeRoots": [], - - // Type declaration files to be included in compilation. - // "types": [], - - // Allow default imports from modules with no default export. This does not affect code emit, just typechecking. - // "allowSyntheticDefaultImports": true, - - - // SourceMap Options - - // Specify the location where debugger should locate TypeScript files instead of source locations. - // "sourceRoot": "./", - - // Specify the location where debugger should locate map files instead of generated locations. - // "mapRoot": "./", - - // Emit a single file with source maps instead of having a separate file. - // "inlineSourceMap": true, - - // Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. - // "inlineSources": true, - - - // JSX Options - - // Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'. - // "jsxFactory": "", - - - // Experimental Options - - // Enables experimental support for ES7 decorators. - // "experimentalDecorators": true, - - // Enables experimental support for emitting type metadata for decorators. - // "emitDecoratorMetadata": true, - - - } -} +{ + "compilerOptions": { + /* Basic Options */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ + "lib": ["es5","es2015.promise"], /* Specify library files to be included in the compilation: */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ + // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + + /* Strict Type Checks */ + "strict": true /* Enable all strict type checks. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + + /* SourceMap Options */ + // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + } +} \ No newline at end of file diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json index 452c031408..13e3bdb0f4 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json @@ -1,133 +1,52 @@ -{ - "compilerOptions": { - // Basic Options - - // Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. - "target": "es5", - - // Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. - "module": "commonjs", - - // Specify library files to be included in the compilation: - // "lib": [], - - // Allow javascript files to be compiled. - // "allowJs": true, - - // Specify JSX code generation: 'preserve', 'react-native', or 'react'. - // "jsx": "preserve", - - // Generates corresponding '.d.ts' file. - // "declaration": true, - - // Generates corresponding '.map' file. - // "sourceMap": true, - - // Concatenate and emit output to single file. - // "outFile": "./", - - // Redirect output structure to the directory. - // "outDir": "./", - - // Specify the root directory of input files. Use to control the output directory structure with --outDir. - // "rootDir": "./", - - // Do not emit comments to output. - // "removeComments": true, - - // Do not emit outputs. - // "noEmit": true, - - // Import emit helpers from 'tslib'. - // "importHelpers": true, - - // Unconditionally emit imports for unresolved files. - // "isolatedModules": true, - - - // Strict Checks - - // Enable all strict type checks. - "strict": true, - - // Raise error on expressions and declarations with an implied 'any' type. - // "noImplicitAny": true, - - // Enable strict null checks. - // "strictNullChecks": true, - - // Raise error on 'this' expressions with an implied 'any' type. - // "noImplicitThis": true, - - // Report errors on unused locals. - // "noUnusedLocals": true, - - // Report errors on unused parameters. - // "noUnusedParameters": true, - - // Parse in strict mode and emit "use strict" for each source file. - // "alwaysStrict": true, - - // Report error when not all code paths in function return a value. - // "noImplicitReturns": true, - - // Report errors for fallthrough cases in switch statement. - // "noFallthroughCasesInSwitch": true, - - - // Module Resolution Options - - // Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). - // "moduleResolution": "node", - - // Base directory to resolve non-absolute module names. - // "baseUrl": "./", - - // List of path mapping entries for module names to locations relative to the 'baseUrl'. - // "paths": {}, - - // List of root folders whose combined content represent the structure of the project at runtime. - // "rootDirs": [], - - // List of folders to include type definitions from. - // "typeRoots": [], - - // Type declaration files to be included in compilation. - // "types": [], - - // Allow default imports from modules with no default export. This does not affect code emit, just typechecking. - // "allowSyntheticDefaultImports": true, - - - // SourceMap Options - - // Specify the location where debugger should locate TypeScript files instead of source locations. - // "sourceRoot": "./", - - // Specify the location where debugger should locate map files instead of generated locations. - // "mapRoot": "./", - - // Emit a single file with source maps instead of having a separate file. - // "inlineSourceMap": true, - - // Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. - // "inlineSources": true, - - - // JSX Options - - // Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'. - // "jsxFactory": "", - - - // Experimental Options - - // Enables experimental support for ES7 decorators. - // "experimentalDecorators": true, - - // Enables experimental support for emitting type metadata for decorators. - // "emitDecoratorMetadata": true, - - - } -} +{ + "compilerOptions": { + /* Basic Options */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ + // "lib": [], /* Specify library files to be included in the compilation: */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ + // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + + /* Strict Type Checks */ + "strict": true /* Enable all strict type checks. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + + /* SourceMap Options */ + // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + } +} \ No newline at end of file diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json index 45915ac038..f4bc1dc9ef 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json @@ -1,133 +1,52 @@ -{ - "compilerOptions": { - // Basic Options - - // Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. - "target": "es5", - - // Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. - "module": "commonjs", - - // Specify library files to be included in the compilation: - "lib": ["es5","es2015.core"], - - // Allow javascript files to be compiled. - // "allowJs": true, - - // Specify JSX code generation: 'preserve', 'react-native', or 'react'. - // "jsx": "preserve", - - // Generates corresponding '.d.ts' file. - // "declaration": true, - - // Generates corresponding '.map' file. - // "sourceMap": true, - - // Concatenate and emit output to single file. - // "outFile": "./", - - // Redirect output structure to the directory. - // "outDir": "./", - - // Specify the root directory of input files. Use to control the output directory structure with --outDir. - // "rootDir": "./", - - // Do not emit comments to output. - // "removeComments": true, - - // Do not emit outputs. - // "noEmit": true, - - // Import emit helpers from 'tslib'. - // "importHelpers": true, - - // Unconditionally emit imports for unresolved files. - // "isolatedModules": true, - - - // Strict Checks - - // Enable all strict type checks. - "strict": true, - - // Raise error on expressions and declarations with an implied 'any' type. - // "noImplicitAny": true, - - // Enable strict null checks. - // "strictNullChecks": true, - - // Raise error on 'this' expressions with an implied 'any' type. - // "noImplicitThis": true, - - // Report errors on unused locals. - // "noUnusedLocals": true, - - // Report errors on unused parameters. - // "noUnusedParameters": true, - - // Parse in strict mode and emit "use strict" for each source file. - // "alwaysStrict": true, - - // Report error when not all code paths in function return a value. - // "noImplicitReturns": true, - - // Report errors for fallthrough cases in switch statement. - // "noFallthroughCasesInSwitch": true, - - - // Module Resolution Options - - // Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). - // "moduleResolution": "node", - - // Base directory to resolve non-absolute module names. - // "baseUrl": "./", - - // List of path mapping entries for module names to locations relative to the 'baseUrl'. - // "paths": {}, - - // List of root folders whose combined content represent the structure of the project at runtime. - // "rootDirs": [], - - // List of folders to include type definitions from. - // "typeRoots": [], - - // Type declaration files to be included in compilation. - // "types": [], - - // Allow default imports from modules with no default export. This does not affect code emit, just typechecking. - // "allowSyntheticDefaultImports": true, - - - // SourceMap Options - - // Specify the location where debugger should locate TypeScript files instead of source locations. - // "sourceRoot": "./", - - // Specify the location where debugger should locate map files instead of generated locations. - // "mapRoot": "./", - - // Emit a single file with source maps instead of having a separate file. - // "inlineSourceMap": true, - - // Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. - // "inlineSources": true, - - - // JSX Options - - // Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'. - // "jsxFactory": "", - - - // Experimental Options - - // Enables experimental support for ES7 decorators. - // "experimentalDecorators": true, - - // Enables experimental support for emitting type metadata for decorators. - // "emitDecoratorMetadata": true, - - - } -} +{ + "compilerOptions": { + /* Basic Options */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ + "lib": ["es5","es2015.core"], /* Specify library files to be included in the compilation: */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ + // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + + /* Strict Type Checks */ + "strict": true /* Enable all strict type checks. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + + /* SourceMap Options */ + // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + } +} \ No newline at end of file diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json index 33b17b3cf5..434e886b25 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json @@ -1,133 +1,52 @@ -{ - "compilerOptions": { - // Basic Options - - // Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. - "target": "es5", - - // Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. - "module": "commonjs", - - // Specify library files to be included in the compilation: - // "lib": [], - - // Allow javascript files to be compiled. - // "allowJs": true, - - // Specify JSX code generation: 'preserve', 'react-native', or 'react'. - // "jsx": "preserve", - - // Generates corresponding '.d.ts' file. - // "declaration": true, - - // Generates corresponding '.map' file. - // "sourceMap": true, - - // Concatenate and emit output to single file. - // "outFile": "./", - - // Redirect output structure to the directory. - // "outDir": "./", - - // Specify the root directory of input files. Use to control the output directory structure with --outDir. - // "rootDir": "./", - - // Do not emit comments to output. - // "removeComments": true, - - // Do not emit outputs. - // "noEmit": true, - - // Import emit helpers from 'tslib'. - // "importHelpers": true, - - // Unconditionally emit imports for unresolved files. - // "isolatedModules": true, - - - // Strict Checks - - // Enable all strict type checks. - "strict": true, - - // Raise error on expressions and declarations with an implied 'any' type. - // "noImplicitAny": true, - - // Enable strict null checks. - // "strictNullChecks": true, - - // Raise error on 'this' expressions with an implied 'any' type. - // "noImplicitThis": true, - - // Report errors on unused locals. - // "noUnusedLocals": true, - - // Report errors on unused parameters. - // "noUnusedParameters": true, - - // Parse in strict mode and emit "use strict" for each source file. - // "alwaysStrict": true, - - // Report error when not all code paths in function return a value. - // "noImplicitReturns": true, - - // Report errors for fallthrough cases in switch statement. - // "noFallthroughCasesInSwitch": true, - - - // Module Resolution Options - - // Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). - // "moduleResolution": "node", - - // Base directory to resolve non-absolute module names. - // "baseUrl": "./", - - // List of path mapping entries for module names to locations relative to the 'baseUrl'. - // "paths": {}, - - // List of root folders whose combined content represent the structure of the project at runtime. - // "rootDirs": [], - - // List of folders to include type definitions from. - // "typeRoots": [], - - // Type declaration files to be included in compilation. - "types": ["jquery","mocha"], - - // Allow default imports from modules with no default export. This does not affect code emit, just typechecking. - // "allowSyntheticDefaultImports": true, - - - // SourceMap Options - - // Specify the location where debugger should locate TypeScript files instead of source locations. - // "sourceRoot": "./", - - // Specify the location where debugger should locate map files instead of generated locations. - // "mapRoot": "./", - - // Emit a single file with source maps instead of having a separate file. - // "inlineSourceMap": true, - - // Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. - // "inlineSources": true, - - - // JSX Options - - // Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'. - // "jsxFactory": "", - - - // Experimental Options - - // Enables experimental support for ES7 decorators. - // "experimentalDecorators": true, - - // Enables experimental support for emitting type metadata for decorators. - // "emitDecoratorMetadata": true, - - - } -} +{ + "compilerOptions": { + /* Basic Options */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ + // "lib": [], /* Specify library files to be included in the compilation: */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ + // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + + /* Strict Type Checks */ + "strict": true, /* Enable all strict type checks. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + "types": ["jquery","mocha"] /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + + /* SourceMap Options */ + // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + } +} \ No newline at end of file From 0a2d7a7f94406d6c1a5c8d187171ac60cb7b56ca Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Wed, 15 Mar 2017 18:09:55 -0700 Subject: [PATCH 087/164] temp * added signature factory/visitor entry --- src/compiler/checker.ts | 34 ++++++++--- src/compiler/factory.ts | 34 +++++++++++ src/compiler/types.ts | 1 + src/compiler/utilities.ts | 4 ++ src/compiler/visitor.ts | 20 +++++-- src/harness/fourslash.ts | 2 +- .../codeFixClassImplementInterfaceComments.ts | 14 +++++ ...aceComputedPropertyNameWellKnownSymbols.ts | 1 - ...ClassImplementInterfaceEmptyTypeLiteral.ts | 13 +++++ ...ixClassImplementInterfaceMemberOrdering.ts | 58 +++++++++++++++++++ 10 files changed, 166 insertions(+), 15 deletions(-) create mode 100644 tests/cases/fourslash/codeFixClassImplementInterfaceComments.ts create mode 100644 tests/cases/fourslash/codeFixClassImplementInterfaceEmptyTypeLiteral.ts create mode 100644 tests/cases/fourslash/codeFixClassImplementInterfaceMemberOrdering.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bc718e4c1d..625f4d75eb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2322,10 +2322,18 @@ namespace ts { if (objectFlags & ObjectFlags.Mapped) { Debug.assert(!!(type.flags & TypeFlags.Object)); - // const typeParameter = getTypeParameterFromMappedType(type); + + // TODO: does typeParameter have the same constraint or do we need to overwrite it somehow? + const typeParameter = getTypeParameterFromMappedType(type); // const constraintType = getConstraintTypeFromMappedType(type); - // const templateType = getTemplateTypeFromMappedType(type); - throw new Error("Mapped types not implemented"); + const typeParameterNode = createTypeParameterDeclarationFromType(typeParameter); + + const templateTypeNode = createTypeNode(getTemplateTypeFromMappedType(type)); + const readonlyToken = (type).declaration && (type).declaration.readonlyToken ? createToken(SyntaxKind.ReadonlyKeyword) : undefined; + const questionToken = (type).declaration && (type).declaration.questionToken ? createToken(SyntaxKind.QuestionToken) : undefined; + + // TODO: test. + return createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode); } if (objectFlags & ObjectFlags.Anonymous) { @@ -2334,6 +2342,7 @@ namespace ts { if (!type.symbol) { // Anonymous types without symbols are literals. // TODO: handle this case correctly. + // TODO: test. noop(); } @@ -2343,9 +2352,11 @@ namespace ts { // TODO: string or number literal here or above? if (type.flags & TypeFlags.Index) { + // TODO: implement and test. throw new Error("index not implemented"); } if (type.flags & TypeFlags.IndexedAccess) { + // TODO: implement and test. throw new Error("indexed access not implemented"); } @@ -2414,7 +2425,6 @@ namespace ts { } function createTypeLiteralNodeFromType(type: ObjectType) { - // TODO: do we need to do something for mapped types here??? const resolvedType = resolveStructuredTypeMembers(type); const newMembers = createTypeNodesFromResolvedType(resolvedType); return createTypeLiteralNode(newMembers); @@ -2446,21 +2456,29 @@ namespace ts { } const kind = oldDeclaration.kind; - const memberName = symbolToString(memberSymbol); + const memberName = getSynthesizedDeepClone(oldDeclaration.name); + const memberType = getTypeOfSymbol(memberSymbol); switch (kind) { case SyntaxKind.PropertySignature: const optional = !!oldDeclaration.questionToken; - const typeOfOldMember = getTypeOfSymbol(memberSymbol); typeElements.push(createPropertySignature( - createIdentifier(memberName) + memberName , optional ? createToken(SyntaxKind.QuestionToken) : undefined - , createTypeNode(typeOfOldMember) + , createTypeNode(memberType) , /*initializer*/undefined)); break; case SyntaxKind.MethodSignature: case SyntaxKind.CallSignature: case SyntaxKind.ConstructSignature: + const signatureType = getSignaturesOfSymbol(memberSymbol); + signatureType + createSignatureDeclaration + throw new Error("signature problems."); + // name ?: PropertyName; + // typeParameters ?: NodeArray; + // parameters: NodeArray; + // type ?: TypeNode; case SyntaxKind.IndexSignature: throw new Error("type literal constituent not implemented."); default: diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index bd46e20878..c9fef5b026 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -255,6 +255,22 @@ namespace ts { : node; } + export function createSignatureDeclaration(kind: SyntaxKind, name: string | PropertyName | undefined, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): T { + const signatureDeclaration = createSynthesizedNode(kind) as T; + signatureDeclaration.name = asName(name); + signatureDeclaration.typeParameters = asNodeArray(typeParameters); + signatureDeclaration.type = type; + return signatureDeclaration; + } + + export function updateSignatureDeclaration(node: T, name: string | PropertyName | undefined, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): T { + return node.name !== name + || node.typeParameters !== typeParameters + || node.type !== type + ? updateNode(createSignatureDeclaration(node.kind, name, typeParameters, parameters, type), node) + : node; + } + export function createTypeReferenceNode(typeName: string | EntityName, typeArguments: NodeArray | undefined) { const typeReference = createSynthesizedNode(SyntaxKind.TypeReference) as TypeReferenceNode; @@ -321,6 +337,24 @@ namespace ts { : node; } + export function createMappedTypeNode(readonlyToken: ReadonlyToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | undefined, type: TypeNode | undefined): MappedTypeNode { + const mappedTypeNode = createSynthesizedNode(SyntaxKind.MappedType) as MappedTypeNode; + mappedTypeNode.readonlyToken = readonlyToken; + mappedTypeNode.typeParameter = typeParameter; + mappedTypeNode.questionToken = questionToken; + mappedTypeNode.type = type; + return mappedTypeNode; + } + + export function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | undefined, type: TypeNode | undefined): MappedTypeNode { + return node.readonlyToken !== readonlyToken + || node.typeParameter !== typeParameter + || node.questionToken !== questionToken + || node.type !== type + ? updateNode(createMappedTypeNode(readonlyToken, typeParameter, questionToken, type), node) + : node; + } + // Type Declarations export function createTypeParameterDeclaration(name: string | Identifier, constraint: TypeNode | undefined, defaultParameter: TypeNode | undefined) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 28c293ae53..7f6c56aa1f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -856,6 +856,7 @@ namespace ts { | SyntaxKind.BooleanKeyword | SyntaxKind.StringKeyword | SyntaxKind.SymbolKeyword + | SyntaxKind.ThisKeyword | SyntaxKind.VoidKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.NullKeyword diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index b4d65958f3..47642291c2 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3717,10 +3717,14 @@ namespace ts { return (kind >= SyntaxKind.FirstTypeNode && kind <= SyntaxKind.LastTypeNode) || kind === SyntaxKind.AnyKeyword || kind === SyntaxKind.NumberKeyword + || kind === SyntaxKind.ObjectKeyword || kind === SyntaxKind.BooleanKeyword || kind === SyntaxKind.StringKeyword || kind === SyntaxKind.SymbolKeyword + || kind === SyntaxKind.ThisKeyword || kind === SyntaxKind.VoidKeyword + || kind === SyntaxKind.UndefinedKeyword + || kind === SyntaxKind.NullKeyword || kind === SyntaxKind.NeverKeyword || kind === SyntaxKind.ExpressionWithTypeArguments; } diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index ba348a558b..206e269f36 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -258,13 +258,23 @@ namespace ts { return updateComputedPropertyName(node, visitNode((node).expression, visitor, isExpression)); - // Signature elements + // Signatures and Signature Elements + case SyntaxKind.FunctionType: + case SyntaxKind.CallSignature: + case SyntaxKind.ConstructSignature: + case SyntaxKind.MethodSignature: + return updateSignatureDeclaration(node + , visitNode((node).name, visitor, isPropertyName) + , nodesVisitor((node).typeParameters, visitor, isTypeParameter) + , nodesVisitor((node).parameters, visitor, isParameter) + , visitNode((node).type, visitor, isTypeNode)); + case SyntaxKind.IndexSignature: return updateIndexSignatureDeclaration(node - , nodesVisitor((node).parameters, visitor) - , visitNode((node).type, visitor) - , nodesVisitor((node).decorators, visitor, isDecorator) - , nodesVisitor((node).modifiers, visitor, isModifier)); + , nodesVisitor((node).parameters, visitor) + , visitNode((node).type, visitor, isTypeNode) + , nodesVisitor((node).decorators, visitor, isDecorator) + , nodesVisitor((node).modifiers, visitor, isModifier)); case SyntaxKind.Parameter: return updateParameter(node, diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index d7638ffc03..08370480aa 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1673,7 +1673,7 @@ namespace FourSlash { // 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. Assumption is that these edit ranges don't overlap let runningOffset = 0; - edits = edits.sort((a, b) => a.span.start - b.span.start); + edits = ts.stableSort(edits, (a, b) => a.span.start - b.span.start); // 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); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceComments.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceComments.ts new file mode 100644 index 0000000000..56d56a5a50 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceComments.ts @@ -0,0 +1,14 @@ +/// + +// @lib: es2017 + +//// /** interface prefix */ +//// interface /**interface name prefix */ I /**open-brace prefix*/{ +//// /** property prefix*/ x /**colon prefix*/: /**number prefix*/ number; +//// +//// /**close-brace prefix*/ } +//// class C implements I {[| |]} + +verify.rangeAfterCodeFix(` + x: number; +`); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyNameWellKnownSymbols.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyNameWellKnownSymbols.ts index 61b4267e7f..31fc167bb9 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyNameWellKnownSymbols.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceComputedPropertyNameWellKnownSymbols.ts @@ -17,7 +17,6 @@ //// [Symbol.toStringTag]: string; //// [Symbol.unscopables]: any; //// } -//// //// class C implements I {[| |]} verify.rangeAfterCodeFix(` diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceEmptyTypeLiteral.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceEmptyTypeLiteral.ts new file mode 100644 index 0000000000..9805901709 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceEmptyTypeLiteral.ts @@ -0,0 +1,13 @@ +/// + +//// interface I { +//// x: {}; +//// } +//// +//// class C implements I {[| +//// |]constructor() { } +//// } + +verify.rangeAfterCodeFix(` +x: {}; +`); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceMemberOrdering.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceMemberOrdering.ts new file mode 100644 index 0000000000..dbfd623be1 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceMemberOrdering.ts @@ -0,0 +1,58 @@ +/// + +// @lib: es2017 + +//// /** asdf */ +//// interface I { +//// 1; +//// 2; +//// 3; +//// 4; +//// 5; +//// 6; +//// 7; +//// 8; +//// 9; +//// 10; +//// 11; +//// 12; +//// 13; +//// 14; +//// 15; +//// 16; +//// 17; +//// 18; +//// 19; +//// 20; +//// 21; +//// 22; +//// /** a nice safe prime */ +//// 23; +//// } +//// class C implements I {[| |]} + +verify.rangeAfterCodeFix(` + 1: any; + 2: any; + 3: any; + 4: any; + 5: any; + 6: any; + 7: any; + 8: any; + 9: any; + 10: any; + 11: any; + 12: any; + 13: any; + 14: any; + 15: any; + 16: any; + 17: any; + 18: any; + 19: any; + 20: any; + 21: any; + 22: any; + 23: any; +`); From d78e5a1db52a2ec72724461a600ea07ab57191e6 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 15 Mar 2017 18:39:44 -0700 Subject: [PATCH 088/164] Normalize line endings when validating baselines --- src/harness/unittests/initializeTSConfig.ts | 5 +- .../tsconfig.json | 102 ++++++++-------- .../tsconfig.json | 102 ++++++++-------- .../tsconfig.json | 102 ++++++++-------- .../tsconfig.json | 112 +++++++++--------- .../tsconfig.json | 102 ++++++++-------- .../tsconfig.json | 102 ++++++++-------- .../tsconfig.json | 102 ++++++++-------- .../tsconfig.json | 102 ++++++++-------- 9 files changed, 416 insertions(+), 415 deletions(-) diff --git a/src/harness/unittests/initializeTSConfig.ts b/src/harness/unittests/initializeTSConfig.ts index 7163ab3e34..4f193d358f 100644 --- a/src/harness/unittests/initializeTSConfig.ts +++ b/src/harness/unittests/initializeTSConfig.ts @@ -1,4 +1,4 @@ -/// +/// /// namespace ts { @@ -12,7 +12,8 @@ namespace ts { it(`Correct output for ${outputFileName}`, () => { Harness.Baseline.runBaseline(outputFileName, () => { if (initResult) { - return initResult; + // normalize line endings + return initResult.replace(new RegExp(sys.newLine, "g"), "\n"); } else { // This can happen if compiler recieve invalid compiler-options diff --git a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json index 13e3bdb0f4..f26b471d2c 100644 --- a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json @@ -1,52 +1,52 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ - // "allowJs": true, /* Allow javascript files to be compiled. */ - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - // "declaration": true, /* Generates corresponding '.d.ts' file. */ - // "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - // "outDir": "./", /* Redirect output structure to the directory. */ - // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ - // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ - - /* Strict Type Checks */ - "strict": true /* Enable all strict type checks. */ - // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* Enable strict null checks. */ - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - - /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - // "types": [], /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - - /* SourceMap Options */ - // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - } +{ + "compilerOptions": { + /* Basic Options */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ + // "lib": [], /* Specify library files to be included in the compilation: */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ + // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + + /* Strict Type Checks */ + "strict": true /* Enable all strict type checks. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + + /* SourceMap Options */ + // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + } } \ No newline at end of file diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json index 39dd00c200..2dc7f0564b 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json @@ -1,52 +1,52 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ - // "allowJs": true, /* Allow javascript files to be compiled. */ - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - // "declaration": true, /* Generates corresponding '.d.ts' file. */ - // "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - // "outDir": "./", /* Redirect output structure to the directory. */ - // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ - // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ - - /* Strict Type Checks */ - "strict": true, /* Enable all strict type checks. */ - // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* Enable strict null checks. */ - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - - /* Additional Checks */ - "noUnusedLocals": true /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - - /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - // "types": [], /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - - /* SourceMap Options */ - // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - } +{ + "compilerOptions": { + /* Basic Options */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ + // "lib": [], /* Specify library files to be included in the compilation: */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ + // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + + /* Strict Type Checks */ + "strict": true, /* Enable all strict type checks. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + "noUnusedLocals": true /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + + /* SourceMap Options */ + // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + } } \ No newline at end of file diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json index 401ae3185f..48a7fd7784 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json @@ -1,52 +1,52 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ - // "allowJs": true, /* Allow javascript files to be compiled. */ - "jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - // "declaration": true, /* Generates corresponding '.d.ts' file. */ - // "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - // "outDir": "./", /* Redirect output structure to the directory. */ - // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ - // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ - - /* Strict Type Checks */ - "strict": true /* Enable all strict type checks. */ - // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* Enable strict null checks. */ - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - - /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - // "types": [], /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - - /* SourceMap Options */ - // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - } +{ + "compilerOptions": { + /* Basic Options */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ + // "lib": [], /* Specify library files to be included in the compilation: */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + "jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ + // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + + /* Strict Type Checks */ + "strict": true /* Enable all strict type checks. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + + /* SourceMap Options */ + // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + } } \ No newline at end of file diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json index 9e99149547..a2f4e6bd99 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json @@ -1,57 +1,57 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ - // "allowJs": true, /* Allow javascript files to be compiled. */ - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - // "declaration": true, /* Generates corresponding '.d.ts' file. */ - // "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - // "outDir": "./", /* Redirect output structure to the directory. */ - // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ - // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ - - /* Strict Type Checks */ - "strict": true /* Enable all strict type checks. */ - // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* Enable strict null checks. */ - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - - /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - // "types": [], /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - - /* SourceMap Options */ - // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - }, - "files": [ - "file0.st", - "file1.ts", - "file2.ts" - ] +{ + "compilerOptions": { + /* Basic Options */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ + // "lib": [], /* Specify library files to be included in the compilation: */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ + // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + + /* Strict Type Checks */ + "strict": true /* Enable all strict type checks. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + + /* SourceMap Options */ + // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + }, + "files": [ + "file0.st", + "file1.ts", + "file2.ts" + ] } \ No newline at end of file diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json index 976f8c984e..62bfc7ca26 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json @@ -1,52 +1,52 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ - "lib": ["es5","es2015.promise"], /* Specify library files to be included in the compilation: */ - // "allowJs": true, /* Allow javascript files to be compiled. */ - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - // "declaration": true, /* Generates corresponding '.d.ts' file. */ - // "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - // "outDir": "./", /* Redirect output structure to the directory. */ - // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ - // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ - - /* Strict Type Checks */ - "strict": true /* Enable all strict type checks. */ - // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* Enable strict null checks. */ - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - - /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - // "types": [], /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - - /* SourceMap Options */ - // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - } +{ + "compilerOptions": { + /* Basic Options */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ + "lib": ["es5","es2015.promise"], /* Specify library files to be included in the compilation: */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ + // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + + /* Strict Type Checks */ + "strict": true /* Enable all strict type checks. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + + /* SourceMap Options */ + // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + } } \ No newline at end of file diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json index 13e3bdb0f4..f26b471d2c 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json @@ -1,52 +1,52 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ - // "allowJs": true, /* Allow javascript files to be compiled. */ - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - // "declaration": true, /* Generates corresponding '.d.ts' file. */ - // "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - // "outDir": "./", /* Redirect output structure to the directory. */ - // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ - // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ - - /* Strict Type Checks */ - "strict": true /* Enable all strict type checks. */ - // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* Enable strict null checks. */ - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - - /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - // "types": [], /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - - /* SourceMap Options */ - // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - } +{ + "compilerOptions": { + /* Basic Options */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ + // "lib": [], /* Specify library files to be included in the compilation: */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ + // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + + /* Strict Type Checks */ + "strict": true /* Enable all strict type checks. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + + /* SourceMap Options */ + // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + } } \ No newline at end of file diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json index f4bc1dc9ef..02a1724add 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json @@ -1,52 +1,52 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ - "lib": ["es5","es2015.core"], /* Specify library files to be included in the compilation: */ - // "allowJs": true, /* Allow javascript files to be compiled. */ - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - // "declaration": true, /* Generates corresponding '.d.ts' file. */ - // "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - // "outDir": "./", /* Redirect output structure to the directory. */ - // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ - // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ - - /* Strict Type Checks */ - "strict": true /* Enable all strict type checks. */ - // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* Enable strict null checks. */ - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - - /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - // "types": [], /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - - /* SourceMap Options */ - // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - } +{ + "compilerOptions": { + /* Basic Options */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ + "lib": ["es5","es2015.core"], /* Specify library files to be included in the compilation: */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ + // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + + /* Strict Type Checks */ + "strict": true /* Enable all strict type checks. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + + /* SourceMap Options */ + // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + } } \ No newline at end of file diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json index 434e886b25..b1e048551d 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json @@ -1,52 +1,52 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ - // "allowJs": true, /* Allow javascript files to be compiled. */ - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - // "declaration": true, /* Generates corresponding '.d.ts' file. */ - // "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - // "outDir": "./", /* Redirect output structure to the directory. */ - // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ - // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ - - /* Strict Type Checks */ - "strict": true, /* Enable all strict type checks. */ - // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* Enable strict null checks. */ - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - - /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - "types": ["jquery","mocha"] /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - - /* SourceMap Options */ - // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - } +{ + "compilerOptions": { + /* Basic Options */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ + // "lib": [], /* Specify library files to be included in the compilation: */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ + // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + + /* Strict Type Checks */ + "strict": true, /* Enable all strict type checks. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + "types": ["jquery","mocha"] /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + + /* SourceMap Options */ + // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + } } \ No newline at end of file From ec997f329914663b16948eaa06fe1a3ba99f910c Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Thu, 16 Mar 2017 09:52:19 -0700 Subject: [PATCH 089/164] more temp --- src/compiler/checker.ts | 233 +++++++++++++++++- src/compiler/factory.ts | 72 ++++-- src/compiler/visitor.ts | 10 +- ...FixClassImplementInterfaceCallSignature.ts | 10 + ...assImplementInterfaceConstructSignature.ts | 10 + ...ImplementInterfacePropertyCallSignature.ts | 13 + ...ntInterfacePropertyConstructSignature.1.ts | 12 + ...plementInterfacePropertyMethodSignature.ts | 11 + 8 files changed, 340 insertions(+), 31 deletions(-) create mode 100644 tests/cases/fourslash/codeFixClassImplementInterfaceCallSignature.ts create mode 100644 tests/cases/fourslash/codeFixClassImplementInterfaceConstructSignature.ts create mode 100644 tests/cases/fourslash/codeFixClassImplementInterfacePropertyCallSignature.ts create mode 100644 tests/cases/fourslash/codeFixClassImplementInterfacePropertyConstructSignature.1.ts create mode 100644 tests/cases/fourslash/codeFixClassImplementInterfacePropertyMethodSignature.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 625f4d75eb..d650865ef7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2208,6 +2208,8 @@ namespace ts { let encounteredError = false; let inObjectTypeLiteral = false; let checkAlias = true; + let enclosingDeclaration: Node = undefined; // TODO: add parameter. + let symbolStack: Symbol[] = undefined; let result = createTypeNodeWorker(type); if (result) { @@ -2224,7 +2226,6 @@ namespace ts { const typeString = typeToString(type); typeString; // TODO: remove. - if (type.flags & TypeFlags.Any) { // TODO: add other case where type ends up being `any`. return createKeywordTypeNode(SyntaxKind.AnyKeyword); @@ -2239,7 +2240,7 @@ namespace ts { return createKeywordTypeNode(SyntaxKind.BooleanKeyword); } if (type.flags & TypeFlags.Enum) { - throw new Error("enum not implemented"); + throw new Error ("enums not implemented") } if (type.flags & (TypeFlags.StringLiteral)) { return createLiteralTypeNode((createLiteral((type).text))); @@ -2316,6 +2317,7 @@ namespace ts { if (type.flags & TypeFlags.Union) { return createUnionOrIntersectionTypeNode(SyntaxKind.UnionType, mapToTypeNodeArray(formatUnionTypes((type).types))); } + if (type.flags & TypeFlags.Intersection) { return createUnionOrIntersectionTypeNode(SyntaxKind.IntersectionType, mapToTypeNodeArray((type as UnionType).types)); } @@ -2336,7 +2338,7 @@ namespace ts { return createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode); } - if (objectFlags & ObjectFlags.Anonymous) { + if (objectFlags & (ObjectFlags.Anonymous | ObjectFlags.Mapped)) { Debug.assert(!!(type.flags & TypeFlags.Object)); // The type is an object literal type. if (!type.symbol) { @@ -2346,18 +2348,20 @@ namespace ts { noop(); } - return createTypeLiteralNodeFromType(type); + return createAnonymousTypeNode(type); } - // TODO: string or number literal here or above? - if (type.flags & TypeFlags.Index) { - // TODO: implement and test. - throw new Error("index not implemented"); + // TODO: test. + const indexType = getIndexType(getApparentType((type).type)); + const indexTypeNode = createTypeNodeWorker(indexType); + return createTypeOperatorNode(indexTypeNode); } if (type.flags & TypeFlags.IndexedAccess) { - // TODO: implement and test. - throw new Error("indexed access not implemented"); + // TODO: test. + const objectTypeNode = createTypeNodeWorker((type).objectType); + const indexTypeNode = createTypeNodeWorker((type).indexType); + return createIndexedAccessTypeNode(objectTypeNode, indexTypeNode); } Debug.fail("Should be unreachable."); @@ -2367,6 +2371,214 @@ namespace ts { return asNodeArray(types && types.map(createTypeNodeWorker) as TypeNode[]); } + /******** START COPY *********/ + + // function buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]) { + // const globalFlagsToPass = globalFlags & TypeFormatFlags.WriteOwnNameForAnyLike; + // let inObjectTypeLiteral = false; + // return writeType(type, globalFlags); + + // function writeType(type: Type, flags: TypeFormatFlags) { + // // const nextFlags = flags & ~TypeFormatFlags.InTypeAlias; + // // // Write undefined/null type as any + // // if (type.flags & TypeFlags.Intrinsic) { + // // // Special handling for unknown / resolving types, they should show up as any and not unknown or __resolving + // // writer.writeKeyword(!(globalFlags & TypeFormatFlags.WriteOwnNameForAnyLike) && isTypeAny(type) + // // ? "any" + // // : (type).intrinsicName); + // // } + // // else if (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType) { + // // if (inObjectTypeLiteral) { + // // writer.reportInaccessibleThisError(); + // // } + // // writer.writeKeyword("this"); + // // } + // else if (getObjectFlags(type) & ObjectFlags.Reference) { + // writeTypeReference(type, nextFlags); + // } + // else if (type.flags & TypeFlags.EnumLiteral) { + // buildSymbolDisplay(getParentOfSymbol(type.symbol), writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags); + // writePunctuation(writer, SyntaxKind.DotToken); + // appendSymbolNameOnly(type.symbol, writer); + // } + // else if (getObjectFlags(type) & ObjectFlags.ClassOrInterface || type.flags & (TypeFlags.Enum | TypeFlags.TypeParameter)) { + // // The specified symbol flags need to be reinterpreted as type flags + // buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags); + // } + // else if (!(flags & TypeFormatFlags.InTypeAlias) && type.aliasSymbol && + // isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) { + // const typeArguments = type.aliasTypeArguments; + // writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, length(typeArguments), nextFlags); + // } + // else if (type.flags & TypeFlags.UnionOrIntersection) { + // writeUnionOrIntersectionType(type, nextFlags); + // } + // else if (getObjectFlags(type) & (ObjectFlags.Anonymous | ObjectFlags.Mapped)) { + // writeAnonymousType(type, nextFlags); + // } + // else if (type.flags & TypeFlags.StringOrNumberLiteral) { + // writer.writeStringLiteral(literalTypeToString(type)); + // } + // } + + /******** END COPY *********/ + + function createAnonymousTypeNode(type: ObjectType): TypeNode { + const symbol = type.symbol; + if (symbol) { + // Always use 'typeof T' for type of class, enum, and module objects + if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) || + symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule) || + shouldWriteTypeOfFunctionSymbol()) { + // TODO: test. + // TODO: get entity name from symbol. + return createTypeQueryNodeFromType(type); + } + else if (contains(symbolStack, symbol)) { + // If type is an anonymous type literal in a type alias declaration, use type alias name + const typeAlias = getTypeAliasForTypeLiteral(type); + if (typeAlias) { + // The specified symbol flags need to be reinterpreted as type flags + const entityName = getEntityNameFromSymbol(typeAlias, enclosingDeclaration); + return createTypeReferenceNode(entityName, /*typeArguments*/ undefined); + } + else { + return createKeywordTypeNode(SyntaxKind.AnyKeyword); + } + } + else { + // Since instantiations of the same anonymous type have the same symbol, tracking symbols instead + // of types allows us to catch circular references to instantiations of the same anonymous type + if (!symbolStack) { + symbolStack = []; + } + symbolStack.push(symbol); + let result = createTypeLiteralNodeFromType(type); + symbolStack.pop(); + return result; + } + } + else { + // Anonymous types with no symbol are never circular + return createTypeLiteralNodeFromType(type); + } + + function shouldWriteTypeOfFunctionSymbol() { + const isStaticMethodSymbol = !!(symbol.flags & SymbolFlags.Method && // typeof static method + forEach(symbol.declarations, declaration => getModifierFlags(declaration) & ModifierFlags.Static)); + const isNonLocalFunctionSymbol = !!(symbol.flags & SymbolFlags.Function) && + (symbol.parent || // is exported function symbol + forEach(symbol.declarations, declaration => + declaration.parent.kind === SyntaxKind.SourceFile || declaration.parent.kind === SyntaxKind.ModuleBlock)); + if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { + // typeof is allowed only for static/non local functions + return contains(symbolStack, symbol); // it is type of the symbol uses itself recursively + } + } + } + + function writeLiteralType(type: ObjectType, flags: TypeFormatFlags) { + if (type.objectFlags & ObjectFlags.Mapped) { + if (getConstraintTypeFromMappedType(type).flags & (TypeFlags.TypeParameter | TypeFlags.Index)) { + writeMappedType(type); + return; + } + } + + const resolved = resolveStructuredTypeMembers(type); + if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { + if (!resolved.callSignatures.length && !resolved.constructSignatures.length) { + writePunctuation(writer, SyntaxKind.OpenBraceToken); + writePunctuation(writer, SyntaxKind.CloseBraceToken); + return; + } + + if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) { + const parenthesizeSignature = shouldAddParenthesisAroundFunctionType(resolved.callSignatures[0], flags); + if (parenthesizeSignature) { + writePunctuation(writer, SyntaxKind.OpenParenToken); + } + buildSignatureDisplay(resolved.callSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | TypeFormatFlags.WriteArrowStyleSignature, /*kind*/ undefined, symbolStack); + if (parenthesizeSignature) { + writePunctuation(writer, SyntaxKind.CloseParenToken); + } + return; + } + if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) { + if (flags & TypeFormatFlags.InElementType) { + writePunctuation(writer, SyntaxKind.OpenParenToken); + } + writeKeyword(writer, SyntaxKind.NewKeyword); + writeSpace(writer); + buildSignatureDisplay(resolved.constructSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | TypeFormatFlags.WriteArrowStyleSignature, /*kind*/ undefined, symbolStack); + if (flags & TypeFormatFlags.InElementType) { + writePunctuation(writer, SyntaxKind.CloseParenToken); + } + return; + } + } + + const saveInObjectTypeLiteral = inObjectTypeLiteral; + inObjectTypeLiteral = true; + writePunctuation(writer, SyntaxKind.OpenBraceToken); + writer.writeLine(); + writer.increaseIndent(); + writeObjectLiteralType(resolved); + writer.decreaseIndent(); + writePunctuation(writer, SyntaxKind.CloseBraceToken); + inObjectTypeLiteral = saveInObjectTypeLiteral; + } + + function writeObjectLiteralType(resolved: ResolvedType) { + for (const signature of resolved.callSignatures) { + buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, /*kind*/ undefined, symbolStack); + writePunctuation(writer, SyntaxKind.SemicolonToken); + writer.writeLine(); + } + for (const signature of resolved.constructSignatures) { + buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, SignatureKind.Construct, symbolStack); + writePunctuation(writer, SyntaxKind.SemicolonToken); + writer.writeLine(); + } + buildIndexSignatureDisplay(resolved.stringIndexInfo, writer, IndexKind.String, enclosingDeclaration, globalFlags, symbolStack); + buildIndexSignatureDisplay(resolved.numberIndexInfo, writer, IndexKind.Number, enclosingDeclaration, globalFlags, symbolStack); + for (const p of resolved.properties) { + const t = getTypeOfSymbol(p); + if (p.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(t).length) { + const signatures = getSignaturesOfType(t, SignatureKind.Call); + for (const signature of signatures) { + writePropertyWithModifiers(p); + buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, /*kind*/ undefined, symbolStack); + writePunctuation(writer, SyntaxKind.SemicolonToken); + writer.writeLine(); + } + } + else { + writePropertyWithModifiers(p); + writePunctuation(writer, SyntaxKind.ColonToken); + writeSpace(writer); + writeType(t, TypeFormatFlags.None); + writePunctuation(writer, SyntaxKind.SemicolonToken); + writer.writeLine(); + } + } + } + + function createTypeQueryNodeFromType(type: Type) { + const symbol = type.symbol; + if (symbol) { + // TODO: get entity name instead. + const entityName = createIdentifier(symbolToString(symbol)); + return createTypeQueryNode(entityName); + } + } + + function getEntityNameFromSymbol(symbol: Symbol, enclosingDeclaration: Node): EntityName { + symbol; enclosingDeclaration; + // TODO: actually implement this + return createIdentifier(symbolToString(symbol, enclosingDeclaration)); + } + function createTypeReferenceNodeFromType(type: TypeReference) { const typeArguments: Type[] = type.typeArguments || emptyArray; if (type.target === globalArrayType) { @@ -2778,6 +2990,7 @@ namespace ts { } } + function writeTypeList(types: Type[], delimiter: SyntaxKind) { for (let i = 0; i < types.length; i++) { if (i > 0) { diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index c9fef5b026..ebb4bbe5a9 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -255,25 +255,8 @@ namespace ts { : node; } - export function createSignatureDeclaration(kind: SyntaxKind, name: string | PropertyName | undefined, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): T { - const signatureDeclaration = createSynthesizedNode(kind) as T; - signatureDeclaration.name = asName(name); - signatureDeclaration.typeParameters = asNodeArray(typeParameters); - signatureDeclaration.type = type; - return signatureDeclaration; - } - - export function updateSignatureDeclaration(node: T, name: string | PropertyName | undefined, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): T { - return node.name !== name - || node.typeParameters !== typeParameters - || node.type !== type - ? updateNode(createSignatureDeclaration(node.kind, name, typeParameters, parameters, type), node) - : node; - } - export function createTypeReferenceNode(typeName: string | EntityName, typeArguments: NodeArray | undefined) { const typeReference = createSynthesizedNode(SyntaxKind.TypeReference) as TypeReferenceNode; - typeReference.typeName = isQualifiedName(typeName) ? typeName : asName(typeName); typeReference.typeArguments = typeArguments; return typeReference; @@ -286,6 +269,16 @@ namespace ts { : node; } + export function createTypeQueryNode(exprName: EntityName) { + const typeQueryNode = createSynthesizedNode(SyntaxKind.TypeQuery) as TypeQueryNode; + typeQueryNode.exprName = exprName; + return typeQueryNode; + } + + export function updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName) { + return node.exprName !== exprName ? updateNode(createTypeQueryNode(exprName) , node) : node; + } + export function createArrayTypeNode(elementType: TypeNode): ArrayTypeNode { const arrayTypeNode = createSynthesizedNode(SyntaxKind.ArrayType) as ArrayTypeNode; arrayTypeNode.elementType = elementType; @@ -355,6 +348,33 @@ namespace ts { : node; } + export function createTypeOperatorNode(type: TypeNode) { + const typeOperatorNode = createSynthesizedNode(SyntaxKind.TypeOperator) as TypeOperatorNode; + typeOperatorNode.operator = SyntaxKind.KeyOfKeyword; + typeOperatorNode.type = type + return typeOperatorNode; + } + + export function updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode) { + return node.type !== type ? updateNode(createTypeOperatorNode(type), node) : node; + } + + export function createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode) { + const indexedAccessTypeNode = createSynthesizedNode(SyntaxKind.IndexedAccessType) as IndexedAccessTypeNode; + indexedAccessTypeNode.objectType = objectType; + indexedAccessTypeNode.indexType = indexType; + return indexedAccessTypeNode; + } + + + export function updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) { + return node.objectType !== objectType + || node.indexType !== indexType + ? updateNode(createIndexedAccessTypeNode(objectType, indexType), node) + : node; + } + + // Type Declarations export function createTypeParameterDeclaration(name: string | Identifier, constraint: TypeNode | undefined, defaultParameter: TypeNode | undefined) { @@ -374,6 +394,24 @@ namespace ts { : node; } + export function createSignatureDeclaration(kind: SyntaxKind, name: string | PropertyName | undefined, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): T { + const signatureDeclaration = createSynthesizedNode(kind) as T; + signatureDeclaration.name = asName(name); + signatureDeclaration.typeParameters = asNodeArray(typeParameters); + signatureDeclaration.parameters = asNodeArray(parameters); + signatureDeclaration.type = type; + return signatureDeclaration; + } + + export function updateSignatureDeclaration(node: T, name: string | PropertyName | undefined, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): T { + return node.name !== name + || node.typeParameters !== typeParameters + || node.parameters !== parameters + || node.type !== type + ? updateNode(createSignatureDeclaration(node.kind, name, typeParameters, parameters, type), node) + : node; + } + // Signature elements export function createPropertySignature(name: PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertySignature { diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 206e269f36..afe236859a 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -320,13 +320,13 @@ namespace ts { case SyntaxKind.ConstructorType: throw new Error("reached unsupported type in visitor."); case SyntaxKind.TypeQuery: - throw new Error("reached unsupported type in visitor."); + return updateTypeQueryNode((node), visitNode((node).exprName, visitor, isEntityName)); case SyntaxKind.TypeLiteral: return updateTypeLiteralNode((node), nodesVisitor((node).members, visitor)); case SyntaxKind.ArrayType: return updateArrayTypeNode(node, visitNode((node).elementType, visitor, isTypeNode)); case SyntaxKind.TupleType: - throw new Error("reached unsupported type in visitor."); + return updateTypleTypeNode((node), nodesVisitor((node).elementTypes, visitor, isTypeNode)); case SyntaxKind.UnionType: case SyntaxKind.IntersectionType: return updateUnionOrIntersectionTypeNode(node @@ -336,9 +336,11 @@ namespace ts { case SyntaxKind.ThisType: throw new Error("reached unsupported type in visitor."); case SyntaxKind.TypeOperator: - throw new Error("reached unsupported type in visitor."); + return updateTypeOperatorNode(node, visitNode((node).type, visitor, isTypeNode)); case SyntaxKind.IndexedAccessType: - throw new Error("reached unsupported type in visitor."); + return updateIndexedAccessTypeNode((node) + , visitNode((node).objectType, visitor, isTypeNode) + , visitNode((node).indexType, visitor, isTypeNode)); case SyntaxKind.MappedType: throw new Error("reached unsupported type in visitor."); case SyntaxKind.LiteralType: diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceCallSignature.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceCallSignature.ts new file mode 100644 index 0000000000..4b47268396 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceCallSignature.ts @@ -0,0 +1,10 @@ +/// + +//// interface I { +//// (x: number, b: string): number; +//// } +//// class C implements I {[| |]} + +verify.not.codeFixAvailable(); + + diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceConstructSignature.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceConstructSignature.ts new file mode 100644 index 0000000000..1700f7ec88 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceConstructSignature.ts @@ -0,0 +1,10 @@ +/// + +//// interface I { +//// new (x: number, b: string); +//// } +//// class C implements I {[| |]} + +verify.not.codeFixAvailable(); + + diff --git a/tests/cases/fourslash/codeFixClassImplementInterfacePropertyCallSignature.ts b/tests/cases/fourslash/codeFixClassImplementInterfacePropertyCallSignature.ts new file mode 100644 index 0000000000..7f0eddfb14 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterfacePropertyCallSignature.ts @@ -0,0 +1,13 @@ +/// + +//// interface I { +//// a1: { (b1: number, c1: string): number; }; +//// a2: (b2: number, c2: string) => number; +//// } +//// class C implements I {[| |]} + +verify.rangeAfterCodeFix(` + a1: (b1: number, c1: string) => number; + a2: (b2: number, c2: string) => number; +`); + diff --git a/tests/cases/fourslash/codeFixClassImplementInterfacePropertyConstructSignature.1.ts b/tests/cases/fourslash/codeFixClassImplementInterfacePropertyConstructSignature.1.ts new file mode 100644 index 0000000000..2b27fab376 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterfacePropertyConstructSignature.1.ts @@ -0,0 +1,12 @@ +/// + +//// interface I { +//// a1: { new (b1: number, c1: string): number; }; +//// a2: new (b2: number, c2: string) => number; +//// } +//// class C implements I {[| |]} + +verify.rangeAfterCodeFix(` + a1: new (b1: number, c1: string) => number; + a2: new (b2: number, c2: string) => number; +`); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfacePropertyMethodSignature.ts b/tests/cases/fourslash/codeFixClassImplementInterfacePropertyMethodSignature.ts new file mode 100644 index 0000000000..3d3505e1d6 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterfacePropertyMethodSignature.ts @@ -0,0 +1,11 @@ +/// + +//// interface I { +//// x: { a(b: number, c: string): number }; +//// } +//// class C implements I {[| |]} + +verify.rangeAfterCodeFix(` + a: { (b: number, c: string): number; }; +`); + From 451b2d648fcc1f36fccf0c604c8f20f893f23dc9 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Thu, 16 Mar 2017 16:09:54 -0700 Subject: [PATCH 090/164] Add signatures test --- ...ImplementInterfacePropertyCallSignature.ts | 13 ------- ...ntInterfacePropertyConstructSignature.1.ts | 12 ------- ...plementInterfacePropertyMethodSignature.ts | 11 ------ ...assImplementInterfacePropertySignatures.ts | 34 +++++++++++++++++++ 4 files changed, 34 insertions(+), 36 deletions(-) delete mode 100644 tests/cases/fourslash/codeFixClassImplementInterfacePropertyCallSignature.ts delete mode 100644 tests/cases/fourslash/codeFixClassImplementInterfacePropertyConstructSignature.1.ts delete mode 100644 tests/cases/fourslash/codeFixClassImplementInterfacePropertyMethodSignature.ts create mode 100644 tests/cases/fourslash/codeFixClassImplementInterfacePropertySignatures.ts diff --git a/tests/cases/fourslash/codeFixClassImplementInterfacePropertyCallSignature.ts b/tests/cases/fourslash/codeFixClassImplementInterfacePropertyCallSignature.ts deleted file mode 100644 index 7f0eddfb14..0000000000 --- a/tests/cases/fourslash/codeFixClassImplementInterfacePropertyCallSignature.ts +++ /dev/null @@ -1,13 +0,0 @@ -/// - -//// interface I { -//// a1: { (b1: number, c1: string): number; }; -//// a2: (b2: number, c2: string) => number; -//// } -//// class C implements I {[| |]} - -verify.rangeAfterCodeFix(` - a1: (b1: number, c1: string) => number; - a2: (b2: number, c2: string) => number; -`); - diff --git a/tests/cases/fourslash/codeFixClassImplementInterfacePropertyConstructSignature.1.ts b/tests/cases/fourslash/codeFixClassImplementInterfacePropertyConstructSignature.1.ts deleted file mode 100644 index 2b27fab376..0000000000 --- a/tests/cases/fourslash/codeFixClassImplementInterfacePropertyConstructSignature.1.ts +++ /dev/null @@ -1,12 +0,0 @@ -/// - -//// interface I { -//// a1: { new (b1: number, c1: string): number; }; -//// a2: new (b2: number, c2: string) => number; -//// } -//// class C implements I {[| |]} - -verify.rangeAfterCodeFix(` - a1: new (b1: number, c1: string) => number; - a2: new (b2: number, c2: string) => number; -`); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfacePropertyMethodSignature.ts b/tests/cases/fourslash/codeFixClassImplementInterfacePropertyMethodSignature.ts deleted file mode 100644 index 3d3505e1d6..0000000000 --- a/tests/cases/fourslash/codeFixClassImplementInterfacePropertyMethodSignature.ts +++ /dev/null @@ -1,11 +0,0 @@ -/// - -//// interface I { -//// x: { a(b: number, c: string): number }; -//// } -//// class C implements I {[| |]} - -verify.rangeAfterCodeFix(` - a: { (b: number, c: string): number; }; -`); - diff --git a/tests/cases/fourslash/codeFixClassImplementInterfacePropertySignatures.ts b/tests/cases/fourslash/codeFixClassImplementInterfacePropertySignatures.ts new file mode 100644 index 0000000000..9438241005 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterfacePropertySignatures.ts @@ -0,0 +1,34 @@ +/// + +//// interface I { +//// a0: {}; +//// a1: { (b1: number, c1: string): number; }; +//// a2: (b2: number, c2: string) => number; +//// a3: { (b3: number, c3: string): number, x: number }; +//// +//// a4: { new (b1: number, c1: string): number; }; +//// a5: new (b2: number, c2: string) => number; +//// a6: { new (b3: number, c3: string): number, x: number }; +//// +//// a7: { foo(b7: number, c7: string): number }; +//// +//// a8: { (b81: number, c81: string): number, new (b82: number, c82: string): number; }; +//// +//// a9: { (b9: number, c9: string): number; [d9: number]: I }; +//// a10: { (b10: number, c10: string): number; [d10: string]: I }; +//// } +//// class C implements I {[| |]} + +verify.rangeAfterCodeFix(` + a0: {}; + a1: (b1: number, c1: string) => number; + a2: (b2: number, c2: string) => number; + a3: { (b3: number, c3: string): number; x: number; }; + a4: new (b1: number, c1: string) => number; + a5: new (b2: number, c2: string) => number; + a6: { new (b3: number, c3: string): number; x: number; }; + a7: { foo(b7: number, c7: string): number; }; + a8: { (b81: number, c81: string): number; new (b82: number, c82: string): number; }; + a9: { (b9: number, c9: string): number; [d9: number]: I; }; + a10: { (b10: number, c10: string): number; [d10: string]: I; }; +`); \ No newline at end of file From 0fa4f112a33a8f7fdc12b61e9e5a8418b9bf95eb Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Thu, 16 Mar 2017 16:41:26 -0700 Subject: [PATCH 091/164] signatures, parameter, literals, anyonymous types --- src/compiler/checker.ts | 283 +++++++++++------------------- src/compiler/factory.ts | 31 ++-- src/compiler/types.ts | 2 + src/compiler/visitor.ts | 56 +++--- src/services/codefixes/helpers.ts | 66 ++++--- 5 files changed, 181 insertions(+), 257 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d650865ef7..7545430717 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -109,6 +109,7 @@ namespace ts { createTypeNode, createTypeParameterDeclarationFromType, createIndexSignatureFromIndexInfo, + createParameterDeclarationFromSymbol, getSymbolsInScope: (location, meaning) => { location = getParseTreeNode(location); return location ? getSymbolsInScope(location, meaning) : []; @@ -2203,6 +2204,45 @@ namespace ts { return createTypeParameterDeclaration(name, constraint, defaultParameter); } + // TODO: enclosing declaration appears to be unused in getTypeOfSymbolAtLocation + function createParameterDeclarationFromSymbol(parameterSymbol: Symbol): ParameterDeclaration { + const parameterDeclaration = parameterSymbol.declarations[0] as ParameterDeclaration; + const parameterType = getTypeOfSymbol(parameterSymbol); + const parameterTypeNode = checker.createTypeNode(parameterType); + // TODO: clone binding names correctly. + // TODO: copy initialzer in a way that checks whether all symbols used in expression are accessible here, and qualify them appropriately. + const parameterNode = createParameter( + parameterDeclaration.decorators && parameterDeclaration.decorators.map(getSynthesizedDeepClone) + , parameterDeclaration.modifiers && parameterDeclaration.modifiers.map(getSynthesizedDeepClone) + , parameterDeclaration.dotDotDotToken && createToken(SyntaxKind.DotDotDotToken) + , getSynthesizedDeepClone(parameterDeclaration.name) + , parameterDeclaration.questionToken && createToken(SyntaxKind.QuestionToken) + , parameterTypeNode + , /*initializer*/ undefined); + return parameterNode; + } + + /* @internal */ + type SignatureParts = { + typeParameters: TypeParameterDeclaration[] | undefined; + parameters: ParameterDeclaration[]; + type: TypeNode; + } + + // TODO: expose this, remove copy from helper, possibly don't expose createParameter/TypeParameter? + function createSignatureParts(signature: Signature): SignatureParts { + return { + typeParameters: signature.typeParameters && signature.typeParameters.map(createTypeParameterDeclarationFromType), + parameters: signature.parameters.map(createParameterDeclarationFromSymbol), + type: createTypeNodeExceptAny(getReturnTypeOfSignature(signature)) + } + + function createTypeNodeExceptAny(type: Type): TypeNode | undefined { + const typeNode = createTypeNode(type); + return typeNode && typeNode.kind !== SyntaxKind.AnyKeyword ? typeNode : undefined; + } + } + function createTypeNode(type: Type): TypeNode { let undefinedArgumentIsError = true; let encounteredError = false; @@ -2322,22 +2362,6 @@ namespace ts { return createUnionOrIntersectionTypeNode(SyntaxKind.IntersectionType, mapToTypeNodeArray((type as UnionType).types)); } - if (objectFlags & ObjectFlags.Mapped) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - - // TODO: does typeParameter have the same constraint or do we need to overwrite it somehow? - const typeParameter = getTypeParameterFromMappedType(type); - // const constraintType = getConstraintTypeFromMappedType(type); - const typeParameterNode = createTypeParameterDeclarationFromType(typeParameter); - - const templateTypeNode = createTypeNode(getTemplateTypeFromMappedType(type)); - const readonlyToken = (type).declaration && (type).declaration.readonlyToken ? createToken(SyntaxKind.ReadonlyKeyword) : undefined; - const questionToken = (type).declaration && (type).declaration.questionToken ? createToken(SyntaxKind.QuestionToken) : undefined; - - // TODO: test. - return createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode); - } - if (objectFlags & (ObjectFlags.Anonymous | ObjectFlags.Mapped)) { Debug.assert(!!(type.flags & TypeFlags.Object)); // The type is an object literal type. @@ -2371,57 +2395,25 @@ namespace ts { return asNodeArray(types && types.map(createTypeNodeWorker) as TypeNode[]); } - /******** START COPY *********/ - - // function buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]) { - // const globalFlagsToPass = globalFlags & TypeFormatFlags.WriteOwnNameForAnyLike; - // let inObjectTypeLiteral = false; - // return writeType(type, globalFlags); - - // function writeType(type: Type, flags: TypeFormatFlags) { - // // const nextFlags = flags & ~TypeFormatFlags.InTypeAlias; - // // // Write undefined/null type as any - // // if (type.flags & TypeFlags.Intrinsic) { - // // // Special handling for unknown / resolving types, they should show up as any and not unknown or __resolving - // // writer.writeKeyword(!(globalFlags & TypeFormatFlags.WriteOwnNameForAnyLike) && isTypeAny(type) - // // ? "any" - // // : (type).intrinsicName); - // // } - // // else if (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType) { - // // if (inObjectTypeLiteral) { - // // writer.reportInaccessibleThisError(); - // // } - // // writer.writeKeyword("this"); - // // } - // else if (getObjectFlags(type) & ObjectFlags.Reference) { - // writeTypeReference(type, nextFlags); - // } - // else if (type.flags & TypeFlags.EnumLiteral) { - // buildSymbolDisplay(getParentOfSymbol(type.symbol), writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags); - // writePunctuation(writer, SyntaxKind.DotToken); - // appendSymbolNameOnly(type.symbol, writer); - // } - // else if (getObjectFlags(type) & ObjectFlags.ClassOrInterface || type.flags & (TypeFlags.Enum | TypeFlags.TypeParameter)) { - // // The specified symbol flags need to be reinterpreted as type flags - // buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags); - // } - // else if (!(flags & TypeFormatFlags.InTypeAlias) && type.aliasSymbol && - // isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) { - // const typeArguments = type.aliasTypeArguments; - // writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, length(typeArguments), nextFlags); - // } - // else if (type.flags & TypeFlags.UnionOrIntersection) { - // writeUnionOrIntersectionType(type, nextFlags); - // } - // else if (getObjectFlags(type) & (ObjectFlags.Anonymous | ObjectFlags.Mapped)) { - // writeAnonymousType(type, nextFlags); - // } + // TODO: implement when this is testable. // else if (type.flags & TypeFlags.StringOrNumberLiteral) { // writer.writeStringLiteral(literalTypeToString(type)); - // } - // } - /******** END COPY *********/ + function createMappedTypeNodeFromType(type: MappedType) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + + // TODO: does typeParameter have the same constraint or do we need to overwrite it somehow? + const typeParameter = getTypeParameterFromMappedType(type); + // const constraintType = getConstraintTypeFromMappedType(type); + const typeParameterNode = createTypeParameterDeclarationFromType(typeParameter); + + const templateTypeNode = createTypeNode(getTemplateTypeFromMappedType(type)); + const readonlyToken = (type).declaration && (type).declaration.readonlyToken ? createToken(SyntaxKind.ReadonlyKeyword) : undefined; + const questionToken = (type).declaration && (type).declaration.questionToken ? createToken(SyntaxKind.QuestionToken) : undefined; + + // TODO: test. + return createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode); + } function createAnonymousTypeNode(type: ObjectType): TypeNode { const symbol = type.symbol; @@ -2439,7 +2431,7 @@ namespace ts { const typeAlias = getTypeAliasForTypeLiteral(type); if (typeAlias) { // The specified symbol flags need to be reinterpreted as type flags - const entityName = getEntityNameFromSymbol(typeAlias, enclosingDeclaration); + const entityName = createNameFromSymbol(typeAlias, enclosingDeclaration); return createTypeReferenceNode(entityName, /*typeArguments*/ undefined); } else { @@ -2453,14 +2445,14 @@ namespace ts { symbolStack = []; } symbolStack.push(symbol); - let result = createTypeLiteralNodeFromType(type); + let result = createTypeNodeFromObjectType(type); symbolStack.pop(); return result; } } else { // Anonymous types with no symbol are never circular - return createTypeLiteralNodeFromType(type); + return createTypeNodeFromObjectType(type); } function shouldWriteTypeOfFunctionSymbol() { @@ -2477,103 +2469,48 @@ namespace ts { } } - function writeLiteralType(type: ObjectType, flags: TypeFormatFlags) { + function createTypeNodeFromObjectType(type: ObjectType): TypeNode { if (type.objectFlags & ObjectFlags.Mapped) { if (getConstraintTypeFromMappedType(type).flags & (TypeFlags.TypeParameter | TypeFlags.Index)) { - writeMappedType(type); - return; + return createMappedTypeNodeFromType(type); } } const resolved = resolveStructuredTypeMembers(type); if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { if (!resolved.callSignatures.length && !resolved.constructSignatures.length) { - writePunctuation(writer, SyntaxKind.OpenBraceToken); - writePunctuation(writer, SyntaxKind.CloseBraceToken); - return; + return createTypeLiteralNode(/*members*/ undefined); } if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) { - const parenthesizeSignature = shouldAddParenthesisAroundFunctionType(resolved.callSignatures[0], flags); - if (parenthesizeSignature) { - writePunctuation(writer, SyntaxKind.OpenParenToken); - } - buildSignatureDisplay(resolved.callSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | TypeFormatFlags.WriteArrowStyleSignature, /*kind*/ undefined, symbolStack); - if (parenthesizeSignature) { - writePunctuation(writer, SyntaxKind.CloseParenToken); - } - return; + const signature = resolved.callSignatures[0]; + const signatureParts = createSignatureParts(signature); + return createSignatureDeclaration(SyntaxKind.FunctionType, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type); } if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) { - if (flags & TypeFormatFlags.InElementType) { - writePunctuation(writer, SyntaxKind.OpenParenToken); - } - writeKeyword(writer, SyntaxKind.NewKeyword); - writeSpace(writer); - buildSignatureDisplay(resolved.constructSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | TypeFormatFlags.WriteArrowStyleSignature, /*kind*/ undefined, symbolStack); - if (flags & TypeFormatFlags.InElementType) { - writePunctuation(writer, SyntaxKind.CloseParenToken); - } - return; + const signature = resolved.constructSignatures[0]; + const signatureParts = createSignatureParts(signature); + return createSignatureDeclaration(SyntaxKind.ConstructorType, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type); } } const saveInObjectTypeLiteral = inObjectTypeLiteral; inObjectTypeLiteral = true; - writePunctuation(writer, SyntaxKind.OpenBraceToken); - writer.writeLine(); - writer.increaseIndent(); - writeObjectLiteralType(resolved); - writer.decreaseIndent(); - writePunctuation(writer, SyntaxKind.CloseBraceToken); + const members = createTypeNodesFromResolvedType(resolved); inObjectTypeLiteral = saveInObjectTypeLiteral; - } - - function writeObjectLiteralType(resolved: ResolvedType) { - for (const signature of resolved.callSignatures) { - buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, /*kind*/ undefined, symbolStack); - writePunctuation(writer, SyntaxKind.SemicolonToken); - writer.writeLine(); - } - for (const signature of resolved.constructSignatures) { - buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, SignatureKind.Construct, symbolStack); - writePunctuation(writer, SyntaxKind.SemicolonToken); - writer.writeLine(); - } - buildIndexSignatureDisplay(resolved.stringIndexInfo, writer, IndexKind.String, enclosingDeclaration, globalFlags, symbolStack); - buildIndexSignatureDisplay(resolved.numberIndexInfo, writer, IndexKind.Number, enclosingDeclaration, globalFlags, symbolStack); - for (const p of resolved.properties) { - const t = getTypeOfSymbol(p); - if (p.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(t).length) { - const signatures = getSignaturesOfType(t, SignatureKind.Call); - for (const signature of signatures) { - writePropertyWithModifiers(p); - buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, /*kind*/ undefined, symbolStack); - writePunctuation(writer, SyntaxKind.SemicolonToken); - writer.writeLine(); - } - } - else { - writePropertyWithModifiers(p); - writePunctuation(writer, SyntaxKind.ColonToken); - writeSpace(writer); - writeType(t, TypeFormatFlags.None); - writePunctuation(writer, SyntaxKind.SemicolonToken); - writer.writeLine(); - } - } + return createTypeLiteralNode(members); } function createTypeQueryNodeFromType(type: Type) { const symbol = type.symbol; if (symbol) { // TODO: get entity name instead. - const entityName = createIdentifier(symbolToString(symbol)); + const entityName = createNameFromSymbol(symbol); return createTypeQueryNode(entityName); } } - function getEntityNameFromSymbol(symbol: Symbol, enclosingDeclaration: Node): EntityName { + function createNameFromSymbol(symbol: Symbol): EntityName { symbol; enclosingDeclaration; // TODO: actually implement this return createIdentifier(symbolToString(symbol, enclosingDeclaration)); @@ -2636,67 +2573,53 @@ namespace ts { } } - function createTypeLiteralNodeFromType(type: ObjectType) { - const resolvedType = resolveStructuredTypeMembers(type); - const newMembers = createTypeNodesFromResolvedType(resolvedType); - return createTypeLiteralNode(newMembers); - } - function createTypeNodesFromResolvedType(resolvedType: ResolvedType): TypeElement[] { const typeElements: TypeElement[] = []; - for(const signature of resolvedType.callSignatures) { - signature; - throw new Error("call signatures not implemented"); + for (const signature of resolvedType.callSignatures) { + const signatureParts = createSignatureParts(signature); + typeElements.push(createSignatureDeclaration(SyntaxKind.CallSignature, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type)); } for (const signature of resolvedType.constructSignatures) { - signature; - throw new Error("Construct signatures not implemented"); + const signatureParts = createSignatureParts(signature); + typeElements.push(createSignatureDeclaration(SyntaxKind.ConstructSignature, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type)); } if (resolvedType.stringIndexInfo) { typeElements.push(createIndexSignatureFromIndexInfo(resolvedType.stringIndexInfo, IndexKind.String)); } if (resolvedType.numberIndexInfo) { - typeElements.push(createIndexSignatureFromIndexInfo(resolvedType.stringIndexInfo, IndexKind.Number)); + typeElements.push(createIndexSignatureFromIndexInfo(resolvedType.numberIndexInfo, IndexKind.Number)); } - const members = resolvedType.members; + const properties = resolvedType.properties; + if (!properties) { + return typeElements; + } - members.forEach(memberSymbol => { - const oldDeclaration = memberSymbol.declarations && memberSymbol.declarations[0] as TypeElement; + for (const propertySymbol of properties) { + const propertyType = getTypeOfSymbol(propertySymbol); + const oldDeclaration = propertySymbol.declarations && propertySymbol.declarations[0] as TypeElement; if (!oldDeclaration) { return; } - - const kind = oldDeclaration.kind; - const memberName = getSynthesizedDeepClone(oldDeclaration.name); - const memberType = getTypeOfSymbol(memberSymbol); - - switch (kind) { - case SyntaxKind.PropertySignature: - const optional = !!oldDeclaration.questionToken; - typeElements.push(createPropertySignature( - memberName - , optional ? createToken(SyntaxKind.QuestionToken) : undefined - , createTypeNode(memberType) - , /*initializer*/undefined)); - break; - case SyntaxKind.MethodSignature: - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - const signatureType = getSignaturesOfSymbol(memberSymbol); - signatureType - createSignatureDeclaration - throw new Error("signature problems."); - // name ?: PropertyName; - // typeParameters ?: NodeArray; - // parameters: NodeArray; - // type ?: TypeNode; - case SyntaxKind.IndexSignature: - throw new Error("type literal constituent not implemented."); - default: - throw new Error("Unknown resolved member kind."); + const propertyName = getSynthesizedDeepClone(oldDeclaration.name); + const optionalToken = propertySymbol.flags & SymbolFlags.Optional ? createToken(SyntaxKind.QuestionToken) : undefined;; + if (propertySymbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length) { + const signatures = getSignaturesOfType(propertyType, SignatureKind.Call); + for (const signature of signatures) { + const signatureParts = createSignatureParts(signature); + const methodDeclaration = createSignatureDeclaration(SyntaxKind.MethodSignature, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type, propertyName, optionalToken); + methodDeclaration.questionToken = optionalToken; + typeElements.push(methodDeclaration); + } } - }); + else { + typeElements.push(createPropertySignature( + propertyName + , optionalToken + , createTypeNode(propertyType) + , /*initializer*/undefined)); + } + } return typeElements.length ? typeElements : undefined; } } diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index ebb4bbe5a9..d91076dcde 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -394,29 +394,37 @@ namespace ts { : node; } - export function createSignatureDeclaration(kind: SyntaxKind, name: string | PropertyName | undefined, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): T { + // TODO: ask if we should have multiple implementations. Some T's can't have question token. + export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined): T; + export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined): T; + export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, name?: string | PropertyName, questionToken?: QuestionToken): T { const signatureDeclaration = createSynthesizedNode(kind) as T; - signatureDeclaration.name = asName(name); signatureDeclaration.typeParameters = asNodeArray(typeParameters); signatureDeclaration.parameters = asNodeArray(parameters); signatureDeclaration.type = type; + signatureDeclaration.name = asName(name); + signatureDeclaration.questionToken = questionToken; return signatureDeclaration; } - export function updateSignatureDeclaration(node: T, name: string | PropertyName | undefined, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): T { - return node.name !== name - || node.typeParameters !== typeParameters + // TODO: figure out right type annotation for this function. + export function updateSignatureDeclaration(node: T, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): T; + export function updateSignatureDeclaration(node: T, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined, name: PropertyName, questionToken: QuestionToken | undefined): T; + export function updateSignatureDeclaration(node: T, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined, name?: PropertyName, questionToken?: QuestionToken): T { + return node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type - ? updateNode(createSignatureDeclaration(node.kind, name, typeParameters, parameters, type), node) + || node.name !== name + || node.questionToken !== questionToken + ? updateNode(createSignatureDeclaration(node.kind, typeParameters, parameters, type, name, questionToken), node) : node; } // Signature elements - export function createPropertySignature(name: PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertySignature { + export function createPropertySignature(name: PropertyName | string, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertySignature { const propertySignature = createSynthesizedNode(SyntaxKind.PropertySignature) as PropertySignature; - propertySignature.name = name; + propertySignature.name = asName(name); propertySignature.questionToken = questionToken; propertySignature.type = type; propertySignature.initializer = initializer; @@ -511,12 +519,13 @@ namespace ts { : node; } - export function createMethod(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | PropertyName, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) { + export function createMethod(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) { const node = createSynthesizedNode(SyntaxKind.MethodDeclaration); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); node.asteriskToken = asteriskToken; node.name = asName(name); + node.questionToken = questionToken; node.typeParameters = asNodeArray(typeParameters); node.parameters = asNodeArray(parameters); node.type = type; @@ -524,7 +533,7 @@ namespace ts { return node; } - export function updateMethod(node: MethodDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: PropertyName, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) { + export function updateMethod(node: MethodDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: PropertyName, questionToken: QuestionToken | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.asteriskToken !== asteriskToken @@ -533,7 +542,7 @@ namespace ts { || node.parameters !== parameters || node.type !== type || node.body !== body - ? updateNode(createMethod(decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body), node) + ? updateNode(createMethod(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body), node) : node; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 7f6c56aa1f..acca1b7398 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2474,6 +2474,8 @@ namespace ts { createTypeParameterDeclarationFromType(type: Type): TypeParameterDeclaration; /** Note that the resulting type node cannot be checked. */ createIndexSignatureFromIndexInfo(indexInfo: IndexInfo, kind: IndexKind): IndexSignatureDeclaration + /** Note that the resulting type node cannot be checked. */ + createParameterDeclarationFromSymbol(parameterSymbol: Symbol): ParameterDeclaration; getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; getSymbolAtLocation(node: Node): Symbol; diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index afe236859a..5d63126ad0 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -245,6 +245,8 @@ namespace ts { case SyntaxKind.EmptyStatement: case SyntaxKind.OmittedExpression: case SyntaxKind.DebuggerStatement: + case SyntaxKind.EndOfDeclarationMarker: + case SyntaxKind.MissingDeclaration: // No need to visit nodes with no children. return node; @@ -260,18 +262,25 @@ namespace ts { // Signatures and Signature Elements case SyntaxKind.FunctionType: + case SyntaxKind.ConstructorType: case SyntaxKind.CallSignature: case SyntaxKind.ConstructSignature: - case SyntaxKind.MethodSignature: return updateSignatureDeclaration(node - , visitNode((node).name, visitor, isPropertyName) , nodesVisitor((node).typeParameters, visitor, isTypeParameter) - , nodesVisitor((node).parameters, visitor, isParameter) + , visitParameterList((node).parameters, visitor, context, nodesVisitor) , visitNode((node).type, visitor, isTypeNode)); + case SyntaxKind.MethodSignature: + return updateSignatureDeclaration(node + , nodesVisitor((node).typeParameters, visitor, isTypeParameter) + , visitParameterList((node).parameters, visitor, context, nodesVisitor) + , visitNode((node).type, visitor, isTypeNode) + , visitNode((node).name, visitor, isPropertyName) + , visitNode((node).questionToken, visitor, isToken)); + case SyntaxKind.IndexSignature: return updateIndexSignatureDeclaration(node - , nodesVisitor((node).parameters, visitor) + , visitParameterList((node).parameters, visitor, context, nodesVisitor) , visitNode((node).type, visitor, isTypeNode) , nodesVisitor((node).decorators, visitor, isDecorator) , nodesVisitor((node).modifiers, visitor, isModifier)); @@ -290,47 +299,32 @@ namespace ts { return updateDecorator(node, visitNode((node).expression, visitor, isExpression)); - // Keyword Types and This - - case SyntaxKind.AnyKeyword: - case SyntaxKind.NumberKeyword: - case SyntaxKind.ObjectKeyword: - case SyntaxKind.BooleanKeyword: - case SyntaxKind.StringKeyword: - case SyntaxKind.SymbolKeyword: - case SyntaxKind.VoidKeyword: - case SyntaxKind.UndefinedKeyword: - case SyntaxKind.NullKeyword: - case SyntaxKind.NeverKeyword: - case SyntaxKind.NeverKeyword: - case SyntaxKind.ThisKeyword: - throw new Error("should be caught above"); - // Types case SyntaxKind.TypePredicate: throw new Error("reached unsupported type in visitor."); case SyntaxKind.TypeReference: return updateTypeReferenceNode(node - , visitNode((node).typeName, visitor, isEntityName) - , nodesVisitor((node).typeArguments, visitor, isTypeNode)); + , visitNode((node).typeName, visitor, isEntityName) + , nodesVisitor((node).typeArguments, visitor, isTypeNode)); - case SyntaxKind.FunctionType: - throw new Error("reached unsupported type in visitor."); - case SyntaxKind.ConstructorType: - throw new Error("reached unsupported type in visitor."); case SyntaxKind.TypeQuery: return updateTypeQueryNode((node), visitNode((node).exprName, visitor, isEntityName)); + case SyntaxKind.TypeLiteral: return updateTypeLiteralNode((node), nodesVisitor((node).members, visitor)); + case SyntaxKind.ArrayType: return updateArrayTypeNode(node, visitNode((node).elementType, visitor, isTypeNode)); + case SyntaxKind.TupleType: return updateTypleTypeNode((node), nodesVisitor((node).elementTypes, visitor, isTypeNode)); + case SyntaxKind.UnionType: case SyntaxKind.IntersectionType: return updateUnionOrIntersectionTypeNode(node - , nodesVisitor((node).types, visitor, isTypeNode)); + , nodesVisitor((node).types, visitor, isTypeNode)); + case SyntaxKind.ParenthesizedType: throw new Error("reached unsupported type in visitor."); case SyntaxKind.ThisType: @@ -366,7 +360,7 @@ namespace ts { case SyntaxKind.IndexSignature: return updateIndexSignatureDeclaration(node - , nodesVisitor((node).parameters, visitor, isParameter) + , visitParameterList((node).parameters, visitor, context, nodesVisitor) , visitNode((node).type, visitor, isTypeNode) , nodesVisitor((node).decorators, visitor, isDecorator) , nodesVisitor((node).modifiers, visitor, isModifier)); @@ -383,8 +377,9 @@ namespace ts { return updateMethod(node, nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), - (node).asteriskToken, + visitNode((node).asteriskToken, visitor, isToken), visitNode((node).name, visitor, isPropertyName), + visitNode((node).questionToken, visitor, isToken), nodesVisitor((node).typeParameters, visitor, isTypeParameter), visitParameterList((node).parameters, visitor, context, nodesVisitor), visitNode((node).type, visitor, isTypeNode), @@ -857,8 +852,7 @@ namespace ts { visitNode((node).expression, visitor, isExpression)); default: - throw new Error("not handled"); - // return node; + return node; } } diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 37ea8bab1a..e98235c3c8 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -85,56 +85,66 @@ namespace ts.codefix { if (!(signatures && signatures.length > 0)) { return undefined; } + + const optional = !!(symbol.flags & SymbolFlags.Optional); if (declarations.length === 1) { Debug.assert(signatures.length === 1); // TODO: suppress any return type // TODO: get parameters working. // TODO: add support for type parameters. const signature = signatures[0]; - const newTypeParameters = signature.typeParameters && signature.typeParameters.map(checker.createTypeParameterDeclarationFromType); - const newParameterNodes = signature.getParameters().map(symbol => createParameterDeclarationFromSymbol(symbol, enclosingDeclaration, checker)); - - const returnType = createTypeNodeExceptAny(checker.getReturnTypeOfSignature(signature), checker); - return createStubbedMethod(modifiers, name, newTypeParameters, newParameterNodes, returnType); + const signatureParts = getSignatureParts(signature); + return createStubbedMethod(modifiers, name, optional, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type); } let signatureDeclarations = []; for (let i = 0; i < signatures.length; i++) { // TODO: make signatures instead of methods const signature = signatures[i]; - const newTypeParameters = signature.typeParameters && signature.typeParameters.map(checker.createTypeParameterDeclarationFromType); - const newParameterNodes = signature.getParameters().map(symbol => createParameterDeclarationFromSymbol(symbol, enclosingDeclaration, checker)); - const returnType = createTypeNodeExceptAny(checker.getReturnTypeOfSignature(signature), checker); + const signatureParts = getSignatureParts(signature); signatureDeclarations.push(createMethod( /*decorators*/ undefined , modifiers , /*asteriskToken*/ undefined , name - , newTypeParameters - , newParameterNodes - , returnType + , optional ? createToken(SyntaxKind.QuestionToken) : undefined + , signatureParts.typeParameters + , signatureParts.parameters + , signatureParts.type , /*body*/undefined)); } if (declarations.length > signatures.length) { let signature = checker.getSignatureFromDeclaration(declarations[declarations.length - 1] as SignatureDeclaration); - const newTypeParameters = signature.typeParameters && signature.typeParameters.map(checker.createTypeParameterDeclarationFromType); - const newParameterNodes = signature.getParameters().map(symbol => createParameterDeclarationFromSymbol(symbol, enclosingDeclaration, checker)); - const returnType = createTypeNodeExceptAny(checker.getReturnTypeOfSignature(signature), checker); - signatureDeclarations.push(createStubbedMethod(modifiers, name, newTypeParameters, newParameterNodes, returnType)); + const signatureParts = getSignatureParts(signature); + signatureDeclarations.push(createStubbedMethod(modifiers, name, optional, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type)); } else { Debug.assert(declarations.length === signatures.length); - const methodImplementingSignatures = createMethodImplementingSignatures(signatures, name, modifiers); + const methodImplementingSignatures = createMethodImplementingSignatures(signatures, name, optional, modifiers); signatureDeclarations.push(methodImplementingSignatures); } return signatureDeclarations; default: return undefined; } + + type SignatureParts = { + typeParameters: TypeParameterDeclaration[]; + parameters: ParameterDeclaration[]; + type: TypeNode; + } + + function getSignatureParts(signature: Signature): SignatureParts { + return { + typeParameters: signature.typeParameters && signature.typeParameters.map(checker.createTypeParameterDeclarationFromType), + parameters: signature.getParameters().map(symbol => checker.createParameterDeclarationFromSymbol(symbol)), + type: createTypeNodeExceptAny(checker.getReturnTypeOfSignature(signature), checker) + } + } } - function createMethodImplementingSignatures(signatures: Signature[], name: PropertyName, modifiers: Modifier[] | undefined): MethodDeclaration { + function createMethodImplementingSignatures(signatures: Signature[], name: PropertyName, optional: boolean, modifiers: Modifier[] | undefined): MethodDeclaration { Debug.assert(signatures && signatures.length > 0); let maxArgsIndex = 0; @@ -153,7 +163,7 @@ namespace ts.codefix { maxArgsSignature = sig; } } - const maxNonRestArgs = maxArgsSignature.parameters.length - (maxArgsSignature.hasRestParameter ? 1 : 0); + const maxNonRestArgs = maxArgsSignature.parameters.length - (maxArgsSignature.hasRestParameter ? 1 : 0); const maxArgsParameterSymbolNames = signatures[maxArgsIndex].getParameters().map(symbol => symbol.getName()); const parameters: ParameterDeclaration[] = []; @@ -186,17 +196,19 @@ namespace ts.codefix { return createStubbedMethod( modifiers , name + , optional , /*typeParameters*/undefined , parameters , /*returnType*/ undefined); } - export function createStubbedMethod(modifiers: Modifier[], name: PropertyName, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], returnType: TypeNode | undefined) { + export function createStubbedMethod(modifiers: Modifier[], name: PropertyName, optional: boolean, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], returnType: TypeNode | undefined) { return createMethod( /*decorators*/undefined , modifiers , /*asteriskToken*/undefined , name + , optional ? createToken(SyntaxKind.QuestionToken) : undefined , typeParameters , parameters , returnType @@ -223,22 +235,6 @@ namespace ts.codefix { return undefined; } - function createParameterDeclarationFromSymbol(parameterSymbol: Symbol, enclosingDeclaration: ClassLikeDeclaration, checker: TypeChecker) { - const parameterDeclaration = parameterSymbol.getDeclarations()[0] as ParameterDeclaration; - const parameterType = checker.getTypeOfSymbolAtLocation(parameterSymbol, enclosingDeclaration); - const parameterTypeNode = checker.createTypeNode(parameterType); - // TODO: deep cloning of decorators/any node. - const parameterNode = createParameter( - parameterDeclaration.decorators && parameterDeclaration.decorators.map(getSynthesizedDeepClone) - , parameterDeclaration.modifiers && parameterDeclaration.modifiers.map(getSynthesizedDeepClone) - , parameterDeclaration.dotDotDotToken && createToken(SyntaxKind.DotDotDotToken) - , getSynthesizedDeepClone(parameterDeclaration.name) - , parameterDeclaration.questionToken && createToken(SyntaxKind.QuestionToken) - , parameterTypeNode - , /*initializer*/ undefined); - return parameterNode; - } - function createTypeNodeExceptAny(type: Type, checker: TypeChecker) { const typeNode = checker.createTypeNode(type); return typeNode && typeNode.kind !== SyntaxKind.AnyKeyword ? typeNode : undefined; From 69587a286afeebe2fa6456e1e8d99b214a3a26a1 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Thu, 16 Mar 2017 16:41:38 -0700 Subject: [PATCH 092/164] transformers tests --- src/compiler/transformers/es2017.ts | 1 + src/compiler/transformers/esnext.ts | 1 + src/compiler/transformers/ts.ts | 1 + 3 files changed, 3 insertions(+) diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 31aae5055a..9c7bcf5b2a 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -125,6 +125,7 @@ namespace ts { visitNodes(node.modifiers, visitor, isModifier), node.asteriskToken, node.name, + node.questionToken, /*typeParameters*/ undefined, visitParameterList(node.parameters, visitor, context), /*type*/ undefined, diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index f66bf14da5..2475e51119 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -541,6 +541,7 @@ namespace ts { ? undefined : node.asteriskToken, visitNode(node.name, visitor, isPropertyName), + visitNode(node.questionToken, visitor, isToken), /*typeParameters*/ undefined, visitParameterList(node.parameters, visitor, context), /*type*/ undefined, diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 885f8fad89..bbc588ee9f 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2049,6 +2049,7 @@ namespace ts { visitNodes(node.modifiers, modifierVisitor, isModifier), node.asteriskToken, visitPropertyNameOfClassElement(node), + node.questionToken, /*typeParameters*/ undefined, visitParameterList(node.parameters, visitor, context), /*type*/ undefined, From 41e511efd24dd0f2d143b99121ff0cc261478511 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Thu, 16 Mar 2017 16:51:18 -0700 Subject: [PATCH 093/164] fix call --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7545430717..294c499128 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2431,7 +2431,7 @@ namespace ts { const typeAlias = getTypeAliasForTypeLiteral(type); if (typeAlias) { // The specified symbol flags need to be reinterpreted as type flags - const entityName = createNameFromSymbol(typeAlias, enclosingDeclaration); + const entityName = createNameFromSymbol(typeAlias); return createTypeReferenceNode(entityName, /*typeArguments*/ undefined); } else { From a88be7c6f9c93b686562519ef59ecd413bdbcec3 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Thu, 16 Mar 2017 16:59:01 -0700 Subject: [PATCH 094/164] consolidate SignatureParts --- src/compiler/checker.ts | 10 +--------- src/compiler/types.ts | 18 +++++++++++------- src/services/codefixes/helpers.ts | 25 +++---------------------- 3 files changed, 15 insertions(+), 38 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 294c499128..4ccc8f84de 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -107,9 +107,8 @@ namespace ts { getReturnTypeOfSignature, getNonNullableType, createTypeNode, - createTypeParameterDeclarationFromType, createIndexSignatureFromIndexInfo, - createParameterDeclarationFromSymbol, + createSignatureParts, getSymbolsInScope: (location, meaning) => { location = getParseTreeNode(location); return location ? getSymbolsInScope(location, meaning) : []; @@ -2222,13 +2221,6 @@ namespace ts { return parameterNode; } - /* @internal */ - type SignatureParts = { - typeParameters: TypeParameterDeclaration[] | undefined; - parameters: ParameterDeclaration[]; - type: TypeNode; - } - // TODO: expose this, remove copy from helper, possibly don't expose createParameter/TypeParameter? function createSignatureParts(signature: Signature): SignatureParts { return { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index acca1b7398..679e11fa25 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2468,14 +2468,12 @@ namespace ts { /* @internal */ getParameterType(signature: Signature, parameterIndex: number): Type; getNonNullableType(type: Type): Type; - /** Note that the resulting type node cannot be checked. */ + /** Note that the resulting nodes cannot be checked. */ createTypeNode(type: Type): TypeNode; - /** Note that the resulting type node cannot be checked. */ - createTypeParameterDeclarationFromType(type: Type): TypeParameterDeclaration; - /** Note that the resulting type node cannot be checked. */ - createIndexSignatureFromIndexInfo(indexInfo: IndexInfo, kind: IndexKind): IndexSignatureDeclaration - /** Note that the resulting type node cannot be checked. */ - createParameterDeclarationFromSymbol(parameterSymbol: Symbol): ParameterDeclaration; + /** Note that the resulting nodes cannot be checked. */ + createIndexSignatureFromIndexInfo(indexInfo: IndexInfo, kind: IndexKind): IndexSignatureDeclaration; + /** Note that the resulting nodes cannot be checked. */ + createSignatureParts(signature: Signature): SignatureParts; getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; getSymbolAtLocation(node: Node): Symbol; @@ -3230,6 +3228,12 @@ namespace ts { declaration?: SignatureDeclaration; } + export interface SignatureParts { + typeParameters: TypeParameterDeclaration[] | undefined; + parameters: ParameterDeclaration[]; + type: TypeNode; + } + /* @internal */ export interface TypeMapper { (t: TypeParameter): Type; diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index e98235c3c8..a8347cb0a9 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -93,7 +93,7 @@ namespace ts.codefix { // TODO: get parameters working. // TODO: add support for type parameters. const signature = signatures[0]; - const signatureParts = getSignatureParts(signature); + const signatureParts = checker.createSignatureParts(signature); return createStubbedMethod(modifiers, name, optional, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type); } @@ -101,7 +101,7 @@ namespace ts.codefix { for (let i = 0; i < signatures.length; i++) { // TODO: make signatures instead of methods const signature = signatures[i]; - const signatureParts = getSignatureParts(signature); + const signatureParts = checker.createSignatureParts(signature); signatureDeclarations.push(createMethod( /*decorators*/ undefined , modifiers @@ -116,7 +116,7 @@ namespace ts.codefix { if (declarations.length > signatures.length) { let signature = checker.getSignatureFromDeclaration(declarations[declarations.length - 1] as SignatureDeclaration); - const signatureParts = getSignatureParts(signature); + const signatureParts = checker.createSignatureParts(signature); signatureDeclarations.push(createStubbedMethod(modifiers, name, optional, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type)); } else { @@ -128,20 +128,6 @@ namespace ts.codefix { default: return undefined; } - - type SignatureParts = { - typeParameters: TypeParameterDeclaration[]; - parameters: ParameterDeclaration[]; - type: TypeNode; - } - - function getSignatureParts(signature: Signature): SignatureParts { - return { - typeParameters: signature.typeParameters && signature.typeParameters.map(checker.createTypeParameterDeclarationFromType), - parameters: signature.getParameters().map(symbol => checker.createParameterDeclarationFromSymbol(symbol)), - type: createTypeNodeExceptAny(checker.getReturnTypeOfSignature(signature), checker) - } - } } function createMethodImplementingSignatures(signatures: Signature[], name: PropertyName, optional: boolean, modifiers: Modifier[] | undefined): MethodDeclaration { @@ -234,9 +220,4 @@ namespace ts.codefix { } return undefined; } - - function createTypeNodeExceptAny(type: Type, checker: TypeChecker) { - const typeNode = checker.createTypeNode(type); - return typeNode && typeNode.kind !== SyntaxKind.AnyKeyword ? typeNode : undefined; - } } \ No newline at end of file From 7318c2c5a9a0a559ab27b5584dd4025d546f33d5 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Thu, 16 Mar 2017 17:18:28 -0700 Subject: [PATCH 095/164] some cleanup --- src/compiler/checker.ts | 49 ++++++++----------- src/compiler/factory.ts | 10 +--- ...lassImplementInterfaceNamespaceConflict.ts | 3 +- 3 files changed, 24 insertions(+), 38 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4ccc8f84de..7af5b877b5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2327,22 +2327,22 @@ namespace ts { if (objectFlags & ObjectFlags.ClassOrInterface) { Debug.assert(!!(type.flags & TypeFlags.Object)); // TODO: Detect whether class is named and fail if not. - const name = getNameOfSymbol(type.symbol); + const name = createNameFromSymbol(type.symbol); // TODO: handle type arguments. return createTypeReferenceNode(name, /*typeParameters*/undefined); } if (type.flags & TypeFlags.TypeParameter) { // TODO: get qualified name when necessary instead of string. - const name = symbolToString(type.symbol); + const name = createNameFromSymbol(type.symbol); // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. return createTypeReferenceNode(name, /*typeArguments*/ undefined); } // TODO: move back up later on? if (checkAlias && type.aliasSymbol) { - const name = getNameOfSymbol(type.aliasSymbol); + const name = createNameFromSymbol(type.aliasSymbol); const typeArgumentNodes = mapToTypeNodeArray(type.aliasTypeArguments); - return createTypeReferenceNode(createIdentifier(name), typeArgumentNodes); + return createTypeReferenceNode(name, typeArgumentNodes); } checkAlias = false; @@ -2357,15 +2357,12 @@ namespace ts { if (objectFlags & (ObjectFlags.Anonymous | ObjectFlags.Mapped)) { Debug.assert(!!(type.flags & TypeFlags.Object)); // The type is an object literal type. - if (!type.symbol) { - // Anonymous types without symbols are literals. - // TODO: handle this case correctly. - // TODO: test. - noop(); - } - return createAnonymousTypeNode(type); } + + // TODO: implement when this is testable. + // else if (type.flags & TypeFlags.StringOrNumberLiteral) { + // writer.writeStringLiteral(literalTypeToString(type)); if (type.flags & TypeFlags.Index) { // TODO: test. @@ -2382,14 +2379,17 @@ namespace ts { Debug.fail("Should be unreachable."); - /** Note that mapToTypeNodeArray(undefined) === undefined. */ function mapToTypeNodeArray(types: Type[]): NodeArray { - return asNodeArray(types && types.map(createTypeNodeWorker) as TypeNode[]); + return types && asNodeArray(types.map(createTypeNodeWorker) as TypeNode[]); } - // TODO: implement when this is testable. - // else if (type.flags & TypeFlags.StringOrNumberLiteral) { - // writer.writeStringLiteral(literalTypeToString(type)); + function createNameFromSymbol(symbol: Symbol): Identifier; + function createNameFromSymbol(symbol: Symbol): EntityName; + function createNameFromSymbol(symbol: Symbol): EntityName { + symbol; enclosingDeclaration; + // TODO: actually implement this + return createIdentifier(symbolToString(symbol, enclosingDeclaration)); + } function createMappedTypeNodeFromType(type: MappedType) { Debug.assert(!!(type.flags & TypeFlags.Object)); @@ -2414,8 +2414,6 @@ namespace ts { if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) || symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule) || shouldWriteTypeOfFunctionSymbol()) { - // TODO: test. - // TODO: get entity name from symbol. return createTypeQueryNodeFromType(type); } else if (contains(symbolStack, symbol)) { @@ -2443,7 +2441,7 @@ namespace ts { } } else { - // Anonymous types with no symbol are never circular + // Anonymous types without a symbol are never circular. return createTypeNodeFromObjectType(type); } @@ -2496,18 +2494,11 @@ namespace ts { function createTypeQueryNodeFromType(type: Type) { const symbol = type.symbol; if (symbol) { - // TODO: get entity name instead. const entityName = createNameFromSymbol(symbol); return createTypeQueryNode(entityName); } } - function createNameFromSymbol(symbol: Symbol): EntityName { - symbol; enclosingDeclaration; - // TODO: actually implement this - return createIdentifier(symbolToString(symbol, enclosingDeclaration)); - } - function createTypeReferenceNodeFromType(type: TypeReference) { const typeArguments: Type[] = type.typeArguments || emptyArray; if (type.target === globalArrayType) { @@ -2535,8 +2526,8 @@ namespace ts { // the default outer type arguments), we don't show the group. // TODO: figure out how to handle type arguments if (!rangeEquals(outerTypeParameters, typeArguments, start, i)) { - const name = symbolToString(parent); - const qualifiedNamePart = createIdentifier(name); // createTypeReferenceNode(name, mapToTypeNodeArray(typeArguments.slice(start, i - start))); + const name = createNameFromSymbol(parent); + const qualifiedNamePart = name; // createTypeReferenceNode(name, mapToTypeNodeArray(typeArguments.slice(start, i - start))); if (!qualifiedName) { qualifiedName = createQualifiedName(qualifiedNamePart, /*right*/undefined); } @@ -2549,7 +2540,7 @@ namespace ts { } } let entityName: EntityName = undefined; - const nameIdentifier = createIdentifier(symbolToString(type.symbol)); + const nameIdentifier = createNameFromSymbol(type.symbol); if (qualifiedName) { // TODO: handle checking of type arguments for qualified names? Debug.assert(!qualifiedName.right); diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index d91076dcde..e60ed0009e 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -68,18 +68,12 @@ namespace ts { } /* @internal */ - /** - * Note this implementation is inefficient in that all nodes except leaves are cloned twice, - * First by the explicit call below and then again as part of updateNode. - * We need to clone before visiting the children because otherwise updateNode - * will overwrite the synthesized span with the original node's span. - */ export function getSynthesizedDeepClone(node: T | undefined): T { if (node === undefined) { return undefined; } - const clone = getSynthesizedClone(node); - return visitEachChild(clone, getSynthesizedDeepClone, nullTransformationContext); + const clone = visitEachChild(node, getSynthesizedDeepClone, nullTransformationContext); + return clone === node ? getSynthesizedClone(node) : clone; } // Literals diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceNamespaceConflict.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceNamespaceConflict.ts index 4ca42640c2..b8b389c463 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceNamespaceConflict.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceNamespaceConflict.ts @@ -3,14 +3,15 @@ //// namespace N1 { //// export interface I1 { //// x: number; +//// y: I1; //// } //// } //// interface I1 { //// f1(); //// } -//// //// class C1 implements N1.I1 {[| |]} verify.rangeAfterCodeFix(` x: number; +y: N1.I1; `); \ No newline at end of file From 28df2ab2df340d343a477e467f8ce4721d83e47d Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Thu, 16 Mar 2017 17:21:12 -0700 Subject: [PATCH 096/164] some cleanup --- src/compiler/checker.ts | 49 +++++++++++++++++------------------------ src/compiler/factory.ts | 10 ++------- 2 files changed, 22 insertions(+), 37 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4ccc8f84de..7af5b877b5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2327,22 +2327,22 @@ namespace ts { if (objectFlags & ObjectFlags.ClassOrInterface) { Debug.assert(!!(type.flags & TypeFlags.Object)); // TODO: Detect whether class is named and fail if not. - const name = getNameOfSymbol(type.symbol); + const name = createNameFromSymbol(type.symbol); // TODO: handle type arguments. return createTypeReferenceNode(name, /*typeParameters*/undefined); } if (type.flags & TypeFlags.TypeParameter) { // TODO: get qualified name when necessary instead of string. - const name = symbolToString(type.symbol); + const name = createNameFromSymbol(type.symbol); // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. return createTypeReferenceNode(name, /*typeArguments*/ undefined); } // TODO: move back up later on? if (checkAlias && type.aliasSymbol) { - const name = getNameOfSymbol(type.aliasSymbol); + const name = createNameFromSymbol(type.aliasSymbol); const typeArgumentNodes = mapToTypeNodeArray(type.aliasTypeArguments); - return createTypeReferenceNode(createIdentifier(name), typeArgumentNodes); + return createTypeReferenceNode(name, typeArgumentNodes); } checkAlias = false; @@ -2357,15 +2357,12 @@ namespace ts { if (objectFlags & (ObjectFlags.Anonymous | ObjectFlags.Mapped)) { Debug.assert(!!(type.flags & TypeFlags.Object)); // The type is an object literal type. - if (!type.symbol) { - // Anonymous types without symbols are literals. - // TODO: handle this case correctly. - // TODO: test. - noop(); - } - return createAnonymousTypeNode(type); } + + // TODO: implement when this is testable. + // else if (type.flags & TypeFlags.StringOrNumberLiteral) { + // writer.writeStringLiteral(literalTypeToString(type)); if (type.flags & TypeFlags.Index) { // TODO: test. @@ -2382,14 +2379,17 @@ namespace ts { Debug.fail("Should be unreachable."); - /** Note that mapToTypeNodeArray(undefined) === undefined. */ function mapToTypeNodeArray(types: Type[]): NodeArray { - return asNodeArray(types && types.map(createTypeNodeWorker) as TypeNode[]); + return types && asNodeArray(types.map(createTypeNodeWorker) as TypeNode[]); } - // TODO: implement when this is testable. - // else if (type.flags & TypeFlags.StringOrNumberLiteral) { - // writer.writeStringLiteral(literalTypeToString(type)); + function createNameFromSymbol(symbol: Symbol): Identifier; + function createNameFromSymbol(symbol: Symbol): EntityName; + function createNameFromSymbol(symbol: Symbol): EntityName { + symbol; enclosingDeclaration; + // TODO: actually implement this + return createIdentifier(symbolToString(symbol, enclosingDeclaration)); + } function createMappedTypeNodeFromType(type: MappedType) { Debug.assert(!!(type.flags & TypeFlags.Object)); @@ -2414,8 +2414,6 @@ namespace ts { if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) || symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule) || shouldWriteTypeOfFunctionSymbol()) { - // TODO: test. - // TODO: get entity name from symbol. return createTypeQueryNodeFromType(type); } else if (contains(symbolStack, symbol)) { @@ -2443,7 +2441,7 @@ namespace ts { } } else { - // Anonymous types with no symbol are never circular + // Anonymous types without a symbol are never circular. return createTypeNodeFromObjectType(type); } @@ -2496,18 +2494,11 @@ namespace ts { function createTypeQueryNodeFromType(type: Type) { const symbol = type.symbol; if (symbol) { - // TODO: get entity name instead. const entityName = createNameFromSymbol(symbol); return createTypeQueryNode(entityName); } } - function createNameFromSymbol(symbol: Symbol): EntityName { - symbol; enclosingDeclaration; - // TODO: actually implement this - return createIdentifier(symbolToString(symbol, enclosingDeclaration)); - } - function createTypeReferenceNodeFromType(type: TypeReference) { const typeArguments: Type[] = type.typeArguments || emptyArray; if (type.target === globalArrayType) { @@ -2535,8 +2526,8 @@ namespace ts { // the default outer type arguments), we don't show the group. // TODO: figure out how to handle type arguments if (!rangeEquals(outerTypeParameters, typeArguments, start, i)) { - const name = symbolToString(parent); - const qualifiedNamePart = createIdentifier(name); // createTypeReferenceNode(name, mapToTypeNodeArray(typeArguments.slice(start, i - start))); + const name = createNameFromSymbol(parent); + const qualifiedNamePart = name; // createTypeReferenceNode(name, mapToTypeNodeArray(typeArguments.slice(start, i - start))); if (!qualifiedName) { qualifiedName = createQualifiedName(qualifiedNamePart, /*right*/undefined); } @@ -2549,7 +2540,7 @@ namespace ts { } } let entityName: EntityName = undefined; - const nameIdentifier = createIdentifier(symbolToString(type.symbol)); + const nameIdentifier = createNameFromSymbol(type.symbol); if (qualifiedName) { // TODO: handle checking of type arguments for qualified names? Debug.assert(!qualifiedName.right); diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index d91076dcde..e60ed0009e 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -68,18 +68,12 @@ namespace ts { } /* @internal */ - /** - * Note this implementation is inefficient in that all nodes except leaves are cloned twice, - * First by the explicit call below and then again as part of updateNode. - * We need to clone before visiting the children because otherwise updateNode - * will overwrite the synthesized span with the original node's span. - */ export function getSynthesizedDeepClone(node: T | undefined): T { if (node === undefined) { return undefined; } - const clone = getSynthesizedClone(node); - return visitEachChild(clone, getSynthesizedDeepClone, nullTransformationContext); + const clone = visitEachChild(node, getSynthesizedDeepClone, nullTransformationContext); + return clone === node ? getSynthesizedClone(node) : clone; } // Literals From 621c04479077badda6ac777a160db67224b86c8b Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Thu, 16 Mar 2017 17:22:57 -0700 Subject: [PATCH 097/164] remove test --- ...xClassImplementInterfaceNamespaceConflict.ts | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 tests/cases/fourslash/codeFixClassImplementInterfaceNamespaceConflict.ts diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceNamespaceConflict.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceNamespaceConflict.ts deleted file mode 100644 index b8b389c463..0000000000 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceNamespaceConflict.ts +++ /dev/null @@ -1,17 +0,0 @@ -/// - -//// namespace N1 { -//// export interface I1 { -//// x: number; -//// y: I1; -//// } -//// } -//// interface I1 { -//// f1(); -//// } -//// class C1 implements N1.I1 {[| |]} - -verify.rangeAfterCodeFix(` -x: number; -y: N1.I1; -`); \ No newline at end of file From dee9ced0608f847962d3c4352608847fa021f898 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Thu, 16 Mar 2017 18:02:34 -0700 Subject: [PATCH 098/164] add tests --- .../codeFixClassImplementInterfaceArrayTuple.ts | 15 +++++++++++++++ ...FixClassImplementInterfaceNamespaceConflict.ts | 15 +++++++++++++++ ...codeFixClassImplementInterfaceQualifiedName.ts | 12 ++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 tests/cases/fourslash/codeFixClassImplementInterfaceArrayTuple.ts create mode 100644 tests/cases/fourslash/codeFixClassImplementInterfaceNamespaceConflict.ts create mode 100644 tests/cases/fourslash/codeFixClassImplementInterfaceQualifiedName.ts diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceArrayTuple.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceArrayTuple.ts new file mode 100644 index 0000000000..4550e5ca31 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceArrayTuple.ts @@ -0,0 +1,15 @@ +/// + +//// interface I { +//// x: number[]; +//// y: Array; +//// z: [number, string, I]; +//// } +//// +//// class C implements I {[| |]} + +verify.rangeAfterCodeFix(` +x: number[]; +y: number[]; +z: [number, string, I]; +`); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceNamespaceConflict.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceNamespaceConflict.ts new file mode 100644 index 0000000000..1d71ce3c47 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceNamespaceConflict.ts @@ -0,0 +1,15 @@ +/// + +//// namespace N1 { +//// export interface I1 { +//// x: number; +//// } +//// } +//// interface I1 { +//// f1(); +//// } +//// class C1 implements N1.I1 {[| |]} + +verify.rangeAfterCodeFix(` +x: number; +`); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceQualifiedName.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceQualifiedName.ts new file mode 100644 index 0000000000..e29f4501b1 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceQualifiedName.ts @@ -0,0 +1,12 @@ +/// + +//// namespace N { +//// export interface I { +//// y: I; +//// } +//// } +//// class C1 implements N.I {[| |]} + +verify.rangeAfterCodeFix(` +y: N.I; +`); \ No newline at end of file From 4fa32a29ce42761f9a20172aad47d3bb60ed11b8 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Thu, 16 Mar 2017 18:02:57 -0700 Subject: [PATCH 099/164] make enclosingdeclaration arg required --- src/compiler/checker.ts | 54 ++++++++----------- src/compiler/types.ts | 6 +-- src/services/codefixes/fixAddMissingMember.ts | 2 +- .../fixClassIncorrectlyImplementsInterface.ts | 14 ++--- src/services/codefixes/helpers.ts | 11 ++-- 5 files changed, 38 insertions(+), 49 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7af5b877b5..960a36e347 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2191,23 +2191,23 @@ namespace ts { return result; } - function createTypeParameterDeclarationFromType(type: TypeParameter): TypeParameterDeclaration { + function createTypeParameterDeclarationFromType(type: TypeParameter, enclosingDeclaration: Node): TypeParameterDeclaration { if (!(type && type.symbol && type.flags & TypeFlags.TypeParameter)) { return undefined; } - const constraint = createTypeNode(getConstraintFromTypeParameter(type)) as TypeNode; - const defaultParameter = createTypeNode(getDefaultFromTypeParameter(type)) as TypeNode; + const constraint = createTypeNode(getConstraintFromTypeParameter(type), enclosingDeclaration); + const defaultParameter = createTypeNode(getDefaultFromTypeParameter(type), enclosingDeclaration); const name = symbolToString(type.symbol); return createTypeParameterDeclaration(name, constraint, defaultParameter); } // TODO: enclosing declaration appears to be unused in getTypeOfSymbolAtLocation - function createParameterDeclarationFromSymbol(parameterSymbol: Symbol): ParameterDeclaration { + function createParameterDeclarationFromSymbol(parameterSymbol: Symbol, enclosingDeclaration: Node): ParameterDeclaration { const parameterDeclaration = parameterSymbol.declarations[0] as ParameterDeclaration; const parameterType = getTypeOfSymbol(parameterSymbol); - const parameterTypeNode = checker.createTypeNode(parameterType); + const parameterTypeNode = createTypeNode(parameterType, enclosingDeclaration); // TODO: clone binding names correctly. // TODO: copy initialzer in a way that checks whether all symbols used in expression are accessible here, and qualify them appropriately. const parameterNode = createParameter( @@ -2222,25 +2222,24 @@ namespace ts { } // TODO: expose this, remove copy from helper, possibly don't expose createParameter/TypeParameter? - function createSignatureParts(signature: Signature): SignatureParts { + function createSignatureParts(signature: Signature, enclosingDeclaration: Node): SignatureParts { return { - typeParameters: signature.typeParameters && signature.typeParameters.map(createTypeParameterDeclarationFromType), - parameters: signature.parameters.map(createParameterDeclarationFromSymbol), + typeParameters: signature.typeParameters && signature.typeParameters.map(parameter => createTypeParameterDeclarationFromType(parameter,enclosingDeclaration)), + parameters: signature.parameters.map(parameter => createParameterDeclarationFromSymbol(parameter,enclosingDeclaration)), type: createTypeNodeExceptAny(getReturnTypeOfSignature(signature)) } function createTypeNodeExceptAny(type: Type): TypeNode | undefined { - const typeNode = createTypeNode(type); + const typeNode = createTypeNode(type, enclosingDeclaration); return typeNode && typeNode.kind !== SyntaxKind.AnyKeyword ? typeNode : undefined; } } - function createTypeNode(type: Type): TypeNode { + function createTypeNode(type: Type, enclosingDeclaration: Node): TypeNode { let undefinedArgumentIsError = true; let encounteredError = false; let inObjectTypeLiteral = false; let checkAlias = true; - let enclosingDeclaration: Node = undefined; // TODO: add parameter. let symbolStack: Symbol[] = undefined; let result = createTypeNodeWorker(type); @@ -2256,7 +2255,7 @@ namespace ts { return undefined; } - const typeString = typeToString(type); typeString; // TODO: remove. + const typeString = typeToString(type, enclosingDeclaration); typeString; // TODO: remove. if (type.flags & TypeFlags.Any) { // TODO: add other case where type ends up being `any`. @@ -2315,15 +2314,8 @@ namespace ts { if (objectFlags & ObjectFlags.Reference) { Debug.assert(!!(type.flags & TypeFlags.Object)); - // and vice versa. - // this case includes tuple types - // TODO: test empty tuples, see if they are coherent. return createTypeReferenceNodeFromType(type); } - - if (type.flags & TypeFlags.EnumLiteral) { - throw new Error("Enum literal not implemented"); - } if (objectFlags & ObjectFlags.ClassOrInterface) { Debug.assert(!!(type.flags & TypeFlags.Object)); // TODO: Detect whether class is named and fail if not. @@ -2397,9 +2389,9 @@ namespace ts { // TODO: does typeParameter have the same constraint or do we need to overwrite it somehow? const typeParameter = getTypeParameterFromMappedType(type); // const constraintType = getConstraintTypeFromMappedType(type); - const typeParameterNode = createTypeParameterDeclarationFromType(typeParameter); + const typeParameterNode = createTypeParameterDeclarationFromType(typeParameter, enclosingDeclaration); - const templateTypeNode = createTypeNode(getTemplateTypeFromMappedType(type)); + const templateTypeNode = createTypeNode(getTemplateTypeFromMappedType(type), enclosingDeclaration); const readonlyToken = (type).declaration && (type).declaration.readonlyToken ? createToken(SyntaxKind.ReadonlyKeyword) : undefined; const questionToken = (type).declaration && (type).declaration.questionToken ? createToken(SyntaxKind.QuestionToken) : undefined; @@ -2474,12 +2466,12 @@ namespace ts { if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) { const signature = resolved.callSignatures[0]; - const signatureParts = createSignatureParts(signature); + const signatureParts = createSignatureParts(signature, enclosingDeclaration); return createSignatureDeclaration(SyntaxKind.FunctionType, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type); } if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) { const signature = resolved.constructSignatures[0]; - const signatureParts = createSignatureParts(signature); + const signatureParts = createSignatureParts(signature, enclosingDeclaration); return createSignatureDeclaration(SyntaxKind.ConstructorType, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type); } } @@ -2559,18 +2551,18 @@ namespace ts { function createTypeNodesFromResolvedType(resolvedType: ResolvedType): TypeElement[] { const typeElements: TypeElement[] = []; for (const signature of resolvedType.callSignatures) { - const signatureParts = createSignatureParts(signature); + const signatureParts = createSignatureParts(signature, enclosingDeclaration); typeElements.push(createSignatureDeclaration(SyntaxKind.CallSignature, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type)); } for (const signature of resolvedType.constructSignatures) { - const signatureParts = createSignatureParts(signature); + const signatureParts = createSignatureParts(signature, enclosingDeclaration); typeElements.push(createSignatureDeclaration(SyntaxKind.ConstructSignature, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type)); } if (resolvedType.stringIndexInfo) { - typeElements.push(createIndexSignatureFromIndexInfo(resolvedType.stringIndexInfo, IndexKind.String)); + typeElements.push(createIndexSignatureFromIndexInfo(resolvedType.stringIndexInfo, IndexKind.String, enclosingDeclaration)); } if (resolvedType.numberIndexInfo) { - typeElements.push(createIndexSignatureFromIndexInfo(resolvedType.numberIndexInfo, IndexKind.Number)); + typeElements.push(createIndexSignatureFromIndexInfo(resolvedType.numberIndexInfo, IndexKind.Number, enclosingDeclaration)); } const properties = resolvedType.properties; @@ -2589,7 +2581,7 @@ namespace ts { if (propertySymbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length) { const signatures = getSignaturesOfType(propertyType, SignatureKind.Call); for (const signature of signatures) { - const signatureParts = createSignatureParts(signature); + const signatureParts = createSignatureParts(signature, enclosingDeclaration); const methodDeclaration = createSignatureDeclaration(SyntaxKind.MethodSignature, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type, propertyName, optionalToken); methodDeclaration.questionToken = optionalToken; typeElements.push(methodDeclaration); @@ -2599,7 +2591,7 @@ namespace ts { typeElements.push(createPropertySignature( propertyName , optionalToken - , createTypeNode(propertyType) + , createTypeNodeWorker(propertyType) , /*initializer*/undefined)); } } @@ -2608,7 +2600,7 @@ namespace ts { } } - function createIndexSignatureFromIndexInfo(indexInfo: IndexInfo, kind: IndexKind): IndexSignatureDeclaration { + function createIndexSignatureFromIndexInfo(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node): IndexSignatureDeclaration { const indexerTypeNode = createKeywordTypeNode(kind === IndexKind.String ? SyntaxKind.StringKeyword : SyntaxKind.NumberKeyword); const name = getNameFromIndexInfo(indexInfo); @@ -2620,7 +2612,7 @@ namespace ts { , /*questionToken*/ undefined , indexerTypeNode , /*initializer*/ undefined); - const typeNode = createTypeNode(indexInfo.type); + const typeNode = createTypeNode(indexInfo.type, enclosingDeclaration); return createIndexSignatureDeclaration( [indexingParameter] , typeNode diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 679e11fa25..d802adf67e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2469,11 +2469,11 @@ namespace ts { getNonNullableType(type: Type): Type; /** Note that the resulting nodes cannot be checked. */ - createTypeNode(type: Type): TypeNode; + createTypeNode(type: Type, enclosingDeclaration: Node): TypeNode; /** Note that the resulting nodes cannot be checked. */ - createIndexSignatureFromIndexInfo(indexInfo: IndexInfo, kind: IndexKind): IndexSignatureDeclaration; + createIndexSignatureFromIndexInfo(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node): IndexSignatureDeclaration; /** Note that the resulting nodes cannot be checked. */ - createSignatureParts(signature: Signature): SignatureParts; + createSignatureParts(signature: Signature, enclosingDeclaration: Node): SignatureParts; getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; getSymbolAtLocation(node: Node): Symbol; diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index ace11cda80..ab973bb577 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -38,7 +38,7 @@ namespace ts.codefix { const checker = context.program.getTypeChecker(); const widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(binaryExpression.right))); - typeNode = checker.createTypeNode(widenedType) || typeNode; + typeNode = checker.createTypeNode(widenedType, classDeclaration) || typeNode; } const openBrace = getOpenBraceOfClassLike(classDeclaration, sourceFile); diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts index 33b4a10dff..de34676eda 100644 --- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts +++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts @@ -11,14 +11,14 @@ namespace ts.codefix { const token = getTokenAtPosition(sourceFile, start); const checker = context.program.getTypeChecker(); - const classDecl = getContainingClass(token); - if (!classDecl) { + const classDeclaration = getContainingClass(token); + if (!classDeclaration) { return undefined; } - const openBrace = getOpenBraceOfClassLike(classDecl, sourceFile); - const classType = checker.getTypeAtLocation(classDecl) as InterfaceType; - const implementedTypeNodes = getClassImplementsHeritageClauseElements(classDecl); + const openBrace = getOpenBraceOfClassLike(classDeclaration, sourceFile); + const classType = checker.getTypeAtLocation(classDeclaration) as InterfaceType; + const implementedTypeNodes = getClassImplementsHeritageClauseElements(classDeclaration); const hasNumericIndexSignature = !!checker.getIndexTypeOfType(classType, IndexKind.Number); const hasStringIndexSignature = !!checker.getIndexTypeOfType(classType, IndexKind.String); @@ -34,7 +34,7 @@ namespace ts.codefix { let newNodes: Node[] = []; createAndAddMissingIndexSignatureDeclaration(implementedType, IndexKind.Number, hasNumericIndexSignature, newNodes); createAndAddMissingIndexSignatureDeclaration(implementedType, IndexKind.String, hasStringIndexSignature, newNodes); - newNodes = newNodes.concat(createMissingMemberNodes(classDecl, nonPrivateMembers, checker)); + newNodes = newNodes.concat(createMissingMemberNodes(classDeclaration, nonPrivateMembers, checker)); const message = formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Implement_interface_0), [implementedTypeNode.getText()]); if (newNodes.length > 0) { pushAction(result, newNodes, message); @@ -53,7 +53,7 @@ namespace ts.codefix { if (!indexInfoOfKind) { return undefined; } - const newIndexSignatureDeclaration = checker.createIndexSignatureFromIndexInfo(indexInfoOfKind, kind); + const newIndexSignatureDeclaration = checker.createIndexSignatureFromIndexInfo(indexInfoOfKind, kind, classDeclaration); newNodes.push(newIndexSignatureDeclaration); } diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index a8347cb0a9..8693cc453b 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -62,7 +62,7 @@ namespace ts.codefix { case SyntaxKind.SetAccessor: case SyntaxKind.PropertySignature: case SyntaxKind.PropertyDeclaration: - const typeNode = checker.createTypeNode(type); + const typeNode = checker.createTypeNode(type, enclosingDeclaration); // TODO: add modifiers. const property = createProperty( /*decorators*/undefined @@ -89,11 +89,8 @@ namespace ts.codefix { const optional = !!(symbol.flags & SymbolFlags.Optional); if (declarations.length === 1) { Debug.assert(signatures.length === 1); - // TODO: suppress any return type - // TODO: get parameters working. - // TODO: add support for type parameters. const signature = signatures[0]; - const signatureParts = checker.createSignatureParts(signature); + const signatureParts = checker.createSignatureParts(signature, enclosingDeclaration); return createStubbedMethod(modifiers, name, optional, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type); } @@ -101,7 +98,7 @@ namespace ts.codefix { for (let i = 0; i < signatures.length; i++) { // TODO: make signatures instead of methods const signature = signatures[i]; - const signatureParts = checker.createSignatureParts(signature); + const signatureParts = checker.createSignatureParts(signature, enclosingDeclaration); signatureDeclarations.push(createMethod( /*decorators*/ undefined , modifiers @@ -116,7 +113,7 @@ namespace ts.codefix { if (declarations.length > signatures.length) { let signature = checker.getSignatureFromDeclaration(declarations[declarations.length - 1] as SignatureDeclaration); - const signatureParts = checker.createSignatureParts(signature); + const signatureParts = checker.createSignatureParts(signature, enclosingDeclaration); signatureDeclarations.push(createStubbedMethod(modifiers, name, optional, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type)); } else { From ac7fc8fe75af8b0bc062fa67ebbe3d8692933545 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Fri, 17 Mar 2017 11:54:51 -0700 Subject: [PATCH 100/164] Handle TODO's --- src/compiler/checker.ts | 113 +++++++++++------- src/compiler/visitor.ts | 13 +- src/services/codefixes/fixAddMissingMember.ts | 1 - src/services/codefixes/helpers.ts | 5 +- ...codeFixClassImplementInterfaceIndexType.ts | 10 ++ ...odeFixClassImplementInterfaceMappedType.ts | 10 ++ 6 files changed, 102 insertions(+), 50 deletions(-) create mode 100644 tests/cases/fourslash/codeFixClassImplementInterfaceIndexType.ts create mode 100644 tests/cases/fourslash/codeFixClassImplementInterfaceMappedType.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 960a36e347..58186560e8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2203,13 +2203,12 @@ namespace ts { return createTypeParameterDeclaration(name, constraint, defaultParameter); } - // TODO: enclosing declaration appears to be unused in getTypeOfSymbolAtLocation function createParameterDeclarationFromSymbol(parameterSymbol: Symbol, enclosingDeclaration: Node): ParameterDeclaration { const parameterDeclaration = parameterSymbol.declarations[0] as ParameterDeclaration; const parameterType = getTypeOfSymbol(parameterSymbol); const parameterTypeNode = createTypeNode(parameterType, enclosingDeclaration); - // TODO: clone binding names correctly. - // TODO: copy initialzer in a way that checks whether all symbols used in expression are accessible here, and qualify them appropriately. + // TODO: how should we clone members/modifiers? + // TODO: check initializer accessibility correctly. const parameterNode = createParameter( parameterDeclaration.decorators && parameterDeclaration.decorators.map(getSynthesizedDeepClone) , parameterDeclaration.modifiers && parameterDeclaration.modifiers.map(getSynthesizedDeepClone) @@ -2217,11 +2216,10 @@ namespace ts { , getSynthesizedDeepClone(parameterDeclaration.name) , parameterDeclaration.questionToken && createToken(SyntaxKind.QuestionToken) , parameterTypeNode - , /*initializer*/ undefined); + , parameterDeclaration.initializer && getSynthesizedDeepClone(parameterDeclaration.initializer)); return parameterNode; } - // TODO: expose this, remove copy from helper, possibly don't expose createParameter/TypeParameter? function createSignatureParts(signature: Signature, enclosingDeclaration: Node): SignatureParts { return { typeParameters: signature.typeParameters && signature.typeParameters.map(parameter => createTypeParameterDeclarationFromType(parameter,enclosingDeclaration)), @@ -2242,12 +2240,8 @@ namespace ts { let checkAlias = true; let symbolStack: Symbol[] = undefined; - let result = createTypeNodeWorker(type); - if (result) { - (result).__type_source = type; - (result).__type_source_str = typeToString(type); - } - return result; + const result = createTypeNodeWorker(type); + return encounteredError ? undefined: result; function createTypeNodeWorker(type: Type): TypeNode { if (!type) { @@ -2255,10 +2249,7 @@ namespace ts { return undefined; } - const typeString = typeToString(type, enclosingDeclaration); typeString; // TODO: remove. - if (type.flags & TypeFlags.Any) { - // TODO: add other case where type ends up being `any`. return createKeywordTypeNode(SyntaxKind.AnyKeyword); } if (type.flags & TypeFlags.String) { @@ -2318,19 +2309,16 @@ namespace ts { } if (objectFlags & ObjectFlags.ClassOrInterface) { Debug.assert(!!(type.flags & TypeFlags.Object)); - // TODO: Detect whether class is named and fail if not. const name = createNameFromSymbol(type.symbol); // TODO: handle type arguments. - return createTypeReferenceNode(name, /*typeParameters*/undefined); + return createTypeReferenceNode(name, /*typeArguments*/ undefined); } if (type.flags & TypeFlags.TypeParameter) { - // TODO: get qualified name when necessary instead of string. const name = createNameFromSymbol(type.symbol); // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. return createTypeReferenceNode(name, /*typeArguments*/ undefined); } - // TODO: move back up later on? if (checkAlias && type.aliasSymbol) { const name = createNameFromSymbol(type.aliasSymbol); const typeArgumentNodes = mapToTypeNodeArray(type.aliasTypeArguments); @@ -2352,18 +2340,14 @@ namespace ts { return createAnonymousTypeNode(type); } - // TODO: implement when this is testable. - // else if (type.flags & TypeFlags.StringOrNumberLiteral) { - // writer.writeStringLiteral(literalTypeToString(type)); + // TODO (aozgaa): implement string and number literals here once there is a testable case. if (type.flags & TypeFlags.Index) { - // TODO: test. - const indexType = getIndexType(getApparentType((type).type)); - const indexTypeNode = createTypeNodeWorker(indexType); + const indexedType = (type).type; + const indexTypeNode = createTypeNodeWorker(indexedType); return createTypeOperatorNode(indexTypeNode); } if (type.flags & TypeFlags.IndexedAccess) { - // TODO: test. const objectTypeNode = createTypeNodeWorker((type).objectType); const indexTypeNode = createTypeNodeWorker((type).indexType); return createIndexedAccessTypeNode(objectTypeNode, indexTypeNode); @@ -2375,27 +2359,15 @@ namespace ts { return types && asNodeArray(types.map(createTypeNodeWorker) as TypeNode[]); } - function createNameFromSymbol(symbol: Symbol): Identifier; - function createNameFromSymbol(symbol: Symbol): EntityName; - function createNameFromSymbol(symbol: Symbol): EntityName { - symbol; enclosingDeclaration; - // TODO: actually implement this - return createIdentifier(symbolToString(symbol, enclosingDeclaration)); - } - function createMappedTypeNodeFromType(type: MappedType) { Debug.assert(!!(type.flags & TypeFlags.Object)); - - // TODO: does typeParameter have the same constraint or do we need to overwrite it somehow? const typeParameter = getTypeParameterFromMappedType(type); - // const constraintType = getConstraintTypeFromMappedType(type); const typeParameterNode = createTypeParameterDeclarationFromType(typeParameter, enclosingDeclaration); const templateTypeNode = createTypeNode(getTemplateTypeFromMappedType(type), enclosingDeclaration); const readonlyToken = (type).declaration && (type).declaration.readonlyToken ? createToken(SyntaxKind.ReadonlyKeyword) : undefined; const questionToken = (type).declaration && (type).declaration.questionToken ? createToken(SyntaxKind.QuestionToken) : undefined; - // TODO: test. return createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode); } @@ -2501,7 +2473,6 @@ namespace ts { return createTupleTypeNode(typeArguments.length > 0 ? mapToTypeNodeArray(typeArguments.slice(0, getTypeReferenceArity(type))) : undefined); } else { - // TODO: handle type parameters in qualified names... const outerTypeParameters = type.target.outerTypeParameters; let i = 0; let qualifiedName: QualifiedName | undefined = undefined; @@ -2516,10 +2487,9 @@ namespace ts { } while (i < length && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent); // When type parameters are their own type arguments for the whole group (i.e. we have // the default outer type arguments), we don't show the group. - // TODO: figure out how to handle type arguments if (!rangeEquals(outerTypeParameters, typeArguments, start, i)) { const name = createNameFromSymbol(parent); - const qualifiedNamePart = name; // createTypeReferenceNode(name, mapToTypeNodeArray(typeArguments.slice(start, i - start))); + const qualifiedNamePart = name; if (!qualifiedName) { qualifiedName = createQualifiedName(qualifiedNamePart, /*right*/undefined); } @@ -2534,7 +2504,6 @@ namespace ts { let entityName: EntityName = undefined; const nameIdentifier = createNameFromSymbol(type.symbol); if (qualifiedName) { - // TODO: handle checking of type arguments for qualified names? Debug.assert(!qualifiedName.right); qualifiedName.right = nameIdentifier; entityName = qualifiedName; @@ -2597,6 +2566,68 @@ namespace ts { } return typeElements.length ? typeElements : undefined; } + + function createNameFromSymbol(symbol: Symbol): Identifier; + function createNameFromSymbol(symbol: Symbol): EntityName; + function createNameFromSymbol(symbol: Symbol): EntityName { + let parentSymbol: Symbol; + symbol; enclosingDeclaration; + let meaning: SymbolFlags; + + // Get qualified name if the symbol is not a type parameter + // and there is an enclosing declaration. + let chain: Symbol[]; + const isTypeParameter = symbol.flags & SymbolFlags.TypeParameter; + if (!isTypeParameter && enclosingDeclaration) { + chain = getSymbolChain(symbol, meaning, /*endOfChain*/ true); + Debug.assert(chain && chain.length > 0); + } + else { + chain = [symbol]; + } + + const result = createEntityNameFromSymbolChain(chain, chain.length - 1); + return result; + + function createEntityNameFromSymbolChain(chain: Symbol[], index: number): EntityName { + Debug.assert(chain && 0 <= index && index < chain.length); + const identifier = createIdentifier(getNameOfSymbol(chain[index])); + return index > 0 ? createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier; + } + + /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */ + function getSymbolChain(symbol: Symbol, meaning: SymbolFlags, endOfChain: boolean): Symbol[] | undefined { + let accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, /*useOnlyExternalAliasing*/false); + + if (!accessibleSymbolChain || + needsQualification(accessibleSymbolChain[0], enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) { + + // Go up and add our parent. + const parent = getParentOfSymbol(accessibleSymbolChain ? accessibleSymbolChain[0] : symbol); + if (parent) { + const parentChain = getSymbolChain(parent, getQualifiedLeftMeaning(meaning), /*endOfChain*/ false); + if (parentChain) { + accessibleSymbolChain = parentChain.concat(accessibleSymbolChain || [symbol]); + } + } + } + + if (accessibleSymbolChain) { + return accessibleSymbolChain; + } + + else if ( + // If this is the last part of outputting the symbol, always output. The cases apply only to parent symbols. + endOfChain || + // If a parent symbol is an external module, don't write it. (We prefer just `x` vs `"foo/bar".x`.) + !(!parentSymbol && ts.forEach(symbol.declarations, hasExternalModuleSymbol)) && + // If a parent symbol is an anonymous type, don't write it. + !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral))) { + + return [symbol]; + } + } + } } } diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 5d63126ad0..1410c7aaab 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -333,13 +333,18 @@ namespace ts { return updateTypeOperatorNode(node, visitNode((node).type, visitor, isTypeNode)); case SyntaxKind.IndexedAccessType: return updateIndexedAccessTypeNode((node) - , visitNode((node).objectType, visitor, isTypeNode) - , visitNode((node).indexType, visitor, isTypeNode)); + , visitNode((node).objectType, visitor, isTypeNode) + , visitNode((node).indexType, visitor, isTypeNode)); case SyntaxKind.MappedType: - throw new Error("reached unsupported type in visitor."); + return updateMappedTypeNode((node) + , visitNode((node).readonlyToken, visitor, isToken) + , visitNode((node).typeParameter, visitor, isTypeParameter) + , visitNode((node).questionToken, visitor, isToken) + , visitNode((node).type, visitor, isTypeNode)); + case SyntaxKind.LiteralType: return updateLiteralTypeNode(node - , visitNode((node).literal, visitor, isExpression)); + , visitNode((node).literal, visitor, isExpression)); // Type Declarations diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index ab973bb577..5399092757 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -50,7 +50,6 @@ namespace ts.codefix { , /*questionToken*/ undefined , typeNode , /*initializer*/ undefined); - // TODO: make index signature. const propertyChangeTracker = textChanges.ChangeTracker.fromCodeFixContext(context); propertyChangeTracker.insertNodeAfter(sourceFile, openBrace, property, { suffix: context.newLineCharacter }); diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 8693cc453b..e642da2159 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -4,7 +4,6 @@ namespace ts.codefix { export function newNodesToChanges(newNodes: Node[], insertAfter: Node, context: CodeFixContext) { const sourceFile = context.sourceFile; if (!(newNodes)) { - // TODO: make the appropriate value flow through gracefully. throw new Error("newNodesToChanges expects an array"); } @@ -13,6 +12,7 @@ namespace ts.codefix { for (const newNode of newNodes) { changeTracker.insertNodeAfter(sourceFile, insertAfter, newNode, { suffix: context.newLineCharacter }); } + // TODO (aozgaa): concatenate changes into a single change. return changeTracker.getChanges(); } @@ -51,7 +51,6 @@ namespace ts.codefix { } const declaration = declarations[0] as Declaration; - // TODO: get name as identifier or computer property name, etc. const name = declaration.name ? getSynthesizedDeepClone(declaration.name) as PropertyName : undefined; const visibilityModifier = createVisibilityModifier(getModifierFlags(declaration)); const modifiers = visibilityModifier ? [visibilityModifier] : undefined; @@ -63,7 +62,6 @@ namespace ts.codefix { case SyntaxKind.PropertySignature: case SyntaxKind.PropertyDeclaration: const typeNode = checker.createTypeNode(type, enclosingDeclaration); - // TODO: add modifiers. const property = createProperty( /*decorators*/undefined , modifiers @@ -96,7 +94,6 @@ namespace ts.codefix { let signatureDeclarations = []; for (let i = 0; i < signatures.length; i++) { - // TODO: make signatures instead of methods const signature = signatures[i]; const signatureParts = checker.createSignatureParts(signature, enclosingDeclaration); signatureDeclarations.push(createMethod( diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceIndexType.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceIndexType.ts new file mode 100644 index 0000000000..ed5ea06ebb --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceIndexType.ts @@ -0,0 +1,10 @@ +/// + +//// interface I { +//// x: keyof X; +//// } +//// class C implements I {[| |]} + +verify.rangeAfterCodeFix(` +x: keyof Y; +`); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceMappedType.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceMappedType.ts new file mode 100644 index 0000000000..64676bce86 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceMappedType.ts @@ -0,0 +1,10 @@ +/// + +//// interface I { +//// x: { readonly [K in keyof X]: X[K] }; +//// } +//// class C implements I {[| |]} + +verify.rangeAfterCodeFix(` +x: { readonly [K in keyof X]: Y[K]; }; +`); From 944b34fd4e96edb9dcb54313aabe0455b3ab51c6 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Fri, 17 Mar 2017 12:08:38 -0700 Subject: [PATCH 101/164] move commas to end of line --- src/compiler/checker.ts | 44 ++++----- src/compiler/visitor.ts | 92 +++++++++--------- src/services/codefixes/fixAddMissingMember.ts | 34 +++---- src/services/codefixes/helpers.ts | 96 +++++++++---------- 4 files changed, 132 insertions(+), 134 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 58186560e8..bb5046a8d6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2210,13 +2210,13 @@ namespace ts { // TODO: how should we clone members/modifiers? // TODO: check initializer accessibility correctly. const parameterNode = createParameter( - parameterDeclaration.decorators && parameterDeclaration.decorators.map(getSynthesizedDeepClone) - , parameterDeclaration.modifiers && parameterDeclaration.modifiers.map(getSynthesizedDeepClone) - , parameterDeclaration.dotDotDotToken && createToken(SyntaxKind.DotDotDotToken) - , getSynthesizedDeepClone(parameterDeclaration.name) - , parameterDeclaration.questionToken && createToken(SyntaxKind.QuestionToken) - , parameterTypeNode - , parameterDeclaration.initializer && getSynthesizedDeepClone(parameterDeclaration.initializer)); + parameterDeclaration.decorators && parameterDeclaration.decorators.map(getSynthesizedDeepClone), + parameterDeclaration.modifiers && parameterDeclaration.modifiers.map(getSynthesizedDeepClone), + parameterDeclaration.dotDotDotToken && createToken(SyntaxKind.DotDotDotToken), + getSynthesizedDeepClone(parameterDeclaration.name), + parameterDeclaration.questionToken && createToken(SyntaxKind.QuestionToken), + parameterTypeNode, + parameterDeclaration.initializer && getSynthesizedDeepClone(parameterDeclaration.initializer)); return parameterNode; } @@ -2558,10 +2558,10 @@ namespace ts { } else { typeElements.push(createPropertySignature( - propertyName - , optionalToken - , createTypeNodeWorker(propertyType) - , /*initializer*/undefined)); + propertyName, + optionalToken, + createTypeNodeWorker(propertyType), + /*initializer*/undefined)); } } return typeElements.length ? typeElements : undefined; @@ -2636,19 +2636,19 @@ namespace ts { const name = getNameFromIndexInfo(indexInfo); const indexingParameter = createParameter( - /*decorators*/ undefined - , /*modifiers*/ undefined - , /*dotDotDotToken*/ undefined - , name - , /*questionToken*/ undefined - , indexerTypeNode - , /*initializer*/ undefined); + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, + name, + /*questionToken*/ undefined, + indexerTypeNode, + /*initializer*/ undefined); const typeNode = createTypeNode(indexInfo.type, enclosingDeclaration); return createIndexSignatureDeclaration( - [indexingParameter] - , typeNode - , /*decorators*/ undefined - , indexInfo.isReadonly ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined); + [indexingParameter], + typeNode, + /*decorators*/ undefined, + indexInfo.isReadonly ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined); } function typePredicateToString(typePredicate: TypePredicate, enclosingDeclaration?: Declaration, flags?: TypeFormatFlags): string { diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 1410c7aaab..44b994ce57 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -2,9 +2,7 @@ /// /// -namespace ts { - - +namespace ts { export const nullTransformationContext: TransformationContext = { enableEmitNotification: noop, enableSubstitution: noop, @@ -265,25 +263,25 @@ namespace ts { case SyntaxKind.ConstructorType: case SyntaxKind.CallSignature: case SyntaxKind.ConstructSignature: - return updateSignatureDeclaration(node - , nodesVisitor((node).typeParameters, visitor, isTypeParameter) - , visitParameterList((node).parameters, visitor, context, nodesVisitor) - , visitNode((node).type, visitor, isTypeNode)); + return updateSignatureDeclaration(node, + nodesVisitor((node).typeParameters, visitor, isTypeParameter), + visitParameterList((node).parameters, visitor, context, nodesVisitor), + visitNode((node).type, visitor, isTypeNode)); case SyntaxKind.MethodSignature: - return updateSignatureDeclaration(node - , nodesVisitor((node).typeParameters, visitor, isTypeParameter) - , visitParameterList((node).parameters, visitor, context, nodesVisitor) - , visitNode((node).type, visitor, isTypeNode) - , visitNode((node).name, visitor, isPropertyName) - , visitNode((node).questionToken, visitor, isToken)); + return updateSignatureDeclaration(node, + nodesVisitor((node).typeParameters, visitor, isTypeParameter), + visitParameterList((node).parameters, visitor, context, nodesVisitor), + visitNode((node).type, visitor, isTypeNode), + visitNode((node).name, visitor, isPropertyName), + visitNode((node).questionToken, visitor, isToken)); case SyntaxKind.IndexSignature: - return updateIndexSignatureDeclaration(node - , visitParameterList((node).parameters, visitor, context, nodesVisitor) - , visitNode((node).type, visitor, isTypeNode) - , nodesVisitor((node).decorators, visitor, isDecorator) - , nodesVisitor((node).modifiers, visitor, isModifier)); + return updateIndexSignatureDeclaration(node, + visitParameterList((node).parameters, visitor, context, nodesVisitor), + visitNode((node).type, visitor, isTypeNode), + nodesVisitor((node).decorators, visitor, isDecorator), + nodesVisitor((node).modifiers, visitor, isModifier)); case SyntaxKind.Parameter: return updateParameter(node, @@ -304,9 +302,9 @@ namespace ts { case SyntaxKind.TypePredicate: throw new Error("reached unsupported type in visitor."); case SyntaxKind.TypeReference: - return updateTypeReferenceNode(node - , visitNode((node).typeName, visitor, isEntityName) - , nodesVisitor((node).typeArguments, visitor, isTypeNode)); + return updateTypeReferenceNode(node, + visitNode((node).typeName, visitor, isEntityName), + nodesVisitor((node).typeArguments, visitor, isTypeNode)); case SyntaxKind.TypeQuery: return updateTypeQueryNode((node), visitNode((node).exprName, visitor, isEntityName)); @@ -322,8 +320,8 @@ namespace ts { case SyntaxKind.UnionType: case SyntaxKind.IntersectionType: - return updateUnionOrIntersectionTypeNode(node - , nodesVisitor((node).types, visitor, isTypeNode)); + return updateUnionOrIntersectionTypeNode(node, + nodesVisitor((node).types, visitor, isTypeNode)); case SyntaxKind.ParenthesizedType: throw new Error("reached unsupported type in visitor."); @@ -332,43 +330,43 @@ namespace ts { case SyntaxKind.TypeOperator: return updateTypeOperatorNode(node, visitNode((node).type, visitor, isTypeNode)); case SyntaxKind.IndexedAccessType: - return updateIndexedAccessTypeNode((node) - , visitNode((node).objectType, visitor, isTypeNode) - , visitNode((node).indexType, visitor, isTypeNode)); + return updateIndexedAccessTypeNode((node), + visitNode((node).objectType, visitor, isTypeNode), + visitNode((node).indexType, visitor, isTypeNode)); case SyntaxKind.MappedType: - return updateMappedTypeNode((node) - , visitNode((node).readonlyToken, visitor, isToken) - , visitNode((node).typeParameter, visitor, isTypeParameter) - , visitNode((node).questionToken, visitor, isToken) - , visitNode((node).type, visitor, isTypeNode)); + return updateMappedTypeNode((node), + visitNode((node).readonlyToken, visitor, isToken), + visitNode((node).typeParameter, visitor, isTypeParameter), + visitNode((node).questionToken, visitor, isToken), + visitNode((node).type, visitor, isTypeNode)); case SyntaxKind.LiteralType: - return updateLiteralTypeNode(node - , visitNode((node).literal, visitor, isExpression)); + return updateLiteralTypeNode(node, + visitNode((node).literal, visitor, isExpression)); // Type Declarations case SyntaxKind.TypeParameter: - return updateTypeParameterDeclaration(node - , visitNode((node).name, visitor, isIdentifier) - , visitNode((node).constraint, visitor, isTypeNode) - , visitNode((node).default, visitor, isTypeNode)); + return updateTypeParameterDeclaration(node, + visitNode((node).name, visitor, isIdentifier), + visitNode((node).constraint, visitor, isTypeNode), + visitNode((node).default, visitor, isTypeNode)); // Type members case SyntaxKind.PropertySignature: - return updatePropertySignature((node) - , visitNode((node).name, visitor, isPropertyName) - , visitNode((node).questionToken, visitor, isToken) - , visitNode((node).type, visitor, isTypeNode) - , visitNode((node).initializer, visitor, isExpression)); + return updatePropertySignature((node), + visitNode((node).name, visitor, isPropertyName), + visitNode((node).questionToken, visitor, isToken), + visitNode((node).type, visitor, isTypeNode), + visitNode((node).initializer, visitor, isExpression)); case SyntaxKind.IndexSignature: - return updateIndexSignatureDeclaration(node - , visitParameterList((node).parameters, visitor, context, nodesVisitor) - , visitNode((node).type, visitor, isTypeNode) - , nodesVisitor((node).decorators, visitor, isDecorator) - , nodesVisitor((node).modifiers, visitor, isModifier)); + return updateIndexSignatureDeclaration(node, + visitParameterList((node).parameters, visitor, context, nodesVisitor), + visitNode((node).type, visitor, isTypeNode), + nodesVisitor((node).decorators, visitor, isDecorator), + nodesVisitor((node).modifiers, visitor, isModifier)); case SyntaxKind.PropertyDeclaration: return updateProperty(node, diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index 5399092757..a67c6791ba 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -44,29 +44,29 @@ namespace ts.codefix { const openBrace = getOpenBraceOfClassLike(classDeclaration, sourceFile); const property = createProperty( - /*decorators*/undefined - , /*modifiers*/ undefined - , token.getText(sourceFile) - , /*questionToken*/ undefined - , typeNode - , /*initializer*/ undefined); + /*decorators*/undefined, + /*modifiers*/ undefined, + token.getText(sourceFile), + /*questionToken*/ undefined, + typeNode, + /*initializer*/ undefined); const propertyChangeTracker = textChanges.ChangeTracker.fromCodeFixContext(context); propertyChangeTracker.insertNodeAfter(sourceFile, openBrace, property, { suffix: context.newLineCharacter }); const stringTypeNode = createKeywordTypeNode(SyntaxKind.StringKeyword); const indexingParameter = createParameter( - /*decorators*/ undefined - , /*modifiers*/ undefined - , /*dotDotDotToken*/ undefined - , "x" - , /*questionToken*/ undefined - , stringTypeNode - , /*initializer*/ undefined); + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, + "x", + /*questionToken*/ undefined, + stringTypeNode, + /*initializer*/ undefined); const indexSignature = createIndexSignatureDeclaration( - [indexingParameter] - , typeNode - , /*decorators*/undefined - , /*modifiers*/ undefined); + [indexingParameter], + typeNode, + /*decorators*/undefined, + /*modifiers*/ undefined); const indexSignatureChangeTracker = textChanges.ChangeTracker.fromCodeFixContext(context); indexSignatureChangeTracker.insertNodeAfter(sourceFile, openBrace, indexSignature, { suffix: context.newLineCharacter }); diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index e642da2159..2d1d76ac8a 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -63,12 +63,12 @@ namespace ts.codefix { case SyntaxKind.PropertyDeclaration: const typeNode = checker.createTypeNode(type, enclosingDeclaration); const property = createProperty( - /*decorators*/undefined - , modifiers - , name - , /*questionToken*/ undefined - , typeNode - , /*initializer*/ undefined); + /*decorators*/undefined, + modifiers, + name, + /*questionToken*/ undefined, + typeNode, + /*initializer*/ undefined); return property; case SyntaxKind.MethodSignature: case SyntaxKind.MethodDeclaration: @@ -97,15 +97,15 @@ namespace ts.codefix { const signature = signatures[i]; const signatureParts = checker.createSignatureParts(signature, enclosingDeclaration); signatureDeclarations.push(createMethod( - /*decorators*/ undefined - , modifiers - , /*asteriskToken*/ undefined - , name - , optional ? createToken(SyntaxKind.QuestionToken) : undefined - , signatureParts.typeParameters - , signatureParts.parameters - , signatureParts.type - , /*body*/undefined)); + /*decorators*/ undefined, + modifiers, + /*asteriskToken*/ undefined, + name, + optional ? createToken(SyntaxKind.QuestionToken) : undefined, + signatureParts.typeParameters, + signatureParts.parameters, + signatureParts.type, + /*body*/undefined)); } if (declarations.length > signatures.length) { @@ -150,59 +150,59 @@ namespace ts.codefix { for (let i = 0; i < maxNonRestArgs; i++) { const anyType = createKeywordTypeNode(SyntaxKind.AnyKeyword); const newParameter = createParameter( - /*decorators*/ undefined - , /*modifiers*/ undefined - , /*dotDotDotToken*/ undefined - , maxArgsParameterSymbolNames[i] - , /*questionToken*/ i >= minArgumentCount ? createToken(SyntaxKind.QuestionToken) : undefined - , anyType - , /*initializer*/ undefined); + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, + maxArgsParameterSymbolNames[i], + /*questionToken*/ i >= minArgumentCount ? createToken(SyntaxKind.QuestionToken) : undefined, + anyType, + /*initializer*/ undefined); parameters.push(newParameter); } if (someSigHasRestParameter) { const anyArrayType = createArrayTypeNode(createKeywordTypeNode(SyntaxKind.AnyKeyword)); const restParameter = createParameter( - /*decorators*/ undefined - , /*modifiers*/ undefined - , createToken(SyntaxKind.DotDotDotToken) - , maxArgsParameterSymbolNames[maxNonRestArgs] || "rest" - , /*questionToken*/ maxNonRestArgs >= minArgumentCount ? createToken(SyntaxKind.QuestionToken) : undefined - , anyArrayType - , /*initializer*/ undefined); + /*decorators*/ undefined, + /*modifiers*/ undefined, + createToken(SyntaxKind.DotDotDotToken), + maxArgsParameterSymbolNames[maxNonRestArgs] || "rest", + /*questionToken*/ maxNonRestArgs >= minArgumentCount ? createToken(SyntaxKind.QuestionToken) : undefined, + anyArrayType, + /*initializer*/ undefined); parameters.push(restParameter); } return createStubbedMethod( - modifiers - , name - , optional - , /*typeParameters*/undefined - , parameters - , /*returnType*/ undefined); + modifiers, + name, + optional, + /*typeParameters*/undefined, + parameters, + /*returnType*/ undefined); } export function createStubbedMethod(modifiers: Modifier[], name: PropertyName, optional: boolean, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], returnType: TypeNode | undefined) { return createMethod( - /*decorators*/undefined - , modifiers - , /*asteriskToken*/undefined - , name - , optional ? createToken(SyntaxKind.QuestionToken) : undefined - , typeParameters - , parameters - , returnType - , createStubbedMethodBody()); + /*decorators*/undefined, + modifiers, + /*asteriskToken*/undefined, + name, + optional ? createToken(SyntaxKind.QuestionToken) : undefined, + typeParameters, + parameters, + returnType, + createStubbedMethodBody()); } function createStubbedMethodBody() { return createBlock( [createThrow( createNew( - createIdentifier('Error') - , /*typeArguments*/undefined - , [createLiteral('Method not implemented.')]))] - , /*multiline*/true); + createIdentifier('Error'), + /*typeArguments*/undefined, + [createLiteral('Method not implemented.')]))], + /*multiline*/true); } function createVisibilityModifier(flags: ModifierFlags) { From d3661f5b6ad801922e11f937c658ce002d2d0109 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Fri, 17 Mar 2017 13:55:39 -0700 Subject: [PATCH 102/164] add tokenVisitor --- src/compiler/core.ts | 3 +++ src/compiler/visitor.ts | 28 ++++++++++++++-------------- src/services/textChanges.ts | 2 +- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index c380a39611..3f466e726d 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1067,6 +1067,9 @@ namespace ts { /** Does nothing. */ export function noop(): void {} + /** Returns its first argument. */ + export function identity(x: X): X { return x; } + /** Throws an error because a function is not implemented. */ export function notImplemented(): never { throw new Error("Not implemented"); diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 44b994ce57..57de104b0c 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -224,9 +224,9 @@ namespace ts { * @param visitor The callback used to visit each child. * @param context A lexical environment context for the visitor. */ - export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes): T | undefined; + export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined; - export function visitEachChild(node: Node, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes): Node { + export function visitEachChild(node: Node, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes, tokenVisitor?: Visitor): Node { if (node === undefined) { return undefined; } @@ -274,7 +274,7 @@ namespace ts { visitParameterList((node).parameters, visitor, context, nodesVisitor), visitNode((node).type, visitor, isTypeNode), visitNode((node).name, visitor, isPropertyName), - visitNode((node).questionToken, visitor, isToken)); + visitNode((node).questionToken, tokenVisitor, isToken)); case SyntaxKind.IndexSignature: return updateIndexSignatureDeclaration(node, @@ -287,9 +287,9 @@ namespace ts { return updateParameter(node, nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), - visitNode((node).dotDotDotToken, visitor), + visitNode((node).dotDotDotToken, tokenVisitor, isToken), visitNode((node).name, visitor, isBindingName), - visitNode((node).questionToken, visitor, isToken), + visitNode((node).questionToken, tokenVisitor, isToken), visitNode((node).type, visitor, isTypeNode), visitNode((node).initializer, visitor, isExpression)); @@ -335,9 +335,9 @@ namespace ts { visitNode((node).indexType, visitor, isTypeNode)); case SyntaxKind.MappedType: return updateMappedTypeNode((node), - visitNode((node).readonlyToken, visitor, isToken), + visitNode((node).readonlyToken, tokenVisitor, isToken), visitNode((node).typeParameter, visitor, isTypeParameter), - visitNode((node).questionToken, visitor, isToken), + visitNode((node).questionToken, tokenVisitor, isToken), visitNode((node).type, visitor, isTypeNode)); case SyntaxKind.LiteralType: @@ -357,7 +357,7 @@ namespace ts { case SyntaxKind.PropertySignature: return updatePropertySignature((node), visitNode((node).name, visitor, isPropertyName), - visitNode((node).questionToken, visitor, isToken), + visitNode((node).questionToken, tokenVisitor, isToken), visitNode((node).type, visitor, isTypeNode), visitNode((node).initializer, visitor, isExpression)); @@ -380,9 +380,9 @@ namespace ts { return updateMethod(node, nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), - visitNode((node).asteriskToken, visitor, isToken), + visitNode((node).asteriskToken, tokenVisitor, isToken), visitNode((node).name, visitor, isPropertyName), - visitNode((node).questionToken, visitor, isToken), + visitNode((node).questionToken, tokenVisitor, isToken), nodesVisitor((node).typeParameters, visitor, isTypeParameter), visitParameterList((node).parameters, visitor, context, nodesVisitor), visitNode((node).type, visitor, isTypeNode), @@ -423,7 +423,7 @@ namespace ts { case SyntaxKind.BindingElement: return updateBindingElement(node, - (node).dotDotDotToken, + visitNode((node).dotDotDotToken, tokenVisitor, isToken), visitNode((node).propertyName, visitor, isPropertyName), visitNode((node).name, visitor, isBindingName), visitNode((node).initializer, visitor, isExpression)); @@ -476,7 +476,7 @@ namespace ts { case SyntaxKind.FunctionExpression: return updateFunctionExpression(node, nodesVisitor((node).modifiers, visitor, isModifier), - (node).asteriskToken, + visitNode((node).asteriskToken, tokenVisitor, isToken), visitNode((node).name, visitor, isIdentifier), nodesVisitor((node).typeParameters, visitor, isTypeParameter), visitParameterList((node).parameters, visitor, context, nodesVisitor), @@ -533,7 +533,7 @@ namespace ts { case SyntaxKind.YieldExpression: return updateYield(node, - (node).asteriskToken, + visitNode((node).asteriskToken, tokenVisitor, isToken), visitNode((node).expression, visitor, isExpression)); case SyntaxKind.SpreadElement: @@ -669,7 +669,7 @@ namespace ts { return updateFunctionDeclaration(node, nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), - (node).asteriskToken, + visitNode((node).asteriskToken, tokenVisitor, isToken), visitNode((node).name, visitor, isIdentifier), nodesVisitor((node).typeParameters, visitor, isTypeParameter), visitParameterList((node).parameters, visitor, context, nodesVisitor), diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index b7a8b101c0..ddcbf2fa2f 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -529,7 +529,7 @@ namespace ts.textChanges { } function assignPositionsToNode(node: Node): Node { - const visited = visitEachChild(node, assignPositionsToNode, nullTransformationContext, assignPositionsToNodeArray); + const visited = visitEachChild(node, assignPositionsToNode, nullTransformationContext, assignPositionsToNodeArray, assignPositionsToNode); // create proxy node for non synthesized nodes const newNode = nodeIsSynthesized(visited) ? visited From ff061a1b934406a41f0fe5f3d95be5fae5793743 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Fri, 17 Mar 2017 14:56:04 -0700 Subject: [PATCH 103/164] consolidate edits --- ...sDoesntImplementInheritedAbstractMember.ts | 2 +- .../fixClassIncorrectlyImplementsInterface.ts | 4 ++-- src/services/codefixes/helpers.ts | 21 ++++++++++++++----- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts index 513853e461..62f89b1a21 100644 --- a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts +++ b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts @@ -31,7 +31,7 @@ namespace ts.codefix { const newNodes = createMissingMemberNodes(classDeclaration, abstractAndNonPrivateExtendsSymbols, checker); const changes = newNodesToChanges(newNodes, getOpenBraceOfClassLike(classDeclaration, sourceFile), context); - if(changes && changes.length > 0) { + if (changes && changes.length > 0) { return [{ description: getLocaleSpecificMessage(Diagnostics.Implement_inherited_abstract_class), changes diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts index de34676eda..365fd35801 100644 --- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts +++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts @@ -45,13 +45,13 @@ namespace ts.codefix { function createAndAddMissingIndexSignatureDeclaration(type: InterfaceType, kind: IndexKind, hasIndexSigOfKind: boolean, newNodes: Node[]): void { if (hasIndexSigOfKind) { - return undefined; + return; } const indexInfoOfKind = checker.getIndexInfoOfType(type, kind); if (!indexInfoOfKind) { - return undefined; + return; } const newIndexSignatureDeclaration = checker.createIndexSignatureFromIndexInfo(indexInfoOfKind, kind, classDeclaration); newNodes.push(newIndexSignatureDeclaration); diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 2d1d76ac8a..4a9ee25228 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -3,17 +3,28 @@ namespace ts.codefix { export function newNodesToChanges(newNodes: Node[], insertAfter: Node, context: CodeFixContext) { const sourceFile = context.sourceFile; - if (!(newNodes)) { - throw new Error("newNodesToChanges expects an array"); - } const changeTracker = textChanges.ChangeTracker.fromCodeFixContext(context); for (const newNode of newNodes) { changeTracker.insertNodeAfter(sourceFile, insertAfter, newNode, { suffix: context.newLineCharacter }); } - // TODO (aozgaa): concatenate changes into a single change. - return changeTracker.getChanges(); + + const changes = changeTracker.getChanges(); + if (!(changes && changes.length > 0)) { + return changes; + } + + Debug.assert(changes.length === 1); + const consolidatedChanges: FileTextChanges[] = [{ + fileName: changes[0].fileName, + textChanges: [{ + span: changes[0].textChanges[0].span, + newText: changes[0].textChanges.reduce((prev, cur) => prev + cur.newText, "") + }] + + }] + return consolidatedChanges; } /** From b8aa84e8bf53f0c4ee2c5d590ba76831172545a7 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Fri, 3 Mar 2017 14:36:16 -0800 Subject: [PATCH 104/164] Use more specific types in a few cases --- src/compiler/factory.ts | 2 +- src/compiler/parser.ts | 5 +++-- src/compiler/types.ts | 23 ++++++++++------------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 669c66c433..453cd04114 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1486,7 +1486,7 @@ namespace ts { // Clauses - export function createHeritageClause(token: SyntaxKind, types: ExpressionWithTypeArguments[]) { + export function createHeritageClause(token: HeritageClause["token"], types: ExpressionWithTypeArguments[]) { const node = createSynthesizedNode(SyntaxKind.HeritageClause); node.token = token; node.types = createNodeArray(types); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index f2175f385e..ee74ce9c9a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5437,9 +5437,10 @@ namespace ts { } function parseHeritageClause(): HeritageClause | undefined { - if (token() === SyntaxKind.ExtendsKeyword || token() === SyntaxKind.ImplementsKeyword) { + const tok = token(); + if (tok === SyntaxKind.ExtendsKeyword || tok === SyntaxKind.ImplementsKeyword) { const node = createNode(SyntaxKind.HeritageClause); - node.token = token(); + node.token = tok; nextToken(); node.types = parseDelimitedList(ParsingContext.HeritageClauseElement, parseExpressionWithTypeArguments); return finishNode(node); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a7adf28ac8..f5bec267ed 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -863,15 +863,13 @@ namespace ts { kind: SyntaxKind.ThisType; } - export interface FunctionOrConstructorTypeNode extends TypeNode, SignatureDeclaration { - kind: SyntaxKind.FunctionType | SyntaxKind.ConstructorType; - } + export type FunctionOrConstructorTypeNode = FunctionTypeNode | ConstructorTypeNode; - export interface FunctionTypeNode extends FunctionOrConstructorTypeNode { + export interface FunctionTypeNode extends TypeNode, SignatureDeclaration { kind: SyntaxKind.FunctionType; } - export interface ConstructorTypeNode extends FunctionOrConstructorTypeNode { + export interface ConstructorTypeNode extends TypeNode, SignatureDeclaration { kind: SyntaxKind.ConstructorType; } @@ -908,17 +906,16 @@ namespace ts { elementTypes: NodeArray; } - export interface UnionOrIntersectionTypeNode extends TypeNode { - kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType; + export type UnionOrIntersectionTypeNode = UnionTypeNode | IntersectionTypeNode; + + export interface UnionTypeNode extends TypeNode { + kind: SyntaxKind.UnionType; types: NodeArray; } - export interface UnionTypeNode extends UnionOrIntersectionTypeNode { - kind: SyntaxKind.UnionType; - } - - export interface IntersectionTypeNode extends UnionOrIntersectionTypeNode { + export interface IntersectionTypeNode extends TypeNode { kind: SyntaxKind.IntersectionType; + types: NodeArray; } export interface ParenthesizedTypeNode extends TypeNode { @@ -1779,7 +1776,7 @@ namespace ts { export interface HeritageClause extends Node { kind: SyntaxKind.HeritageClause; parent?: InterfaceDeclaration | ClassDeclaration | ClassExpression; - token: SyntaxKind; + token: SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword; types?: NodeArray; } From 0c1642a8b778e9f117beb341b3b0ba20f4c5ca7d Mon Sep 17 00:00:00 2001 From: Mine Starks Date: Mon, 20 Mar 2017 16:07:20 -0700 Subject: [PATCH 105/164] Allow specifying location of typingSafeList.json --- src/server/server.ts | 10 +++++++++- src/server/shared.ts | 1 + src/server/typingsInstaller/nodeTypingsInstaller.ts | 7 ++++--- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/server/server.ts b/src/server/server.ts index 4e443add77..e80b6f6b7b 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -219,6 +219,7 @@ namespace ts.server { host: ServerHost, eventPort: number, readonly globalTypingsCacheLocation: string, + readonly typingSafeListLocation: string, private newLine: string) { this.throttledOperations = new ThrottledOperations(host); if (eventPort) { @@ -260,6 +261,9 @@ namespace ts.server { if (this.logger.loggingEnabled() && this.logger.getLogFileName()) { args.push(Arguments.LogFile, combinePaths(getDirectoryPath(normalizeSlashes(this.logger.getLogFileName())), `ti-${process.pid}.log`)); } + if (this.typingSafeListLocation) { + args.push(Arguments.TypingSafeListLocation, this.typingSafeListLocation); + } const execArgv: string[] = []; { for (const arg of process.execArgv) { @@ -378,11 +382,12 @@ namespace ts.server { useSingleInferredProject: boolean, disableAutomaticTypingAcquisition: boolean, globalTypingsCacheLocation: string, + typingSafeListLocation: string, telemetryEnabled: boolean, logger: server.Logger) { const typingsInstaller = disableAutomaticTypingAcquisition ? undefined - : new NodeTypingsInstaller(telemetryEnabled, logger, host, installerEventPort, globalTypingsCacheLocation, host.newLine); + : new NodeTypingsInstaller(telemetryEnabled, logger, host, installerEventPort, globalTypingsCacheLocation, typingSafeListLocation, host.newLine); super( host, @@ -728,6 +733,8 @@ namespace ts.server { if (localeStr) { validateLocaleAndSetLanguage(localeStr, sys); } + + const typingSafeListLocation = findArgument("--typingSafeListLocation"); const useSingleInferredProject = hasArgument("--useSingleInferredProject"); const disableAutomaticTypingAcquisition = hasArgument("--disableAutomaticTypingAcquisition"); @@ -741,6 +748,7 @@ namespace ts.server { useSingleInferredProject, disableAutomaticTypingAcquisition, getGlobalTypingsCacheLocation(), + typingSafeListLocation, telemetryEnabled, logger); process.on("uncaughtException", function (err: Error) { diff --git a/src/server/shared.ts b/src/server/shared.ts index 5d65f8c90e..6dcf888192 100644 --- a/src/server/shared.ts +++ b/src/server/shared.ts @@ -11,6 +11,7 @@ namespace ts.server { export const GlobalCacheLocation = "--globalTypingsCacheLocation"; export const LogFile = "--logFile"; export const EnableTelemetry = "--enableTelemetry"; + export const TypingSafeListLocation = "--typingSafeListLocation"; } export function hasArgument(argumentName: string) { diff --git a/src/server/typingsInstaller/nodeTypingsInstaller.ts b/src/server/typingsInstaller/nodeTypingsInstaller.ts index 0a9d8ee29f..1018b37d90 100644 --- a/src/server/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/server/typingsInstaller/nodeTypingsInstaller.ts @@ -76,11 +76,11 @@ namespace ts.server.typingsInstaller { private delayedInitializationError: InitializationFailedResponse; - constructor(globalTypingsCacheLocation: string, throttleLimit: number, log: Log) { + constructor(globalTypingsCacheLocation: string, typingSafeListLocation: string, throttleLimit: number, log: Log) { super( sys, globalTypingsCacheLocation, - toPath("typingSafeList.json", __dirname, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)), + typingSafeListLocation ? toPath(typingSafeListLocation, "", createGetCanonicalFileName(sys.useCaseSensitiveFileNames)) : toPath("typingSafeList.json", __dirname, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)), throttleLimit, log); if (this.log.isEnabled()) { @@ -164,6 +164,7 @@ namespace ts.server.typingsInstaller { const logFilePath = findArgument(server.Arguments.LogFile); const globalTypingsCacheLocation = findArgument(server.Arguments.GlobalCacheLocation); + const typingSafeListLocation = findArgument(server.Arguments.TypingSafeListLocation); const log = new FileLog(logFilePath); if (log.isEnabled()) { @@ -177,6 +178,6 @@ namespace ts.server.typingsInstaller { } process.exit(0); }); - const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, /*throttleLimit*/5, log); + const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, typingSafeListLocation, /*throttleLimit*/5, log); installer.listen(); } \ No newline at end of file From a8ffb5cad97e6cf04d8042e69dd6594c08b4633e Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 21 Mar 2017 07:26:47 -0700 Subject: [PATCH 106/164] Address code review --- ...ckUsedBeforeDefinitionInFunctionDeclaration.js | 15 +++++++++++++++ ...dBeforeDefinitionInFunctionDeclaration.symbols | 10 ++++++++++ ...sedBeforeDefinitionInFunctionDeclaration.types | 11 +++++++++++ ...eclarationCheckUsedBeforeDefinitionInItself.js | 9 +++++++++ ...ationCheckUsedBeforeDefinitionInItself.symbols | 8 ++++++++ ...arationCheckUsedBeforeDefinitionInItself.types | 9 +++++++++ ...ckUsedBeforeDefinitionInFunctionDeclaration.ts | 4 ++++ ...eclarationCheckUsedBeforeDefinitionInItself.ts | 4 ++++ 8 files changed, 70 insertions(+) create mode 100644 tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.js create mode 100644 tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.symbols create mode 100644 tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.types create mode 100644 tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInItself.js create mode 100644 tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInItself.symbols create mode 100644 tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInItself.types create mode 100644 tests/cases/compiler/classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.ts create mode 100644 tests/cases/compiler/classDeclarationCheckUsedBeforeDefinitionInItself.ts diff --git a/tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.js b/tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.js new file mode 100644 index 0000000000..195cd78f35 --- /dev/null +++ b/tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.js @@ -0,0 +1,15 @@ +//// [classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.ts] +function f() { + new C2(); // OK +} +class C2 { } + +//// [classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.js] +function f() { + new C2(); // OK +} +var C2 = (function () { + function C2() { + } + return C2; +}()); diff --git a/tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.symbols b/tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.symbols new file mode 100644 index 0000000000..19e4620b5c --- /dev/null +++ b/tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.symbols @@ -0,0 +1,10 @@ +=== tests/cases/compiler/classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.ts === +function f() { +>f : Symbol(f, Decl(classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.ts, 0, 0)) + + new C2(); // OK +>C2 : Symbol(C2, Decl(classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.ts, 2, 1)) +} +class C2 { } +>C2 : Symbol(C2, Decl(classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.ts, 2, 1)) + diff --git a/tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.types b/tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.types new file mode 100644 index 0000000000..6255006523 --- /dev/null +++ b/tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.types @@ -0,0 +1,11 @@ +=== tests/cases/compiler/classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.ts === +function f() { +>f : () => void + + new C2(); // OK +>new C2() : C2 +>C2 : typeof C2 +} +class C2 { } +>C2 : C2 + diff --git a/tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInItself.js b/tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInItself.js new file mode 100644 index 0000000000..b3a3d25a81 --- /dev/null +++ b/tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInItself.js @@ -0,0 +1,9 @@ +//// [classDeclarationCheckUsedBeforeDefinitionInItself.ts] +class C3 { + static intance = new C3(); // ok +} + +//// [classDeclarationCheckUsedBeforeDefinitionInItself.js] +class C3 { +} +C3.intance = new C3(); // ok diff --git a/tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInItself.symbols b/tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInItself.symbols new file mode 100644 index 0000000000..f0e6f2a5a7 --- /dev/null +++ b/tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInItself.symbols @@ -0,0 +1,8 @@ +=== tests/cases/compiler/classDeclarationCheckUsedBeforeDefinitionInItself.ts === +class C3 { +>C3 : Symbol(C3, Decl(classDeclarationCheckUsedBeforeDefinitionInItself.ts, 0, 0)) + + static intance = new C3(); // ok +>intance : Symbol(C3.intance, Decl(classDeclarationCheckUsedBeforeDefinitionInItself.ts, 0, 10)) +>C3 : Symbol(C3, Decl(classDeclarationCheckUsedBeforeDefinitionInItself.ts, 0, 0)) +} diff --git a/tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInItself.types b/tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInItself.types new file mode 100644 index 0000000000..e4f36dda38 --- /dev/null +++ b/tests/baselines/reference/classDeclarationCheckUsedBeforeDefinitionInItself.types @@ -0,0 +1,9 @@ +=== tests/cases/compiler/classDeclarationCheckUsedBeforeDefinitionInItself.ts === +class C3 { +>C3 : C3 + + static intance = new C3(); // ok +>intance : C3 +>new C3() : C3 +>C3 : typeof C3 +} diff --git a/tests/cases/compiler/classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.ts b/tests/cases/compiler/classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.ts new file mode 100644 index 0000000000..cf09163ed5 --- /dev/null +++ b/tests/cases/compiler/classDeclarationCheckUsedBeforeDefinitionInFunctionDeclaration.ts @@ -0,0 +1,4 @@ +function f() { + new C2(); // OK +} +class C2 { } \ No newline at end of file diff --git a/tests/cases/compiler/classDeclarationCheckUsedBeforeDefinitionInItself.ts b/tests/cases/compiler/classDeclarationCheckUsedBeforeDefinitionInItself.ts new file mode 100644 index 0000000000..389c669e74 --- /dev/null +++ b/tests/cases/compiler/classDeclarationCheckUsedBeforeDefinitionInItself.ts @@ -0,0 +1,4 @@ +// @target: es6 +class C3 { + static intance = new C3(); // ok +} \ No newline at end of file From bb5b20b587d89a01d2e4a3bb8235205553006e38 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 21 Mar 2017 08:07:11 -0700 Subject: [PATCH 107/164] Address code review --- src/compiler/checker.ts | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 56306fb772..56b3a0704b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14964,11 +14964,10 @@ namespace ts { } else { let yieldTypes: Type[]; - let returnTypes: Type[]; + let types: Type[]; if (functionFlags & FunctionFlags.Generator) { // Generator or AsyncGenerator function - yieldTypes = checkAndAggregateYieldOperandTypes(func, contextualMapper); - returnTypes = checkAndAggregateReturnExpressionTypes(func, contextualMapper); - if (yieldTypes.length === 0 && (!returnTypes || returnTypes.length === 0)) { + types = concatenate(checkAndAggregateYieldOperandTypes(func, contextualMapper), checkAndAggregateReturnExpressionTypes(func, contextualMapper)); + if (!types || types.length === 0) { const iterableIteratorAny = functionFlags & FunctionFlags.Async ? createAsyncIterableIteratorType(anyType) // AsyncGenerator function : createIterableIteratorType(anyType); // Generator function @@ -14980,14 +14979,14 @@ namespace ts { } } else { - returnTypes = checkAndAggregateReturnExpressionTypes(func, contextualMapper); - if (!returnTypes) { + types = checkAndAggregateReturnExpressionTypes(func, contextualMapper); + if (!types) { // For an async function, the return type will not be never, but rather a Promise for never. return functionFlags & FunctionFlags.Async ? createPromiseReturnType(func, neverType) // Async function : neverType; // Normal function } - if (returnTypes.length === 0) { + if (types.length === 0) { // For an async function, the return type will not be void, but rather a Promise for void. return functionFlags & FunctionFlags.Async ? createPromiseReturnType(func, voidType) // Async function @@ -14995,7 +14994,7 @@ namespace ts { } } // Return a union of the return expression types. - type = getUnionType(yieldTypes ? yieldTypes.concat(returnTypes) : returnTypes, /*subtypeReduction*/ true); + type = getUnionType(yieldTypes ? yieldTypes.concat(types) : types, /*subtypeReduction*/ true); if (functionFlags & FunctionFlags.Generator) { // AsyncGenerator function or Generator function type = functionFlags & FunctionFlags.Async From 71e52dea923670fac1b8373ec041009bd0cc95ba Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 21 Mar 2017 08:38:01 -0700 Subject: [PATCH 108/164] finish remove unused yieldTypes --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f550fcf9c3..43311c81f7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15138,7 +15138,7 @@ namespace ts { } } // Return a union of the return expression types. - type = getUnionType(yieldTypes ? yieldTypes.concat(types) : types, /*subtypeReduction*/ true); + type = getUnionType(types, /*subtypeReduction*/ true); if (functionFlags & FunctionFlags.Generator) { // AsyncGenerator function or Generator function type = functionFlags & FunctionFlags.Async From 1b2cd3e01a7bfa7e3986f9d95c56db79e5e722c9 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Mon, 20 Mar 2017 07:28:55 -0700 Subject: [PATCH 109/164] Remove unused test files --- Gulpfile.ts | 2 +- Jakefile.js | 2 +- .../formatting/documentFormattingTests.json | 80 ---- .../formatting/formatDiffTemplate.html | 66 --- .../formatting/getFormattingEditsForRange.ts | 88 ---- .../formatting/getSmartIndentAtLineNumber.ts | 410 ------------------ .../importedJavaScriptFormatting.ts | 212 --------- .../formatting/ruleFormattingTests.json | 284 ------------ .../formatting/testCode/formatting/classes.ts | 79 ---- .../testCode/formatting/classesBaseline.ts | 79 ---- .../testCode/formatting/colonAndQMark.ts | 4 - .../formatting/colonAndQMarkBaseline.ts | 4 - .../formatting/documentReadyFunction.ts | 3 - .../documentReadyFunctionBaseLine.ts | 3 - .../testCode/formatting/emptyBlock.ts | 1 - .../testCode/formatting/emptyBlockBaseline.ts | 1 - .../formatting/emptyInterfaceLiteral.ts | 10 - .../emptyInterfaceLiteralBaseLine.ts | 10 - .../testCode/formatting/fatArrowFunctions.ts | 112 ----- .../formatting/fatArrowFunctionsBaseline.ts | 112 ----- .../formatting/formatDebuggerStatement.ts | 2 - .../formatDebuggerStatementBaseline.ts | 2 - .../formatvariableDeclarationList.ts | 13 - .../formatvariableDeclarationListBaseline.ts | 13 - .../testCode/formatting/implicitModule.ts | 3 - .../formatting/implicitModuleBaseline.ts | 3 - .../testCode/formatting/importDeclaration.ts | 6 - .../formatting/importDeclarationBaseline.ts | 6 - .../formatting/testCode/formatting/main.ts | 95 ---- .../testCode/formatting/mainBaseline.ts | 98 ----- .../testCode/formatting/moduleIndentation.ts | 3 - .../formatting/moduleIndentationBaseline.ts | 3 - .../formatting/testCode/formatting/modules.ts | 76 ---- .../testCode/formatting/modulesBaseline.ts | 76 ---- .../testCode/formatting/objectLiteral.ts | 27 -- .../formatting/objectLiteralBaseline.ts | 31 -- .../testCode/formatting/onClosingBracket.ts | 32 -- .../formatting/onClosingBracketBaseLine.ts | 28 -- .../testCode/formatting/onSemiColon.ts | 1 - .../formatting/onSemiColonBaseline.ts | 1 - .../formatting/spaceAfterConstructor.ts | 1 - .../spaceAfterConstructorBaseline.ts | 1 - .../testCode/formatting/tabAfterCloseCurly.ts | 10 - .../formatting/tabAfterCloseCurlyBaseline.ts | 9 - .../formatting/typescriptConstructs.ts | 65 --- .../typescriptConstructsBaseline.ts | 58 --- .../formatting/testCode/formatting/various.ts | 17 - .../testCode/formatting/variousBaseline.ts | 17 - .../testCode/formatting/withStatement.ts | 9 - .../formatting/withStatementBaseline.ts | 6 - .../fourslash_old/callOrderDependence.ts | 9 - .../chainedFunctionCallsErrorSpan.ts | 5 - .../completionListGenericConstraintsNames.ts | 24 - .../completionListInTypedObjectLiterals.ts | 142 ------ ...onstructorOverloadWithoutImplementation.ts | 9 - ...nstructorOverloadWithoutImplementation2.ts | 9 - .../fourslash_old/exportEqualIncremental.ts | 20 - tests/cases/fourslash_old/findReferences.ts | 62 --- tests/cases/fourslash_old/findReferences1.ts | 28 -- .../fourslash_old/findReferencesAliases1.ts | 20 - .../fourslash_old/findReferencesModules1.ts | 27 -- .../funduleDefinedInADifferentFile.ts | 12 - .../funduleDefinedInADifferentFile2.ts | 29 -- .../fourslash_old/genericIncrementalParse.ts | 30 -- .../genericStructuralTypeConstraint.ts | 37 -- .../getTypeOfUnresolvedGenericExtension.ts | 10 - .../fourslash_old/overloadResolutionErrors.ts | 38 -- tests/cases/fourslash_old/thisRefGotoDef.ts | 12 - 68 files changed, 2 insertions(+), 2795 deletions(-) delete mode 100644 src/harness/unittests/services/formatting/documentFormattingTests.json delete mode 100644 src/harness/unittests/services/formatting/formatDiffTemplate.html delete mode 100644 src/harness/unittests/services/formatting/getFormattingEditsForRange.ts delete mode 100644 src/harness/unittests/services/formatting/getSmartIndentAtLineNumber.ts delete mode 100644 src/harness/unittests/services/formatting/importedJavaScriptFormatting.ts delete mode 100644 src/harness/unittests/services/formatting/ruleFormattingTests.json delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/classes.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/classesBaseline.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/colonAndQMark.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/colonAndQMarkBaseline.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/documentReadyFunction.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/documentReadyFunctionBaseLine.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/emptyBlock.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/emptyBlockBaseline.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/emptyInterfaceLiteral.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/emptyInterfaceLiteralBaseLine.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/fatArrowFunctions.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/fatArrowFunctionsBaseline.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/formatDebuggerStatement.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/formatDebuggerStatementBaseline.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/formatvariableDeclarationList.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/formatvariableDeclarationListBaseline.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/implicitModule.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/implicitModuleBaseline.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/importDeclaration.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/importDeclarationBaseline.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/main.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/mainBaseline.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/moduleIndentation.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/moduleIndentationBaseline.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/modules.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/modulesBaseline.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/objectLiteral.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/objectLiteralBaseline.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/onClosingBracket.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/onClosingBracketBaseLine.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/onSemiColon.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/onSemiColonBaseline.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/spaceAfterConstructor.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/spaceAfterConstructorBaseline.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/tabAfterCloseCurly.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/tabAfterCloseCurlyBaseline.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/typescriptConstructs.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/typescriptConstructsBaseline.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/various.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/variousBaseline.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/withStatement.ts delete mode 100644 src/harness/unittests/services/formatting/testCode/formatting/withStatementBaseline.ts delete mode 100644 tests/cases/fourslash_old/callOrderDependence.ts delete mode 100644 tests/cases/fourslash_old/chainedFunctionCallsErrorSpan.ts delete mode 100644 tests/cases/fourslash_old/completionListGenericConstraintsNames.ts delete mode 100644 tests/cases/fourslash_old/completionListInTypedObjectLiterals.ts delete mode 100644 tests/cases/fourslash_old/constructorOverloadWithoutImplementation.ts delete mode 100644 tests/cases/fourslash_old/constructorOverloadWithoutImplementation2.ts delete mode 100644 tests/cases/fourslash_old/exportEqualIncremental.ts delete mode 100644 tests/cases/fourslash_old/findReferences.ts delete mode 100644 tests/cases/fourslash_old/findReferences1.ts delete mode 100644 tests/cases/fourslash_old/findReferencesAliases1.ts delete mode 100644 tests/cases/fourslash_old/findReferencesModules1.ts delete mode 100644 tests/cases/fourslash_old/funduleDefinedInADifferentFile.ts delete mode 100644 tests/cases/fourslash_old/funduleDefinedInADifferentFile2.ts delete mode 100644 tests/cases/fourslash_old/genericIncrementalParse.ts delete mode 100644 tests/cases/fourslash_old/genericStructuralTypeConstraint.ts delete mode 100644 tests/cases/fourslash_old/getTypeOfUnresolvedGenericExtension.ts delete mode 100644 tests/cases/fourslash_old/overloadResolutionErrors.ts delete mode 100644 tests/cases/fourslash_old/thisRefGotoDef.ts diff --git a/Gulpfile.ts b/Gulpfile.ts index 296e374a53..022606e133 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -1024,7 +1024,7 @@ gulp.task("lint", "Runs tslint on the compiler sources. Optional arguments are: const fileMatcher = cmdLineOptions["files"]; const files = fileMatcher ? `src/**/${fileMatcher}` - : "Gulpfile.ts 'src/**/*.ts' --exclude src/lib/es5.d.ts --exclude 'src/lib/*.generated.d.ts' --exclude 'src/harness/unittests/services/**/*.ts'"; + : "Gulpfile.ts 'src/**/*.ts' --exclude src/lib/es5.d.ts --exclude 'src/lib/*.generated.d.ts'"; const cmd = `node node_modules/tslint/bin/tslint ${files} --format stylish`; console.log("Linting: " + cmd); child_process.execSync(cmd, { stdio: [0, 1, 2] }); diff --git a/Jakefile.js b/Jakefile.js index 9c2b3d38d1..100ebc63f4 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -1182,7 +1182,7 @@ task("lint", ["build-rules"], () => { const fileMatcher = process.env.f || process.env.file || process.env.files; const files = fileMatcher ? `src/**/${fileMatcher}` - : "Gulpfile.ts 'src/**/*.ts' --exclude src/lib/es5.d.ts --exclude 'src/lib/*.generated.d.ts' --exclude 'src/harness/unittests/services/**/*.ts'"; + : "Gulpfile.ts 'src/**/*.ts' --exclude src/lib/es5.d.ts --exclude 'src/lib/*.generated.d.ts'"; const cmd = `node node_modules/tslint/bin/tslint ${files} --format stylish`; console.log("Linting: " + cmd); jake.exec([cmd], { interactive: true }, () => { diff --git a/src/harness/unittests/services/formatting/documentFormattingTests.json b/src/harness/unittests/services/formatting/documentFormattingTests.json deleted file mode 100644 index f7d48dba8c..0000000000 --- a/src/harness/unittests/services/formatting/documentFormattingTests.json +++ /dev/null @@ -1,80 +0,0 @@ -{ input: "function foo () {}", rules: [ ], span: { start: 0, length: 20 }, expected: "function foo() { }" }, -{ input: "var a = (0);\r\na = (1 % 2);\r\nvar b = new Array(1, 2);\r\nfunction c(d) {\r\n try { }\r\n catch (e) { }\r\n for (f = 0; f < 10; ++f) { }\r\n for (g in h) { }\r\n if (true) {\r\n } else if (false) { }\r\n switch (i) {\r\n case (0):\r\n break;\r\n }\r\n do { } while (true);\r\n with (j) {\r\n }\r\n delete (h);\r\n void (i);\r\n}", rules: [ "SpaceAfterOpenParen", "SpaceBeforeCloseParen", "NoSpaceBetweenParens" ], span: { start: 0, length: 349 }, expected: "var a = ( 0 );\r\na = ( 1 % 2 );\r\nvar b = new Array( 1, 2 );\r\nfunction c( d ) {\r\n try { }\r\n catch ( e ) { }\r\n for ( f = 0; f < 10; ++f ) { }\r\n for ( g in h ) { }\r\n if ( true ) {\r\n } else if ( false ) { }\r\n switch ( i ) {\r\n case ( 0 ):\r\n break;\r\n }\r\n do { } while ( true );\r\n with ( j ) {\r\n }\r\n delete ( h );\r\n void ( i );\r\n}" }, -{ input: "var a = ( 0 );\r\na = ( 1 % 2 );\r\nvar b = new Array( 1, 2 );\r\nfunction c( d ) {\r\n try { }\r\n catch ( e ) { }\r\n for ( f = 0; f < 10; ++f ) { }\r\n for ( g in h ) { }\r\n if ( true ) {\r\n } else if ( false ) { }\r\n switch ( i ) {\r\n case ( 0 ):\r\n break;\r\n }\r\n do { } while ( true );\r\n with ( j ) {\r\n }\r\n delete ( h );\r\n void ( i );\r\n}", rules: [ "NoSpaceAfterOpenParen", "NoSpaceBeforeCloseParen", "NoSpaceBetweenParens" ], span: { start: 0, length: 379 }, expected: "var a = (0);\r\na = (1 % 2);\r\nvar b = new Array(1, 2);\r\nfunction c(d) {\r\n try { }\r\n catch (e) { }\r\n for (f = 0; f < 10; ++f) { }\r\n for (g in h) { }\r\n if (true) {\r\n } else if (false) { }\r\n switch (i) {\r\n case (0):\r\n break;\r\n }\r\n do { } while (true);\r\n with (j) {\r\n }\r\n delete (h);\r\n void (i);\r\n}" }, -{ input: "this . alert( \"Hello, World!\" );", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 32 }, expected: "this.alert( \"Hello, World!\" );" }, -{ input: "a\r\n;b;", rules: [ ], span: { start: 0, length: 6 }, expected: "a\r\n; b;" }, -{ input: "a\r\n; b;", rules: [ ], span: { start: 0, length: 8 }, expected: "a\r\n; b;" }, -{ input: "var a , b;\r\nf(a , b);", rules: [ ], span: { start: 0, length: 40 }, expected: "var a, b;\r\nf(a, b);" }, -{ input: "function a() {\r\n while(false)\r\n switch(b) { }\r\n\r\n for(c in d)\r\n if(c)\r\n break;\r\n\r\n do { } while(true);\r\n with(f)\r\n g = null;\r\n}", rules: [ "SpaceAfterKeywordInControl" ], span: { start: 0, length: 171 }, expected: "function a() {\r\n while (false)\r\n switch (b) { }\r\n\r\n for (c in d)\r\n if (c)\r\n break;\r\n\r\n do { } while (true);\r\n with (f)\r\n g = null;\r\n}" }, -{ input: "function a() {\r\n while (false)\r\n switch (b) { }\r\n\r\n for (c in d)\r\n if (c)\r\n break;\r\n\r\n do { } while (true);\r\n with (f)\r\n g = null;\r\n}", rules: [ "NoSpaceAfterKeywordInControl" ], span: { start: 0, length: 177 }, expected: "function a() {\r\n while(false)\r\n switch(b) { }\r\n\r\n for(c in d)\r\n if(c)\r\n break;\r\n\r\n do { } while(true);\r\n with(f)\r\n g = null;\r\n}" }, -{ input: "{\r\n(a);\r\n}", rules: [ ], span: { start: 0, length: 10 }, expected: "{\r\n (a);\r\n}" }, -{ input: "var a=[1,2];\r\nvar b=8>>2 ;\r\nvar c=1+2;", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 14, length: 12 }, expected: "var a=[1,2];\r\nvar b = 8 >> 2;\r\nvar c=1+2;" }, -{ input: "if (true) {\r\n(a);\r\n}", rules: [ ], span: { start: 0, length: 20 }, expected: "if (true) {\r\n (a);\r\n}" }, -{ input: " // var a=[1,2];\r\n /*var a=[3,4];*/\r\n /*\r\n var a=[5,6];\r\n */", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 62 }, expected: "// var a=[1,2];\r\n/*var a=[3,4];*/\r\n/*\r\n var a=[5,6];\r\n */" }, -{ input: "f ();", rules: [ ], span: { start: 0, length: 14 }, expected: "f();" }, -{ input: "var a = { b: 1 , c: 2 };\r\nvar d = [1 , 2];", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 44 }, expected: "var a = { b: 1, c: 2 };\r\nvar d = [1, 2];" }, -{ input: "if (a)\r\n if (b)\r\n if (c)\r\n c();\r\n else\r\n b();\r\n else\r\n b();\r\nelse\r\n a();", rules: [ ], span: { start: 0, length: 124 }, expected: "if (a)\r\n if (b)\r\n if (c)\r\n c();\r\n else\r\n b();\r\n else\r\n b();\r\nelse\r\n a();" }, -{ input: "function a() { };", rules: [ ], span: { start: 0, length: 20 }, expected: "function a() { };" }, -{ input: "var a =[1.2,\"JavaScript\",true,{ x: 1,y: 3 }];\r\nvar b =[[1,2],[3,4]];\r\nvar c =[1,,,,5];\r\nvar d =[\r\n [1,2],\r\n [3,4]\r\n];", rules: [ "SpaceAfterComma" ], span: { start: 0, length: 123 }, expected: "var a =[1.2, \"JavaScript\", true, { x: 1, y: 3 }];\r\nvar b =[[1, 2], [3, 4]];\r\nvar c =[1, , , , 5];\r\nvar d =[\r\n [1, 2],\r\n [3, 4]\r\n];" }, -{ input: "var a =[1.2, \"JavaScript\", true, { x: 1, y: 3 }];\r\nvar b =[[1, 2], [3, 4]];\r\nvar c =[1, , , , 5];\r\nvar d =[\r\n [1, 2],\r\n [3, 4]\r\n];", rules: [ "NoSpaceAfterComma" ], span: { start: 0, length: 136 }, expected: "var a =[1.2,\"JavaScript\",true,{ x: 1,y: 3 }];\r\nvar b =[[1,2],[3,4]];\r\nvar c =[1,,,,5];\r\nvar d =[\r\n [1,2],\r\n [3,4]\r\n];" }, -{ input: "function a(b,c) { }\r\na(0,1);\r\nvar a =[,];\r\nvar a =[0,1];\r\nvar a,b,c = 0,d = 0;\r\nfor (var a = 0,b = 10; a < 10,b >= 0; ++a,--b) { }\r\nvar a = new ActiveXObject(\"\",\"\");\r\nswitch (a) {\r\n case 1,2,3:\r\n break;\r\n}", rules: [ "SpaceAfterComma" ], span: { start: 0, length: 215 }, expected: "function a(b, c) { }\r\na(0, 1);\r\nvar a =[, ];\r\nvar a =[0, 1];\r\nvar a, b, c = 0, d = 0;\r\nfor (var a = 0, b = 10; a < 10, b >= 0; ++a, --b) { }\r\nvar a = new ActiveXObject(\"\", \"\");\r\nswitch (a) {\r\n case 1, 2, 3:\r\n break;\r\n}" }, -{ input: "function a(b, c) { }\r\na(0, 1);\r\nvar a =[, ];\r\nvar a =[0, 1];\r\nvar a, b, c = 0, d = 0;\r\nfor (var a = 0, b = 10; a < 10, b >= 0; ++a, --b) { }\r\nvar a = new ActiveXObject(\"\", \"\");\r\nswitch (a) {\r\n case 1, 2, 3:\r\n break;\r\n}", rules: [ "NoSpaceAfterComma" ], span: { start: 0, length: 228 }, expected: "function a(b,c) { }\r\na(0,1);\r\nvar a =[,];\r\nvar a =[0,1];\r\nvar a,b,c = 0,d = 0;\r\nfor (var a = 0,b = 10; a < 10,b >= 0; ++a,--b) { }\r\nvar a = new ActiveXObject(\"\",\"\");\r\nswitch (a) {\r\n case 1,2,3:\r\n break;\r\n}" }, -{ input: "function Sum(a, b, c) {\r\nvar d = 1;\r\n}", rules: [ ], span: { start: 0, length: 38 }, expected: "function Sum(a, b, c) {\r\n var d = 1;\r\n}" }, -{ input: "(function() { })();\r\nvar a = function() { };\r\nvar a = { b: function() { } };", rules: [ "SpaceAfterAnonymousFunctionKeyword" ], span: { start: 0, length: 76 }, expected: "(function () { })();\r\nvar a = function () { };\r\nvar a = { b: function () { } };" }, -{ input: "(function () { })();\r\nvar a = function () { };\r\nvar a = { b: function () { } };", rules: [ "NoSpaceAfterAnonymousFunctionKeyword" ], span: { start: 0, length: 79 }, expected: "(function() { })();\r\nvar a = function() { };\r\nvar a = { b: function() { } };" }, -{ input: "function a() {\r\n}b;", rules: [ ], span: { start: 0, length: 19 }, expected: "function a() {\r\n} b;" }, -{ input: "function a() {\r\n} b;", rules: [ ], span: { start: 0, length: 21 }, expected: "function a() {\r\n} b;" }, -{ input: "function a(){return 0;}\r\nfunction b(){toString();return 0;}", rules: [ ], span: { start: 0, length: 59 }, expected: "function a() { return 0; }\r\nfunction b() { toString(); return 0; }" }, -{ input: "for (var i = 0;i < 10;++i) { }", rules: [ "SpaceAfterSemicolonInFor" ], span: { start: 0, length: 30 }, expected: "for (var i = 0; i < 10; ++i) { }" }, -{ input: "for (var i = 0; i < 10; ++i) { }", rules: [ "NoSpaceAfterSemicolonInFor" ], span: { start: 0, length: 32 }, expected: "for (var i = 0;i < 10;++i) { }" }, -{ input: "function f() {\r\nif (1)\r\n{\r\nvar a=0;\r\n}\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl", "NewLineBeforeOpenCurlyInFunction" ], span: { start: 0, length: 41 }, expected: "function f()\n{\r\n if (1) {\r\n var a=0;\r\n }\r\n}" }, -{ input: "function a(b) {\r\n a({\r\n});\r\n}", rules: [ ], span: { start: 0, length: 32 }, expected: "function a(b) {\r\n a({\r\n });\r\n}" }, -{ input: "// var a=[1,2];\r\n/*\r\nvar a=[1,2];\r\n*/", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 3, length: 12 }, expected: "// var a=[1,2];\r\n/*\r\nvar a=[1,2];\r\n*/" }, -{ input: "// var a=[1,2];\r\n/*\r\nvar a=[1,2];\r\n*/", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 21, length: 12 }, expected: "// var a=[1,2];\r\n/*\r\nvar a=[1,2];\r\n*/" }, -{ input: "eval(\"var a=b[1,2+3];\");", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 6, length: 15 }, expected: "eval(\"var a=b[1,2+3];\");" }, -{ input: "0 + +1;\r\n0 + +a;\r\n0 + +(1);\r\n0 + +(+1);\r\n0 + +[1];\r\n0 + +[+1];\r\n0 + +this.a;\r\n0 + +new Number(+1);\r\n\r\n0 - -1;\r\n0 - -a;\r\n0 - -(1);\r\n0 - -(-1);\r\n0 - -[1];\r\n0 - -[-1];\r\n0 - -this.a;\r\n0 - -new Number(-1);\r\n\r\n0 + ~1;\r\n0 - ~a;\r\n0 + ~(1);\r\n0 - ~(~1);\r\n0 + ~[1];\r\n0 - ~[~1];\r\n0 + ~this.a;\r\n0 - ~new Number(~1);\r\n\r\n0 - !1;\r\n0 + !a;\r\n0 - !(1);\r\n0 + !(!1);\r\n0 - ![1];\r\n0 + ![!1];\r\n0 - !this.a;\r\n0 + !new Number(!1);", rules: [ "NoSpaceBeforeBinaryOperator", "NoSpaceAfterBinaryOperator" ], span: { start: 0, length: 404 }, expected: "0+ +1;\r\n0+ +a;\r\n0+ +(1);\r\n0+ +(+1);\r\n0+ +[1];\r\n0+ +[+1];\r\n0+ +this.a;\r\n0+ +new Number(+1);\r\n\r\n0- -1;\r\n0- -a;\r\n0- -(1);\r\n0- -(-1);\r\n0- -[1];\r\n0- -[-1];\r\n0- -this.a;\r\n0- -new Number(-1);\r\n\r\n0+~1;\r\n0-~a;\r\n0+~(1);\r\n0-~(~1);\r\n0+~[1];\r\n0-~[~1];\r\n0+~this.a;\r\n0-~new Number(~1);\r\n\r\n0-!1;\r\n0+!a;\r\n0-!(1);\r\n0+!(!1);\r\n0-![1];\r\n0+![!1];\r\n0-!this.a;\r\n0+!new Number(!1);" }, -{ input: "0+ +1;\r\n0+ +a;\r\n0+ +(1);\r\n0+ +(+1);\r\n0+ +[1];\r\n0+ +[+1];\r\n0+ +this.a;\r\n0+ +new Number(+1);\r\n\r\n0- -1;\r\n0- -a;\r\n0- -(1);\r\n0- -(-1);\r\n0- -[1];\r\n0- -[-1];\r\n0- -this.a;\r\n0- -new Number(-1);\r\n\r\n0+~1;\r\n0-~a;\r\n0+~(1);\r\n0-~(~1);\r\n0+~[1];\r\n0-~[~1];\r\n0+~this.a;\r\n0-~new Number(~1);\r\n\r\n0-!1;\r\n0+!a;\r\n0-!(1);\r\n0+!(!1);\r\n0-![1];\r\n0+![!1];\r\n0-!this.a;\r\n0+!new Number(!1);", rules: [ "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 356 }, expected: "0 + +1;\r\n0 + +a;\r\n0 + +(1);\r\n0 + +(+1);\r\n0 + +[1];\r\n0 + +[+1];\r\n0 + +this.a;\r\n0 + +new Number(+1);\r\n\r\n0 - -1;\r\n0 - -a;\r\n0 - -(1);\r\n0 - -(-1);\r\n0 - -[1];\r\n0 - -[-1];\r\n0 - -this.a;\r\n0 - -new Number(-1);\r\n\r\n0 + ~1;\r\n0 - ~a;\r\n0 + ~(1);\r\n0 - ~(~1);\r\n0 + ~[1];\r\n0 - ~[~1];\r\n0 + ~this.a;\r\n0 - ~new Number(~1);\r\n\r\n0 - !1;\r\n0 + !a;\r\n0 - !(1);\r\n0 + !(!1);\r\n0 - ![1];\r\n0 + ![!1];\r\n0 - !this.a;\r\n0 + !new Number(!1);" }, -{ input: "for (var a = 0; a < 2; ++a) {\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl", "SpaceAfterSemicolonInFor" ], span: { start: 0, length: 32 }, expected: "for (var a = 0; a < 2; ++a)\n{\r\n}" }, -{ input: "for (var a = 0; a < 2; ++a)\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl", "SpaceAfterSemicolonInFor" ], span: { start: 0, length: 32 }, expected: "for (var a = 0; a < 2; ++a) {\r\n}" }, -{ input: "function foo(a, b, c) { a = b + c;\n}", rules: [ "NewLineBeforeOpenCurlyInFunction", "NewLineAfterOpenCurlyInBlockContext", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 36 }, expected: "function foo(a, b, c)\n{\n a = b + c;\n}" }, -{ input: "function a() {\r\n // comment\r\n}", rules: [ ], span: { start: 0, length: 33 }, expected: "function a() {\r\n // comment\r\n}" }, -{ input: "if (false) {\r\n} else if (true) {\r\n} else {\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 45 }, expected: "if (false)\n{\r\n} else if (true)\n{\r\n} else\n{\r\n}" }, -{ input: "if (false)\n{\r\n} else if (true)\n{\r\n} else\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 45 }, expected: "if (false) {\r\n} else if (true) {\r\n} else {\r\n}" }, -{ input: "var a = (0);\r\nvar b = (1);\r\nvar c = (1 + 2);\r\nvar d = ((1 + 2)-(3 + 4));\r\n\r\nvar e = ( 0 );\r\nvar f = ( 1 );\r\nvar g = ( 1 + 2 );\r\nvar h = ( ( 1 + 2 ) - ( 3 + 4 ) );", rules: [ "SpaceAfterOpenParen", "SpaceBeforeCloseParen", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 162 }, expected: "var a = ( 0 );\r\nvar b = ( 1 );\r\nvar c = ( 1 + 2 );\r\nvar d = ( ( 1 + 2 ) - ( 3 + 4 ) );\r\n\r\nvar e = ( 0 );\r\nvar f = ( 1 );\r\nvar g = ( 1 + 2 );\r\nvar h = ( ( 1 + 2 ) - ( 3 + 4 ) );" }, -{ input: "eval(\"var a=b[1,2+3];\");", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 24 }, expected: "eval(\"var a=b[1,2+3];\");" }, -{ input: "for (a in b)\r\n\r\n{ i++; }\r\n\r\nfor (a in b)\r\n\r\n{\r\ni++; }", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 53 }, expected: "for (a in b)\r\n\r\n{ i++; }\r\n\r\nfor (a in b) {\r\n i++;\n}" }, -{ input: "for (a in b) {\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 17 }, expected: "for (a in b)\n{\r\n}" }, -{ input: "for (a in b)\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 17 }, expected: "for (a in b) {\r\n}" }, -{ input: " var a = { } ; \r\nvar b = { c : d, e : { } };\r\n ", rules: [ "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 59 }, expected: "var a = {};\r\nvar b = { c: d, e: {} };\r\n" }, -{ input: "while (true) { }", rules: [ ], span: { start: 0, length: 19 }, expected: "while (true) { }" }, -{ input: "for (a in b){ i++; }\r\n\r\nfor (a in b){ i++; }", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 44 }, expected: "for (a in b) { i++; }\r\n\r\nfor (a in b) { i++; }" }, -{ input: "function a() {\r\n}", rules: [ "NewLineBeforeOpenCurlyInFunction" ], span: { start: 0, length: 17 }, expected: "function a()\n{\r\n}" }, -{ input: "function a()\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInFunction" ], span: { start: 0, length: 17 }, expected: "function a() {\r\n}" }, -{ input: "a;\r\nb;c;\r\nd;", rules: [ ], span: { start: 0, length: 12 }, expected: "a;\r\nb; c;\r\nd;" }, -{ input: "a;\r\nb; c;\r\nd;", rules: [ ], span: { start: 0, length: 14 }, expected: "a;\r\nb; c;\r\nd;" }, -{ input: " var a = 0;\r\n function b() {\r\n var c = 0;\r\n }", rules: [ "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 61 }, expected: "var a = 0;\r\nfunction b() {\r\n var c = 0;\r\n}" }, -{ input: "a;b;", rules: [ ], span: { start: 0, length: 4 }, expected: "a; b;" }, -{ input: "a; b;", rules: [ ], span: { start: 0, length: 6 }, expected: "a; b;" }, -{ input: "var a = (0);\r\nvar b = (1);\r\nvar c = (1 + 2);\r\nvar d = ((1 + 2)-(3 + 4));\r\n\r\nvar e = ( 0 );\r\nvar f = ( 1 );\r\nvar g = ( 1 + 2 );\r\nvar h = ( ( 1 + 2 ) - ( 3 + 4 ) );", rules: [ "NoSpaceAfterOpenParen", "NoSpaceBeforeCloseParen", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 162 }, expected: "var a = (0);\r\nvar b = (1);\r\nvar c = (1 + 2);\r\nvar d = ((1 + 2) - (3 + 4));\r\n\r\nvar e = (0);\r\nvar f = (1);\r\nvar g = (1 + 2);\r\nvar h = ((1 + 2) - (3 + 4));" }, -{ input: "function a() {\r\n(b);\r\n}", rules: [ ], span: { start: 0, length: 23 }, expected: "function a() {\r\n (b);\r\n}" }, -{ input: "function test(a) {\n var i;\n for (i = 0;i < 1; i++){ //select\n a++;//select\n }\n}", rules: [ "NewLineBeforeOpenCurlyInControl", "NewLineAfterOpenCurlyInBlockContext", "NewLineBeforeOpenCurlyInFunction", "SpaceAfterSemicolonInFor" ], span: { start: 30, length: 50 }, expected: "function test(a) {\n var i;\n for (i = 0; i < 1; i++)\n { //select\n a++;//select\n }\n}" }, -{ input: "function a(){ return 1; }", rules: [ "SpaceBeforeOpenCurlyInFunction" ], span: { start: 0, length: 25 }, expected: "function a() { return 1; }" }, -{ input: "do {\r\n} while (true);", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 21 }, expected: "do\n{\r\n} while (true);" }, -{ input: "do\n{\r\n} while (true);", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 21 }, expected: "do {\r\n} while (true);" }, -{ input: "for (;;) { a = b + c; b = 2;\n}", rules: [ "NewLineBeforeOpenCurlyInControl", "NewLineAfterOpenCurlyInBlockContext", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator", "NoSpaceAfterSemicolonInFor" ], span: { start: 0, length: 30 }, expected: "for (;;)\n{\n a = b + c; b = 2;\n}" }, -{ input: "var a =0;\r\n\r\n+ 1;\r\n+ a;\r\n+ (1);\r\n+ (+ 1);\r\n+ [1];\r\n+ [+ 1];\r\n+ this.a;\r\n+ new Number(+ 1);\r\n\r\n- 1;\r\n- a;\r\n- (1);\r\n- (- 1);\r\n- [1];\r\n- [- 1];\r\n- this.a;\r\n- new Number(- 1);\r\n\r\n~ 1;\r\n~ a;\r\n~ (1);\r\n~ (~ 1);\r\n~ [1];\r\n~ [~ 1];\r\n~ this.a;\r\n~ new Number(~ 1);\r\n\r\n! 1;\r\n! a;\r\n! (1);\r\n! (! 1);\r\n! [1];\r\n! [! 1];\r\n! this.a;\r\n! new Number(! 1);\r\n\r\n++ a;\r\n++ (a);\r\n++ this.a;\r\n++ new f().a;\r\n\r\n-- a;\r\n-- (a);\r\n-- this.a;\r\n-- new f().a;\r\n\r\na ++;\r\n(a) ++;\r\nthis.a ++;\r\nnew f().a ++;\r\n\r\na --;\r\n(a) --;\r\nthis.a --;\r\nnew f().a --;", rules: [ ], span: { start: 0, length: 513 }, expected: "var a =0;\r\n\r\n+1;\r\n+a;\r\n+(1);\r\n+(+1);\r\n+[1];\r\n+[+1];\r\n+this.a;\r\n+new Number(+1);\r\n\r\n-1;\r\n-a;\r\n-(1);\r\n-(-1);\r\n-[1];\r\n-[-1];\r\n-this.a;\r\n-new Number(-1);\r\n\r\n~1;\r\n~a;\r\n~(1);\r\n~(~1);\r\n~[1];\r\n~[~1];\r\n~this.a;\r\n~new Number(~1);\r\n\r\n!1;\r\n!a;\r\n!(1);\r\n!(!1);\r\n![1];\r\n![!1];\r\n!this.a;\r\n!new Number(!1);\r\n\r\n++a;\r\n++(a);\r\n++this.a;\r\n++new f().a;\r\n\r\n--a;\r\n--(a);\r\n--this.a;\r\n--new f().a;\r\n\r\na++;\r\n(a)++;\r\nthis.a++;\r\nnew f().a++;\r\n\r\na--;\r\n(a)--;\r\nthis.a--;\r\nnew f().a--;" }, -{ input: "switch (a) {\r\n case 0:\r\n break;\r\n default:\r\n break;\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 74 }, expected: "switch (a)\n{\r\n case 0:\r\n break;\r\n default:\r\n break;\r\n}" }, -{ input: "switch (a)\n{\r\n case 0:\r\n break;\r\n default:\r\n break;\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 74 }, expected: "switch (a) {\r\n case 0:\r\n break;\r\n default:\r\n break;\r\n}" }, -{ input: "function a()\r\n\r\n\r\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInFunction" ], span: { start: 0, length: 22 }, expected: "function a() {\r\n}" }, -{ input: "try {\r\n} catch (e) {\r\n} finally {\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 36 }, expected: "try\n{\r\n} catch (e)\n{\r\n} finally\n{\r\n}" }, -{ input: "try\n{\r\n} catch (e)\n{\r\n} finally\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 36 }, expected: "try {\r\n} catch (e) {\r\n} finally {\r\n}" }, -{ input: "with (a) {\r\n b = 0;\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 25 }, expected: "with (a)\n{\r\n b = 0;\r\n}" }, -{ input: "with (a)\n{\r\n b = 0;\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 25 }, expected: "with (a) {\r\n b = 0;\r\n}" }, -{ input: "var a=0+1-2*3/4%5;\r\na+=6;\r\na-=7;\r\na*=7;\r\na/=8;\r\na%=9;\r\na=+1- -2+ +3;\r\na=1.0+2.+.0;\r\n++a+a++;\r\n--a-a--;\r\n\r\nvar b=~1&2|3^4<<1>>1>>>2;\r\nb&=5;\r\nb^=6;\r\nb|=7;\r\nb<<=8;\r\nb>>=9;\r\nb>>>=10;\r\n\r\nvar c=a>b;\r\nc=b=b;\r\nc=!c;\r\n\r\n++a+ ++a+a++ +a++ + ++a;\r\n--a- --a-a-- -a-- - --a;\r\n\r\nfunction d::e() { }", rules: [ "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 366 }, expected: "var a = 0 + 1 - 2 * 3 / 4 % 5;\r\na += 6;\r\na -= 7;\r\na *= 7;\r\na /= 8;\r\na %= 9;\r\na = +1 - -2 + +3;\r\na = 1.0 + 2. + .0;\r\n++a + a++;\r\n--a - a--;\r\n\r\nvar b = ~1 & 2 | 3 ^ 4 << 1 >> 1 >>> 2;\r\nb &= 5;\r\nb ^= 6;\r\nb |= 7;\r\nb <<= 8;\r\nb >>= 9;\r\nb >>>= 10;\r\n\r\nvar c = a > b;\r\nc = b < a ? a : b;\r\nc = true && false || true;\r\nc = a == b;\r\nc = a === b;\r\nc = a != b;\r\nc = a !== b;\r\nc = a <= b;\r\nc = a >= b;\r\nc = !c;\r\n\r\n++a + ++a + a++ + a++ + ++a;\r\n--a - --a - a-- - a-- - --a;\r\n\r\nfunction d::e() { }" }, -{ input: "var a = 0 + 1 - 2 * 3 / 4 % 5;\r\na += 6;\r\na -= 7;\r\na *= 7;\r\na /= 8;\r\na %= 9;\r\na = +1 - -2 + +3;\r\na = 1.0 + 2. + .0;\r\n++a + a++;\r\n--a - a--;\r\n\r\nvar b = ~1 & 2 | 3 ^ 4 << 1 >> 1 >>> 2;\r\nb &= 5;\r\nb ^= 6;\r\nb |= 7;\r\nb <<= 8;\r\nb >>= 9;\r\nb >>>= 10;\r\n\r\nvar c = a > b;\r\nc = b < a ? a : b;\r\nc = true && false || true;\r\nc = a == b;\r\nc = a === b;\r\nc = a != b;\r\nc = a !== b;\r\nc = a <= b;\r\nc = a >= b;\r\nc = !c;\r\n\r\n++a + ++a + a++ + a++ + ++a;\r\n--a - --a - a-- - a-- - --a;\r\n\r\nfunction d::e() { }", rules: [ "NoSpaceBeforeBinaryOperator", "NoSpaceAfterBinaryOperator" ], span: { start: 0, length: 480 }, expected: "var a=0+1-2*3/4%5;\r\na+=6;\r\na-=7;\r\na*=7;\r\na/=8;\r\na%=9;\r\na=+1- -2+ +3;\r\na=1.0+2.+.0;\r\n++a+a++;\r\n--a-a--;\r\n\r\nvar b=~1&2|3^4<<1>>1>>>2;\r\nb&=5;\r\nb^=6;\r\nb|=7;\r\nb<<=8;\r\nb>>=9;\r\nb>>>=10;\r\n\r\nvar c=a>b;\r\nc=b=b;\r\nc=!c;\r\n\r\n++a+ ++a+a++ +a++ + ++a;\r\n--a- --a-a-- -a-- - --a;\r\n\r\nfunction d::e() { }" }, -{ input: "function foo()\n\n{ a = 1\n}", rules: [ "NewLineBeforeOpenCurlyInFunction" ], span: { start: 0, length: 25 }, expected: "function foo()\n{\n a = 1\n}" }, -{ input: "while (true) {\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 17 }, expected: "while (true)\n{\r\n}" }, -{ input: "while (true)\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 17 }, expected: "while (true) {\r\n}" }, -{ input: "var z = 1;\r\n for (i = 0; i < 10; i++)\r\n for (j = 0; j < 10; j++)\r\nfor (k = 0; k < 10; ++k)\r\n{\r\nz++;\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl", "SpaceAfterSemicolonInFor" ], span: { start: 0, length: 117 }, expected: "var z = 1;\r\nfor (i = 0; i < 10; i++)\r\n for (j = 0; j < 10; j++)\r\n for (k = 0; k < 10; ++k) {\r\n z++;\r\n }" }, -{ input: "a++;b++;\nfor (; ; ) {\nx++;m++;\n}", rules: [ "SpaceAfterSemicolonInFor" ], span: { start: 0, length: 32 }, expected: "a++; b++;\nfor (; ; ) {\n x++; m++;\n}" }, -{ input: "var a;\r\n $(document).ready(function() {\r\n alert('hello');\r\n});\r\n", rules: [ ], span: { start: 0, length: 117 }, expected: "var a;\r\n$(document).ready(function () {\r\n alert('hello');\r\n});\r\n" } \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/formatDiffTemplate.html b/src/harness/unittests/services/formatting/formatDiffTemplate.html deleted file mode 100644 index d5bc6537cc..0000000000 --- a/src/harness/unittests/services/formatting/formatDiffTemplate.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/getFormattingEditsForRange.ts b/src/harness/unittests/services/formatting/getFormattingEditsForRange.ts deleted file mode 100644 index 9ad1102d2f..0000000000 --- a/src/harness/unittests/services/formatting/getFormattingEditsForRange.ts +++ /dev/null @@ -1,88 +0,0 @@ -/// - -describe('getFormattingEditsForRange', function() { - // - // Verify that formatting the typescript file "sourceFileName" results in the - // baseline file "baselineFileName". - // - function getFormattingEditsForRange(sourceFileName: string) { - var baselineFileName = "tests/cases/unittests/services/testCode/formatting/" + sourceFileName + "BaseLine.ts"; - sourceFileName = "tests/cases/unittests/services/testCode/formatting/" + sourceFileName + ".ts"; - - var typescriptLS = new Harness.TypeScriptLS(); - typescriptLS.addDefaultLibrary(); - typescriptLS.addFile(sourceFileName); - - var ls = typescriptLS.getLanguageService(); - var script = ls.languageService.getScriptAST(sourceFileName); - assert.notNull(script); - - var edits = ls.languageService.getFormattingEditsForRange(sourceFileName, 0, script.limChar, new Services.FormatCodeOptions()); - typescriptLS.checkEdits(sourceFileName, baselineFileName, edits); - } - - describe('test cases for formatting engine', function() { - it("formats typescript constructs properly", function() { - getFormattingEditsForRange('typescriptConstructs'); - }); - it("formats document ready function properly", function() { - getFormattingEditsForRange('documentReadyFunction'); - }); - it("formats on closing bracket properly", function() { - getFormattingEditsForRange('onClosingBracket'); - }); - it("formats various javascript constructs", function() { - getFormattingEditsForRange('various'); - }); - it("formats main javascript program", function() { - getFormattingEditsForRange('main'); - }); - it("formats on semicolon properly", function() { - getFormattingEditsForRange('onSemiColon'); - }); - it("formats enum with trailling tab characters properly", function() { - getFormattingEditsForRange('tabAfterCloseCurly'); - }); - it("formats object literal", function() { - getFormattingEditsForRange('objectLiteral'); - }); - it("formats with statements", function() { - getFormattingEditsForRange('withStatement'); - }); - it("formats ':' and '?' in parameters", function() { - getFormattingEditsForRange('colonAndQMark'); - }); - it("formats 'import' declaration", function() { - getFormattingEditsForRange('importDeclaration'); - }); - it("formats exported class with implicit module", function() { - //TODO: this is to force generation of implicit module in AST - var svGenTarget = TypeScript.moduleGenTarget; - try { - TypeScript.moduleGenTarget = TypeScript.ModuleGenTarget.Asynchronous; - getFormattingEditsForRange('implicitModule'); - } - finally { - TypeScript.moduleGenTarget = svGenTarget; - } - }); - it("formats constructor statements correctelly", function() { - getFormattingEditsForRange('spaceAfterConstructor'); - }); - it("formats classes and interfaces correctelly", function() { - getFormattingEditsForRange('classes'); - }); - it("formats modules correctly", function() { - getFormattingEditsForRange('modules'); - }); - it("formats fat arrow expressions correctelly", function() { - getFormattingEditsForRange('fatArrowFunctions'); - }); - it("formats empty object/interface literals correctelly", function() { - getFormattingEditsForRange('emptyInterfaceLiteral'); - }); - it("formats variable declaration lists", function() { - getFormattingEditsForRange('formatVariableDeclarationList'); - }); - }); -}); diff --git a/src/harness/unittests/services/formatting/getSmartIndentAtLineNumber.ts b/src/harness/unittests/services/formatting/getSmartIndentAtLineNumber.ts deleted file mode 100644 index 52e7982bd4..0000000000 --- a/src/harness/unittests/services/formatting/getSmartIndentAtLineNumber.ts +++ /dev/null @@ -1,410 +0,0 @@ -/// - -describe('getSmartIndentAtLineNumber', function() { - var typescriptLS = new Harness.TypeScriptLS(); - - typescriptLS.addDefaultLibrary(); - - var fileName = 'tests/cases/unittests/services/testCode/getSmartIndentAtLineNumber.ts'; - var fileName2 = 'tests/cases/unittests/services/testCode/getSmartIndentAtLineNumber2.ts'; - var fileName3 = 'tests/cases/unittests/services/testCode/getSmartIndentAtLineNumber3.ts'; - - typescriptLS.addFile(fileName); - typescriptLS.addFile(fileName2); - typescriptLS.addFile(fileName3); - - var ls = typescriptLS.getLanguageService(); - - // - // line is 1-based - // - function getSmartIndent(fileName: string, line: number): number { - assert.is(line >= 1); - var options = new Services.EditorOptions(); - var position = typescriptLS.lineColToPosition(fileName, line, 1); - return ls.languageService.getSmartIndentAtLineNumber(fileName, position, options); - } - - describe("test cases for smart indent", function() { - - it("smart indent inside module", function() { - var result = getSmartIndent(fileName, 2); - - assert.notNull(result); - assert.equal(4, result); - }); - - it("smart indent inside class", function() { - var result = getSmartIndent(fileName, 4); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent after property in class", function() { - var result = getSmartIndent(fileName, 6); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent inside method in class ", function() { - var result = getSmartIndent(fileName, 9); - - assert.notNull(result); - assert.equal(12, result); - }); - - it("smart indent after after method in class", function() { - var result = getSmartIndent(fileName, 12); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent after class", function() { - var result = getSmartIndent(fileName, 17); - - assert.notNull(result); - assert.equal(4, result); - }); - - it("smart indent in interface", function() { - var result = getSmartIndent(fileName, 19); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent after property in interface", function() { - var result = getSmartIndent(fileName, 21); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent after method in interface", function() { - var result = getSmartIndent(fileName, 23); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent after interface", function() { - var result = getSmartIndent(fileName, 25); - - assert.notNull(result); - assert.equal(4, result); - }); - - it("smart indent in nested module", function() { - var result = getSmartIndent(fileName, 27); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent after function in nested module", function() { - var result = getSmartIndent(fileName, 30); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent after variable in nested module", function() { - var result = getSmartIndent(fileName, 32); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent after nested module", function() { - var result = getSmartIndent(fileName, 34); - - assert.notNull(result); - assert.equal(4, result); - }); - - it("smart indent in enum", function() { - var result = getSmartIndent(fileName, 36); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent after variable in enum", function() { - var result = getSmartIndent(fileName, 38); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent after 2nd variable in enum", function() { - var result = getSmartIndent(fileName, 40); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent after enum", function() { - var result = getSmartIndent(fileName, 42); - - assert.notNull(result); - assert.equal(4, result); - }); - - it("smart indent after module", function() { - var result = getSmartIndent(fileName, 44); - - assert.notNull(result); - assert.equal(0, result); - }); - - /////////////////////////////////////////////////////////////////////// - - it("smart indent after an aligned function argument", function() { - var result = getSmartIndent(fileName, 47); - - assert.notNull(result); - assert.equal(13, result); - }); - - /////////////////////////////////////////////////////////////////////// - - it("smart indent inside a 'for' statement", function() { - var result = getSmartIndent(fileName, 53); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent after a 'for' statement", function() { - var result = getSmartIndent(fileName, 55); - - assert.notNull(result); - assert.equal(4, result); - }); - - it("smart indent inside a 'for in' statement", function() { - var result = getSmartIndent(fileName, 57); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent after a 'for in' statement", function() { - var result = getSmartIndent(fileName, 59); - - assert.notNull(result); - assert.equal(4, result); - }); - - it("smart indent inside a 'with' statement", function() { - var result = getSmartIndent(fileName, 61); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent after a 'with' statement", function() { - var result = getSmartIndent(fileName, 63); - - assert.notNull(result); - assert.equal(4, result); - }); - - it("smart indent inside a 'switch' statement", function() { - var result = getSmartIndent(fileName, 65); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent after a 'switch' statement", function() { - var result = getSmartIndent(fileName, 67); - - assert.notNull(result); - assert.equal(4, result); - }); - - it("smart indent inside a 'break' statement", function() { - var result = getSmartIndent(fileName, 69); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent after a 'break' statement", function() { - var result = getSmartIndent(fileName, 71); - - assert.notNull(result); - assert.equal(12, result); - }); - - it("smart indent after a 'break' statement", function() { - var result = getSmartIndent(fileName, 73); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent after last 'switch' statement", function() { - var result = getSmartIndent(fileName, 75); - - assert.notNull(result); - assert.equal(4, result); - }); - - /////////////////////////////////////////////////////////////////////// - - it("smart indent before 'try' in 'try/catch' statement", function() { - var result = getSmartIndent(fileName, 79); - - assert.notNull(result); - assert.equal(4, result); - }); - - it("smart indent insde 'try' in 'try/catch' statement", function() { - var result = getSmartIndent(fileName, 81); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent before 'catch' in 'try/catch' statement", function() { - var result = getSmartIndent(fileName, 83); - - assert.notNull(result); - assert.equal(4, result); - }); - - it("smart indent inside 'catch' in 'try/catch' statement", function() { - var result = getSmartIndent(fileName, 85); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent after 'catch' in 'try/catch' statement", function() { - var result = getSmartIndent(fileName, 87); - - assert.notNull(result); - assert.equal(4, result); - }); - - /////////////////////////////////////////////////////////////////////// - - it("smart indent before 'try' in 'try/finally' statement", function() { - var result = getSmartIndent(fileName, 92); - - assert.notNull(result); - assert.equal(4, result); - }); - - it("smart indent insde 'try' in 'try/finally' statement", function() { - var result = getSmartIndent(fileName, 94); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent before 'finally' in 'try/finally' statement", function() { - var result = getSmartIndent(fileName, 96); - - assert.notNull(result); - assert.equal(4, result); - }); - - it("smart indent inside 'finally' in 'try/finally' statement", function() { - var result = getSmartIndent(fileName, 98); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent after 'finally' in 'try/finally' statement", function() { - var result = getSmartIndent(fileName, 100); - - assert.notNull(result); - assert.equal(4, result); - }); - - /////////////////////////////////////////////////////////////////////// - - it("smart indent before 'try' in 'try/catch/finally' statement", function() { - var result = getSmartIndent(fileName, 104); - - assert.notNull(result); - assert.equal(4, result); - }); - - it("smart indent insde 'try' in 'try/catch/finally' statement", function() { - var result = getSmartIndent(fileName, 106); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent before 'catch' in 'try/catch/finally' statement", function() { - var result = getSmartIndent(fileName, 108); - - assert.notNull(result); - assert.equal(4, result); - }); - - it("smart indent inside 'catch' in 'try/catch/finally' statement", function() { - var result = getSmartIndent(fileName, 110); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent before 'finally' in 'try/catch/finally' statement", function() { - var result = getSmartIndent(fileName, 112); - - assert.notNull(result); - assert.equal(4, result); - }); - - it("smart indent inside 'finally' in 'try/catch/finally' statement", function() { - var result = getSmartIndent(fileName, 114); - - assert.notNull(result); - assert.equal(8, result); - }); - - it("smart indent after 'finally' in 'try/catch/finally' statement", function() { - var result = getSmartIndent(fileName, 116); - - assert.notNull(result); - assert.equal(4, result); - }); - - /////////////////////////////////////////////////////////////////////// - - it("smart indent inside a block inside case", function() { - var result = getSmartIndent(fileName, 127); - - assert.notNull(result); - assert.equal(20, result); - }); - - /////////////////////////////////////////////////////////////////////// - - it("smart indent works for a non terminated argument list at the end of a file", function() { - var result = getSmartIndent(fileName2, 8); - - assert.notNull(result); - assert.equal(4, result); - }); - - /////////////////////////////////////////////////////////////////////// - - it("smart indent works for a non terminated if statement at the end of a file", function() { - var result = getSmartIndent(fileName3, 7); - - assert.notNull(result); - assert.equal(4, result); - }); - }); -}); diff --git a/src/harness/unittests/services/formatting/importedJavaScriptFormatting.ts b/src/harness/unittests/services/formatting/importedJavaScriptFormatting.ts deleted file mode 100644 index 2fcb997767..0000000000 --- a/src/harness/unittests/services/formatting/importedJavaScriptFormatting.ts +++ /dev/null @@ -1,212 +0,0 @@ -/// -/// - -interface DocumentTestJson { - input: string; - rules: string[]; - span: { start: number; length: number; }; - expected: string; -} - -interface FormatOperationTestJson { - input: string; - operations: { - operation: string; - point: { position: number; }; - span: { start: number; length: number; }; - }[]; - expected: string; -} - -function markupCodeForHtml(code: string) { - var formatted = code.replace(/'); - var escaped = encodeURIComponent(code).replace(/'/g, '%27'); - - return formatted + '
Copy'; -} - -describe('importedJavaScriptFormatting - formatting rules', function() { - var documentTests: DocumentTestJson[] = eval('[' + IO.readFile(Harness.userSpecifiedroot + 'tests/cases/unittests/services/documentFormattingTests.json').contents() + ']'); - - var outputFile = 'diff-1.html'; - IO.writeFile(outputFile, IO.readFile(Harness.userSpecifiedroot + 'tests/cases/unittests/services/formatDiffTemplate.html').contents(), false); - - var checkTest = function(test: DocumentTestJson) { - var filename = 'temp.ts'; - var typescriptLS = new Harness.TypeScriptLS(); - typescriptLS.addScript(filename, test.input); - - var ls = typescriptLS.getLanguageService().languageService; - - var unsupportedRules = []; - var ruleMap = { - 'SpaceAfterSemicolonInFor': 'InsertSpaceAfterSemicolonInForStatements', - 'SpaceAfterComma': 'InsertSpaceAfterCommaDelimiter', - 'NewLineBeforeOpenCurlyInControl': 'PlaceOpenBraceOnNewLineForControlBlocks', - 'NewLineBeforeOpenCurlyInFunction': 'PlaceOpenBraceOnNewLineForFunctions' - }; - - var options = new Services.FormatCodeOptions(); - if (test.rules.indexOf('SpaceBeforeBinaryOperator') >= 0 && test.rules.indexOf('SpaceAfterBinaryOperator') >= 0) { - test.rules.splice(test.rules.indexOf('SpaceBeforeBinaryOperator'), 1); - test.rules.splice(test.rules.indexOf('SpaceAfterBinaryOperator'), 1); - options.InsertSpaceBeforeAndAfterBinaryOperators = true; - } - - test.rules.forEach(ruleName => { - if (options[ruleName] !== undefined) { - // The options struct has a matching property, just set it directly - options[ruleName] = true; - } else { - if (ruleMap[ruleName] !== undefined) { - // We have a remapping of this name, use that instead - options[ruleMap[ruleName]] = true; - } else { - if (ruleName.indexOf('No') === 0) { - // This is a 'NoFoo', set 'Foo' to false - options[ruleMap[ruleName.substr(2)]] = false; - } else { - // ?? - IO.printLine('Unsupported rule name ' + ruleName); - return; - } - } - } - }); - - var edits = ls.getFormattingEditsForRange(filename, test.span.start, test.span.start + test.span.length, options); - - var output = typescriptLS.applyEdits(test.input, edits); - - // Normalize line endings - output = output.replace(/\r\n/g, '\n'); - test.expected = test.expected.replace(/\r\n/g, '\n'); - - if (output != test.expected) { - var outputHtml = ''; - outputHtml += ''; - outputHtml += ''; - outputHtml += ''; - outputHtml += ''; - outputHtml += ''; - outputHtml += ''; - outputHtml += ''; - outputHtml += ''; - outputHtml += ''; - outputHtml += ''; - outputHtml += ''; - outputHtml += ''; - outputHtml += '
InputOutputExpected
' + markupCodeForHtml(test.input) + '' + markupCodeForHtml(output) + '' + markupCodeForHtml(test.expected) + '
Format from character ' + test.span.start + ' to ' + (test.span.start + test.span.length) + ' with rules: ' + test.rules.join(', ') + '
'; // test-table - - IO.writeFile(outputFile, IO.readFile(outputFile).contents() + outputHtml, false); - - // TODO: Uncomment when things are working - // throw new Error("Formatting failed - refer to diff-1.html"); - } - } - - var i = 0; - - for (var i = 0; i < documentTests.length; i++) { - var test = documentTests[i]; - - var msg = 'formats the code (index ' + i + ') from ' + test.span.start + ' to ' + (test.span.start + test.span.length) + ' with rules = [' + test.rules.join(', ') + '] correctly'; - it(msg, function(t) { - return function() { - checkTest(t); - } - }(test)); - } -}); - -describe('importedJavaScriptFormatting - formatting operations', function() { - var outputFile = 'diff-2.html'; - IO.writeFile(outputFile, IO.readFile(Harness.userSpecifiedroot + 'tests/cases/unittests/services/formatDiffTemplate.html').contents(), false); - - var checkTest = function(test: FormatOperationTestJson) { - var filename = 'temp.ts'; - var typescriptLS = new Harness.TypeScriptLS(); - typescriptLS.addScript(filename, test.input); - - var ls = typescriptLS.getLanguageService(); - - var operationsText = ''; - - var markedUpInput = test.input; - var output = test.input; - - for (var i = 0; i < test.operations.length; i++) { - var options = new Services.FormatCodeOptions(); - var op = test.operations[i]; - var edits: Services.TextEdit[]; - - if (op.operation === 'CloseBrace') { - edits = ls.languageService.getFormattingEditsAfterKeystroke(filename, op.point.position, '}', options); - operationsText += 'Format for } at position ' + op.point.position.toString(); - markedUpInput = markedUpInput.substring(0, op.point.position) + '✪' + markedUpInput.substring(op.point.position); - } else if (op.operation === 'Enter') { - edits = ls.languageService.getFormattingEditsAfterKeystroke(filename, op.point.position, '\n', options); - operationsText += 'Format for [enter] at position ' + op.point.position.toString(); - markedUpInput = markedUpInput.substring(0, op.point.position) + '✪' + markedUpInput.substring(op.point.position); - } else if (op.operation === 'Semicolon') { - edits = ls.languageService.getFormattingEditsAfterKeystroke(filename, op.point.position, ';', options); - operationsText += 'Format for ; at position ' + op.point.position.toString(); - markedUpInput = markedUpInput.substring(0, op.point.position) + '✪' + markedUpInput.substring(op.point.position); - } else if (op.operation === 'Document') { - edits = ls.languageService.getFormattingEditsForRange(filename, 0, output.length, options); - operationsText += 'Format Document'; - } else if (op.operation === 'Selection') { - edits = ls.languageService.getFormattingEditsForRange(filename, op.span.start, op.span.start + op.span.length, options); - operationsText += 'Format selection from ' + op.span.start + ', length = ' + op.span.length; - } else if (op.operation === 'Paste') { - edits = ls.languageService.getFormattingEditsForRange(filename, op.span.start, op.span.start + op.span.length, options); - operationsText += 'Format pasted content from ' + op.span.start + ', length = ' + op.span.length; - } else { - throw new Error('Unknown operation: ' + op.operation); - } - - output = typescriptLS.applyEdits(test.input, edits); - typescriptLS.updateScript(filename, output); - } - - // Normalize line endings - output = output.replace(/\r\n/g, '\n'); - test.expected = test.expected.replace(/\r\n/g, '\n'); - - var outputHtml = ''; - outputHtml += ''; - outputHtml += ''; - outputHtml += ''; - outputHtml += ''; - outputHtml += ''; - outputHtml += ''; - outputHtml += ''; - outputHtml += ''; - outputHtml += ''; - outputHtml += ''; - outputHtml += ''; - outputHtml += ''; - outputHtml += '
InputOutputExpected
' + markupCodeForHtml(markedUpInput) + '' + markupCodeForHtml(output) + '' + markupCodeForHtml(test.expected) + '
' + operationsText + '
'; // test-table - - if (test.expected == output) { - // Pass - } else { - IO.writeFile(outputFile, IO.readFile(outputFile).contents() + outputHtml, false); - // TODO: Uncomment when things are working - // throw new Error('Format test failed - refer to ' + outputFile); - } - } - - var operationsTests: FormatOperationTestJson[] = eval('[' + IO.readFile(Harness.userSpecifiedroot + 'tests/cases/unittests/services/ruleFormattingTests.json').contents() + ']'); - for (var i = 0; i < operationsTests.length; i++) { - var test = operationsTests[i]; - - var msg = 'formats the text correctly, line = ' + i; - it(msg, function(t) { - return function() { - checkTest(t); - } - }(test)); - } -}); - diff --git a/src/harness/unittests/services/formatting/ruleFormattingTests.json b/src/harness/unittests/services/formatting/ruleFormattingTests.json deleted file mode 100644 index 8f330156f6..0000000000 --- a/src/harness/unittests/services/formatting/ruleFormattingTests.json +++ /dev/null @@ -1,284 +0,0 @@ -{ input: "function a() {\r\nvar b = 0;//}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 31 } } ], expected: "function a() {\r\nvar b = 0;//}\r\n}" }, -{ input: "function foo() {\n do {\n } while (y < 10)\n\n}", operations: [ { operation: "Enter", point: { position: 50 } } ], expected: "function foo() {\n do {\n } while (y < 10)\n\n}" }, -{ input: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\r\n}\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 87 } } ], expected: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\r\n }\r\n\r\n}" }, -{ input: "function a() {\r\n return (\r\n {\r\n x: 0\r\n }\r\n}", operations: [ { operation: "CloseBrace", point: { position: 76 } } ], expected: "function a() {\r\n return (\r\n {\r\n x: 0\r\n }\r\n}" }, -{ input: " if ( a[\";\"])\r\nb++;", operations: [ { operation: "Semicolon", point: { position: 10 } } ], expected: " if ( a[\";\"])\r\nb++;" }, -{ input: "(function () {\r\n a({\r\n b: 0\r\n });\r\n\r\n})();", operations: [ { operation: "Enter", point: { position: 48 } } ], expected: "(function () {\r\n a({\r\n b: 0\r\n });\r\n\r\n})();" }, -{ input: "var obj={a:{b:2,c:{d:{e:{\r\n}}}}}", operations: [ { operation: "Enter", point: { position: 27 } } ], expected: "var obj = {\n a: {\n b: 2, c: {\n d: {\n e: {\r\n }\n }\n }\n }\n}" }, -{ input: "if(1)if(1)if(1)if(1)x+=2;", operations: [ { operation: "Semicolon", point: { position: 25 } } ], expected: "if (1) if (1) if (1) if (1) x += 2;" }, -{ input: "\r\nvar webclass = [\r\n { 'student':\r\n { 'id': '1', 'name': 'Linda Jones', 'legacySkill': 'Access, VB 5.0' }\r\n }\r\n]", operations: [ { operation: "Document" } ], expected: "\r\nvar webclass = [\r\n {\n 'student':\r\n { 'id': '1', 'name': 'Linda Jones', 'legacySkill': 'Access, VB 5.0' }\r\n }\r\n]" }, -{ input: "function f(x){ return x }\nwhile (f(true))\n y++;\n", operations: [ { operation: "Enter", point: { position: 51 } } ], expected: "function f(x){ return x }\nwhile (f(true))\n y++;\n" }, -{ input: "throw e;", operations: [ { operation: "Document" } ], expected: "throw e;" }, -{ input: "x = {\n a: 1,\n b: 1\n +\n // test\n 2\n}", operations: [ { operation: "Document" } ], expected: "x = {\n a: 1,\n b: 1\n +\n // test\n 2\n}" }, -{ input: "return 1;", operations: [ { operation: "Document" } ], expected: "return 1;" }, -{ input: "var x = [\n 1,\n 2,\n 3\n]", operations: [ { operation: "Document" } ], expected: "var x = [\n 1,\n 2,\n 3\n]" }, -{ input: "switch \r\n( a ){\r\n case 1:x+=2; break\r\n case 2:{\r\n }\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 9 } } ], expected: "switch\r\n(a) {\r\n case 1:x+=2; break\r\n case 2:{\r\n }\r\n}\r\n" }, -{ input: "if (a)\r\ntest;\r\nelse\r\nif (b)\r\ntest;\r\n", operations: [ { operation: "Enter", point: { position: 36 } } ], expected: "if (a)\r\ntest;\r\nelse\r\nif (b)\r\n test;\r\n" }, -{ input: "do{\r\ndo{\r\ndo{\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)", operations: [ { operation: "CloseBrace", point: { position: 16 } } ], expected: "do{\r\ndo{\r\n do {\r\n } while (a !== b)\r\n}while(a!==b)\r\n}while(a!==b)" }, -{ input: "label1:\r\nvar a;\r\nvar b;", operations: [ { operation: "Document" } ], expected: "label1:\r\n var a;\r\nvar b;" }, -{ input: "\r\nfunction a() {\r\nfunction test() // test\r\n{\r\nif (test) // test\r\n{\r\n}\r\n}\r\n}", operations: [ { operation: "Document" } ], expected: "\r\nfunction a() {\r\n function test() // test\r\n {\r\n if (test) // test\r\n {\r\n }\r\n }\r\n}" }, -{ input: "var obj = {\r\na:{\r\nb:2,c:{\r\nd: {\r\ne: function f() {\r\nreturn obj.a.c.d.e() +f();\r\n}\r\n}\r\n}\r\n}\r\n};", operations: [ { operation: "Semicolon", point: { position: 94 } } ], expected: "var obj = {\r\n a: {\r\n b: 2, c: {\r\n d: {\r\n e: function f() {\r\n return obj.a.c.d.e() + f();\r\n }\r\n }\r\n }\r\n }\r\n};" }, -{ input: "function f() {\r\n do{\r\nx++ }\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "function f() {\r\n do{\r\n x++\n }\r\n\r\n}" }, -{ input: "function foo (a, b, c)", operations: [ { operation: "Document" } ], expected: "function foo(a, b, c)" }, -{ input: "{ var b;\n}", operations: [ { operation: "Document" } ], expected: "{\n var b;\n}" }, -{ input: "var z = {\na: 1};", operations: [ { operation: "Document" } ], expected: "var z = {\n a: 1\n};" }, -{ input: "for (var i = 0; i < 10; i++)\n { var a\n}", operations: [ { operation: "Document" } ], expected: "for (var i = 0; i < 10; i++) {\n var a\n}" }, -{ input: "if (1)\n {\nvar a }", operations: [ { operation: "Document" } ], expected: "if (1) {\n var a\n}" }, -{ input: "while (1)\n { var a\n}", operations: [ { operation: "Document" } ], expected: "while (1) {\n var a\n}" }, -{ input: "do\n { var a\n} while (1)", operations: [ { operation: "Document" } ], expected: "do {\n var a\n} while (1)" }, -{ input: "for (var a in b)\n { var a\n}", operations: [ { operation: "Document" } ], expected: "for (var a in b) {\n var a\n}" }, -{ input: "with (x)\n { var a\n}", operations: [ { operation: "Document" } ], expected: "with (x) {\n var a\n}" }, -{ input: "try\n { var a\n} \ncatch (e)\n { var a\n} \nfinally\n {\n}", operations: [ { operation: "Document" } ], expected: "try {\n var a\n}\ncatch (e) {\n var a\n}\nfinally {\n}" }, -{ input: "switch (x)\n { case 1: { var a }\n}", operations: [ { operation: "Document" } ], expected: "switch (x) {\n case 1: { var a }\n}" }, -{ input: "function f()\n { var x\n}", operations: [ { operation: "Document" } ], expected: "function f() {\n var x\n}" }, -{ input: "if(1)if(1)if(1)if(1){x+=2\r\n}", operations: [ { operation: "CloseBrace", point: { position: 28 } } ], expected: "if (1) if (1) if (1) if (1) {\n x += 2\r\n}" }, -{ input: "switch (a){\r\n case 1: x += 2;\r\n case 2 : \r\n for (var i=0;i<10;i++)\r\ni --;\r\n}\r\n", operations: [ { operation: "Semicolon", point: { position: 84 } } ], expected: "switch (a){\r\n case 1: x += 2;\r\n case 2 : \r\n for (var i = 0; i < 10; i++)\r\n i--;\r\n}\r\n" }, -{ input: "do{for(var i=0;i<10;i++)i-=2}while(1!==1);", operations: [ { operation: "Semicolon", point: { position: 42 } } ], expected: "do { for (var i = 0; i < 10; i++) i -= 2 } while (1 !== 1);" }, -{ input: "for(var i=0;i<10;i++){for(var j=0;j<10;j++)\r\n{j-=i}}", operations: [ { operation: "Enter", point: { position: 45 } } ], expected: "for (var i = 0; i < 10; i++) {\n for (var j = 0; j < 10; j++)\r\n { j -= i }\n}" }, -{ input: "function f() {\r\nstring='string\\r\n line2' + 'other part'}", operations: [ { operation: "CloseBrace", point: { position: 63 } } ], expected: "function f() {\r\n string = 'string\\r\n line2' + 'other part'\n}" }, -{ input: "x =\r\n function ()\r\n{\r\n var a\r\n}", operations: [ { operation: "Document" } ], expected: "x =\r\n function () {\r\n var a\r\n }" }, -{ input: "if (a instanceof b) { }", operations: [ { operation: "Document" } ], expected: "if (a instanceof b) { }" }, -{ input: "do a++; while (0)", operations: [ { operation: "Document" } ], expected: "do a++; while (0)" }, -{ input: "foo\r\n(1, 2, 3)", operations: [ { operation: "Document" } ], expected: "foo\r\n(1, 2, 3)" }, -{ input: "if(1) //comment\r\n{\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "if (1) //comment\r\n{\r\n}\r\n" }, -{ input: "var x =\n [\n1\n]", operations: [ { operation: "Document" } ], expected: "var x =\n [\n1\n ]" }, -{ input: "\r\n{\r\n function f() {\r\n var s = 1\r\n }\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 59 } } ], expected: "\r\n{\r\n function f() {\r\n var s = 1\r\n }\r\n\r\n}" }, -{ input: "\r\ndefine(null,\r\n function test() {\r\nvar a;\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\ndefine(null,\r\n function test() {\r\n var a;\r\n }\r\n" }, -{ input: "x = [\r\n 1,\r\n\r\n]", operations: [ { operation: "Enter", point: { position: 15 } } ], expected: "x = [\r\n 1,\r\n\r\n]" }, -{ input: "var x =\n {\na: 1\n}", operations: [ { operation: "Document" } ], expected: "var x =\n {\n a: 1\n }" }, -{ input: "for(var i=0;i<10;i++){for(var j=0;j<10;j++){j-=i}}", operations: [ { operation: "CloseBrace", point: { position: 50 } } ], expected: "for (var i = 0; i < 10; i++) { for (var j = 0; j < 10; j++) { j -= i } }" }, -{ input: "function f()\n{\n for (a in b)\n a++;\n}", operations: [ { operation: "Semicolon", point: { position: 40 } } ], expected: "function f()\n{\n for (a in b)\n a++;\n}" }, -{ input: "if(x!=1^y===2) \r\nx+=2\r\n", operations: [ { operation: "Enter", point: { position: 25 } } ], expected: "if(x!=1^y===2) \r\n x += 2\r\n" }, -{ input: "if (1)\r\n if (1)\r\n x++\r\n else\r\n if (1)\r\n x--\r\nelse\r\n x+=2\r\n", operations: [ { operation: "Enter", point: { position: 81 } } ], expected: "if (1)\r\n if (1)\r\n x++\r\n else\r\n if (1)\r\n x--\r\n else\r\n x += 2\r\n" }, -{ input: "switch (a){\r\ncase 1 : x+=2 ; break;\r\n case 2:{\r\n }\r\n}\r\n", operations: [ { operation: "Semicolon", point: { position: 44 } } ], expected: "switch (a){\r\n case 1: x += 2; break;\r\n case 2:{\r\n }\r\n}\r\n" }, -{ input: "{ { {\r\n{\r\ntest\r\n}\r\n}\r\n}\r\n}", operations: [ { operation: "Selection", span: { start: 7, length: 19 } } ], expected: "{ { {\r\n {\r\n test\r\n }\r\n}\r\n}\r\n}" }, -{ input: "do {\r\n do {\r\n do {\r\n }while(a!==b)\r\n\r\n} while (a !== b)\r\n} while (a !== b)", operations: [ { operation: "Enter", point: { position: 55 } } ], expected: "do {\r\n do {\r\n do {\r\n }while(a!==b)\r\n\r\n } while (a !== b)\r\n} while (a !== b)" }, -{ input: "\r\nswitch (t) {\r\n case 1:\r\n{\r\ntest\r\n}\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\nswitch (t) {\r\n case 1:\r\n {\r\n test\r\n }\r\n}\r\n" }, -{ input: "if (true) {\r\n \r\n}", operations: [ { operation: "Document" } ], expected: "if (true) {\r\n\r\n}" }, -{ input: "for(var j=0;j<10;j++)\r\nj-=i;", operations: [ { operation: "Semicolon", point: { position: 28 } } ], expected: "for (var j = 0; j < 10; j++)\r\n j -= i;" }, -{ input: "function a() {\r\n function b() {\r\n //\r\n\r\n }\r\n}", operations: [ { operation: "Enter", point: { position: 48 } } ], expected: "function a() {\r\n function b() {\r\n //\r\n\r\n }\r\n}" }, -{ input: "if(1)if(1)if(1)if(1)x+=2\r\n", operations: [ { operation: "Enter", point: { position: 26 } } ], expected: "if (1) if (1) if (1) if (1) x += 2\r\n" }, -{ input: "do{do{do{}while(a!==b)}while(a!==b)}while(a!==b)\r\n", operations: [ { operation: "Enter", point: { position: 50 } } ], expected: "do { do { do { } while (a !== b) } while (a !== b) } while (a !== b)\r\n" }, -{ input: "foo(\r\n)", operations: [ { operation: "Document" } ], expected: "foo(\r\n)" }, -{ input: "function f() {\r\n'use strict';\r\n}", operations: [ { operation: "Semicolon", point: { position: 29 } } ], expected: "function f() {\r\n 'use strict';\r\n}" }, -{ input: "var x = function() {\n//comment\nreturn 1;\n}", operations: [ { operation: "Document" } ], expected: "var x = function () {\n //comment\n return 1;\n}" }, -{ input: " function foo4() {\r\n function foo5() {\r\n function foo6() {\r\n test1\r\n }\r\n test2\r\n }\r\n }", operations: [ { operation: "Selection", span: { start: 62, length: 120 } } ], expected: " function foo4() {\r\n function foo5() {\r\n function foo6() {\r\n test1\r\n }\r\n test2\r\n }\r\n }" }, -{ input: "do{\r\ndo{\r\ndo{\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)", operations: [ { operation: "CloseBrace", point: { position: 46 } } ], expected: "do {\r\n do {\r\n do {\r\n } while (a !== b)\r\n } while (a !== b)\r\n} while (a !== b)" }, -{ input: "if (true)\n// test\n test;", operations: [ { operation: "Document" } ], expected: "if (true)\n // test\n test;" }, -{ input: "function test() {\r\n return (\r\n function test() {\r\n test;\r\n }\r\n );\r\n}", operations: [ { operation: "Document" } ], expected: "function test() {\r\n return (\r\n function test() {\r\n test;\r\n }\r\n );\r\n}" }, -{ input: "for(var i=0;i<10;i++){\r\nfor(var j=0;j<10;j++){\r\nj-=i\r\n}}", operations: [ { operation: "CloseBrace", point: { position: 56 } } ], expected: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\r\n }\n}" }, -{ input: " var a = 0 ;", operations: [ { operation: "Semicolon", point: { position: 14 } } ], expected: "var a = 0;" }, -{ input: "var obj={a:{b:2,c:{d:\r\n{e:{}}}}}", operations: [ { operation: "Enter", point: { position: 23 } } ], expected: "var obj = {\n a: {\n b: 2, c: {\n d:\r\n { e: {} }\n }\n }\n}" }, -{ input: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n}finally {\r\nx+=2\r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 74 } } ], expected: "function foo() {\r\n try {\r\n x += 2\r\n }\r\n catch (e) {\r\n x += 2\r\n } finally {\r\n x += 2\r\n }\r\n}" }, -{ input: "var obj = {\r\na: {\r\nb: 2, c: {\r\nd: {\r\ne: function f() {\r\nreturn obj.a.c.d.e() + f();\r\n}\r\n}\r\n}\r\n}}", operations: [ { operation: "CloseBrace", point: { position: 96 } } ], expected: "var obj = {\r\n a: {\r\n b: 2, c: {\r\n d: {\r\n e: function f() {\r\n return obj.a.c.d.e() + f();\r\n }\r\n }\r\n }\r\n }\n}" }, -{ input: "if (x!=1^y===2){ x+=2}", operations: [ { operation: "CloseBrace", point: { position: 24 } } ], expected: "if (x != 1 ^ y === 2) { x += 2 }" }, -{ input: "function test() {\r\n var a;\r\n label:\r\n for (; ;)\r\n\r\n", operations: [ { operation: "Enter", point: { position: 58 } } ], expected: "function test() {\r\n var a;\r\n label:\r\n for (; ;)\r\n\r\n" }, -{ input: "for(var i=0;i<10;i++){for(var j=0;j<10;j++){\r\nj-=i}}", operations: [ { operation: "Enter", point: { position: 46 } } ], expected: "for (var i = 0; i < 10; i++) {\n for (var j = 0; j < 10; j++) {\r\n j -= i\n }\n}" }, -{ input: "do {\r\n for (var i = 0; i < 10; i++)\r\n i -= 2\r\n }\r\nwhile (1 !== 1)", operations: [ { operation: "Enter", point: { position: 67 } } ], expected: "do {\r\n for (var i = 0; i < 10; i++)\r\n i -= 2\r\n}\r\nwhile (1 !== 1)" }, -{ input: "{\r\n try {\r\n } catch (e) {\r\n }\r\n}", operations: [ { operation: "Document" } ], expected: "{\r\n try {\r\n } catch (e) {\r\n }\r\n}" }, -{ input: "{ { {\r\n{\r\n}\r\n}\r\n}\r\n}", operations: [ { operation: "Selection", span: { start: 7, length: 13 } } ], expected: "{ { {\r\n {\r\n }\r\n}\r\n}\r\n}" }, -{ input: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) {\r\nj -= i}}\r\n", operations: [ { operation: "Enter", point: { position: 78 } } ], expected: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\n }\n}\r\n" }, -{ input: "var a = {\r\n}", operations: [ { operation: "Document" } ], expected: "var a = {\r\n}" }, -{ input: "\r\n switch ( a ) {\r\n case 1: x+=2;\r\n case 2:{\r\n }\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 2 } } ], expected: "\r\nswitch (a) {\r\n case 1: x+=2;\r\n case 2:{\r\n }\r\n}\r\n" }, -{ input: "function a() {\r\nvar b = 0;//;\r\n}", operations: [ { operation: "Semicolon", point: { position: 31 } } ], expected: "function a() {\r\nvar b = 0;//;\r\n}" }, -{ input: "for (a in b) { }", operations: [ { operation: "Document" } ], expected: "for (a in b) { }" }, -{ input: "\r\n{\r\nfunction test(/* test */ a,\r\n /* test */ b\r\n /* test */) {\r\n// test\r\n}\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\n{\r\n function test(/* test */ a,\r\n /* test */ b\r\n /* test */) {\r\n // test\r\n }\r\n}\r\n" }, -{ input: " //\r\n", operations: [ { operation: "Enter", point: { position: 8 } } ], expected: "//\r\n" }, -{ input: " if ( a[\"}\"])\r\nb++;", operations: [ { operation: "CloseBrace", point: { position: 10 } } ], expected: " if ( a[\"}\"])\r\nb++;" }, -{ input: "$ ( document ) . ready ( function ( ) { \n alert ( \"i am ready\" ) ;\n } );", operations: [ { operation: "Semicolon", point: { position: 138 } } ], expected: "$(document).ready(function () {\n alert(\"i am ready\");\n});" }, -{ input: "function f() {\r\nvar s=\"string\";\r\n}", operations: [ { operation: "Semicolon", point: { position: 31 } } ], expected: "function f() {\r\n var s = \"string\";\r\n}" }, -{ input: "do{for(var i=0;i<10;i++)i-=2\r\n}while(1!==1)", operations: [ { operation: "Enter", point: { position: 30 } } ], expected: "do {\n for (var i = 0; i < 10; i++) i -= 2\r\n} while (1 !== 1)" }, -{ input: "do{\r\ndo{\r\n\r\ndo{\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)", operations: [ { operation: "Enter", point: { position: 12 } } ], expected: "do{\r\ndo{\r\n\r\n do {\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)" }, -{ input: "for(var i=0;i<10;i++){for(var j=0;j<10;j++){j-=i}}", operations: [ { operation: "CloseBrace", point: { position: 49 } } ], expected: "for (var i = 0; i < 10; i++) { for (var j = 0; j < 10; j++) { j -= i }}" }, -{ input: "var obj = {\r\na: {\r\nb: 2, c: {\r\nd: {\r\ne: function f() {\r\nreturn obj.a.c.d.e() + f();\r\n}\r\n}\r\n } \r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 99 } } ], expected: "var obj = {\r\na: {\r\n b: 2, c: {\r\n d: {\r\n e: function f() {\r\n return obj.a.c.d.e() + f();\r\n }\r\n }\r\n }\r\n}\r\n}" }, -{ input: "var a = 0 ;var b=0;var c = 0 ;", operations: [ { operation: "Paste", span: { start: 13, length: 7 } } ], expected: "var a = 0; var b = 0; var c = 0;" }, -{ input: "function a()\r\n{\r\n}", operations: [ { operation: "Enter", point: { position: 14 } } ], expected: "function a()\r\n{\r\n}" }, -{ input: " function test() { function foo() { function foo3() { function foo4() { function foo5() { function foo6()\r\n{\r\ntest\r\n}\r\n}\r\n}\r\n}\r\n}\r\n}", operations: [ { operation: "Selection", span: { start: 110, length: 25 } } ], expected: " function test() { function foo() { function foo3() { function foo4() { function foo5() { function foo6()\r\n {\r\n test\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }" }, -{ input: " \r\nfunction a() { \r\n return; \r\n} \r\n ", operations: [ { operation: "Document" } ], expected: "\r\nfunction a() {\r\n return;\r\n}\r\n" }, -{ input: "foo(\r\n1, 2, 3)", operations: [ { operation: "Document" } ], expected: "foo(\r\n1, 2, 3)" }, -{ input: "function Init() {\r\n var a = [[1, 2],\r\n [3, 4],\r\n\r\n ];\r\n}", operations: [ { operation: "Enter", point: { position: 63 } } ], expected: "function Init() {\r\n var a = [[1, 2],\r\n [3, 4],\r\n\r\n ];\r\n}" }, -{ input: "\r\n //function start\r\n function abc() { }\r\n //function end\r\n", operations: [ { operation: "Document" } ], expected: "\r\n//function start\r\nfunction abc() { }\r\n//function end\r\n" }, -{ input: "for(var i=0;i<10;i++){\r\n for (var j = 0; j < 10; j++) {\r\nj-=i\r\n\r\n}\r\n}", operations: [ { operation: "Enter", point: { position: 66 } } ], expected: "for(var i=0;i<10;i++){\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\r\n\r\n}\r\n}" }, -{ input: "// JScript source code\r\nfunction adder(a, b) {\r\n ///Adds two numbers \r\n return a + b;\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 94 } } ], expected: "// JScript source code\r\nfunction adder(a, b) {\r\n ///Adds two numbers \r\n return a + b;\r\n}\r\n" }, -{ input: "x = {\r\n a: function() {\r\n},\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "x = {\r\n a: function() {\r\n },\r\n\r\n}" }, -{ input: "if(1)\r\n if(1)\r\n x++\r\n else\r\n if(1)\r\n x+=2\r\n else\r\nx+=2\r\n", operations: [ { operation: "Enter", point: { position: 94 } } ], expected: "if(1)\r\n if(1)\r\n x++\r\n else\r\n if(1)\r\n x+=2\r\n else\r\n x += 2\r\n" }, -{ input: "for (a in b) {\nx++;}\n", operations: [ { operation: "Enter", point: { position: 21 } } ], expected: "for (a in b) {\n x++;\n}\n" }, -{ input: "if(1)if(1)if(1)if(1){x+=2}", operations: [ { operation: "CloseBrace", point: { position: 26 } } ], expected: "if (1) if (1) if (1) if (1) { x += 2 }" }, -{ input: "if (x!=1^y===2){ x+=2\r\n}", operations: [ { operation: "CloseBrace", point: { position: 26 } } ], expected: "if (x != 1 ^ y === 2) {\n x += 2\r\n}" }, -{ input: "var d = new Date ()", operations: [ { operation: "Document" } ], expected: "var d = new Date()" }, -{ input: "do {\r\n} while (1 == 10);", operations: [ { operation: "Document" } ], expected: "do {\r\n} while (1 == 10);" }, -{ input: "string='string+=2';", operations: [ { operation: "Semicolon", point: { position: 19 } } ], expected: "string = 'string+=2';" }, -{ input: "function foo() {\r\n try {\r\n }\r\ncatch(e){\r\n } finally {\r\n }\r\n}", operations: [ { operation: "Enter", point: { position: 48 } } ], expected: "function foo() {\r\n try {\r\n }\r\n catch (e) {\r\n } finally {\r\n }\r\n}" }, -{ input: "try // comment\r\n{\r\n}\r\ncatch (e) // comment\r\n{\r\n}\r\nfinally // comment\r\n{\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "try // comment\r\n{\r\n}\r\ncatch (e) // comment\r\n{\r\n}\r\nfinally // comment\r\n{\r\n}\r\n" }, -{ input: "function f() {\r\n /**/ var x;\r\n}", operations: [ { operation: "Semicolon", point: { position: 39 } } ], expected: "function f() {\r\n /**/ var x;\r\n}" }, -{ input: "if (a)\r\ntest;\r\nelse if (b)\r\ntest;", operations: [ { operation: "Document" } ], expected: "if (a)\r\n test;\r\nelse if (b)\r\n test;" }, -{ input: "foo(1, 2, 3\r\n)", operations: [ { operation: "Document" } ], expected: "foo(1, 2, 3\r\n)" }, -{ input: "\r\nswitch (a){\r\n case 1: x++;\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\nswitch (a) {\r\n case 1: x++;\r\n}\r\n" }, -{ input: "x = {\r\n a: function () {\r\n\r\n }\r\n}", operations: [ { operation: "Enter", point: { position: 39 } } ], expected: "x = {\r\n a: function () {\r\n\r\n }\r\n}" }, -{ input: "switch (a) {\n case 1: b++;\n break;\n\n default: a++;\n break;\n}", operations: [ { operation: "Enter", point: { position: 45 } } ], expected: "switch (a) {\n case 1: b++;\n break;\n\n default: a++;\n break;\n}" }, -{ input: "string='string+=2;'", operations: [ { operation: "Semicolon", point: { position: 18 } } ], expected: "string='string+=2;'" }, -{ input: "function test() {\r\n function foo() {\r\n var a;\r\n// some\r\ncomment\r\n", operations: [ { operation: "Enter", point: { position: 66 } } ], expected: "function test() {\r\n function foo() {\r\n var a;\r\n // some\r\n comment\r\n" }, -{ input: "switch ( a ) {\r\n case 1: x+=2;\r\n case 2:{for(var i=0;i<10;i++){ \r\nx+=2;}\r\n }\r\n}", operations: [ { operation: "CloseBrace", point: { position: 89 } } ], expected: "switch (a) {\r\n case 1: x += 2;\r\n case 2: {\n for (var i = 0; i < 10; i++) {\r\n x += 2;\n }\r\n }\r\n}" }, -{ input: "do{\r\nfor(var i=0;i<10;i++)\r\ni-=2;\r\n}while(1!==1)", operations: [ { operation: "Semicolon", point: { position: 33 } } ], expected: "do{\r\n for (var i = 0; i < 10; i++)\r\n i -= 2;\r\n}while(1!==1)" }, -{ input: "\r\nfunction foo() {\r\n try{ } catch (e) { } finally { }\r\n\r\n\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 63 } } ], expected: "\r\nfunction foo() {\r\n try { } catch (e) { } finally { }\r\n\r\n\r\n}\r\n" }, -{ input: "do{for(var i=0;i<10;i++)\r\ni-=2}while(1!==1)", operations: [ { operation: "Enter", point: { position: 26 } } ], expected: "do {\n for (var i = 0; i < 10; i++)\r\n i -= 2\n} while (1 !== 1)" }, -{ input: "\r\n fun(\r\n {\r\n a: 1\r\n });\r\n", operations: [ { operation: "Document" } ], expected: "\r\nfun(\r\n {\r\n a: 1\r\n });\r\n" }, -{ input: "function f () //comment\r\n{\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "function f() //comment\r\n{\r\n}\r\n" }, -{ input: "function a(b) {\r\n var c = 0;\r\n if (b != null) {\r\n for (d in b) {\r\n }\r\n }\r\n}", operations: [ { operation: "CloseBrace", point: { position: 94 } } ], expected: "function a(b) {\r\n var c = 0;\r\n if (b != null) {\r\n for (d in b) {\r\n }\r\n }\r\n}" }, -{ input: "switch (a) {\r\n case 1:\r\n\r\n break;\r\n}", operations: [ { operation: "Enter", point: { position: 34 } } ], expected: "switch (a) {\r\n case 1:\r\n\r\n break;\r\n}" }, -{ input: " \r\n do{\r\n for(var i=0;i<10;i++)\r\n i -= 2\r\n}\r\nwhile (1 !== 1)", operations: [ { operation: "Enter", point: { position: 5 } } ], expected: "\r\ndo {\r\n for(var i=0;i<10;i++)\r\n i -= 2\r\n}\r\nwhile (1 !== 1)" }, -{ input: "function test() {\r\n label1:\r\nvar a\r\n\r\n var b;\r\n}", operations: [ { operation: "Enter", point: { position: 39 } } ], expected: "function test() {\r\n label1:\r\n var a\r\n\r\n var b;\r\n}" }, -{ input: "var x = {\n//comment\na: 1\n}", operations: [ { operation: "Document" } ], expected: "var x = {\n //comment\n a: 1\n}" }, -{ input: "for(var i=0;i<10;i++){\r\n\r\nfor(var j=0;j<10;j++){\r\nj-=i\r\n}\r\n}", operations: [ { operation: "Enter", point: { position: 26 } } ], expected: "for(var i=0;i<10;i++){\r\n\r\n for (var j = 0; j < 10; j++) {\r\nj-=i\r\n}\r\n}" }, -{ input: "if (true) {\r\n//\r\n} else if (false) {\r\n//\r\n} else\r\n if (true)\r\n//", operations: [ { operation: "Document" } ], expected: "if (true) {\r\n //\r\n} else if (false) {\r\n //\r\n} else\r\n if (true)\r\n //" }, -{ input: "x = [\n 1,\n 1\n +\n // test\n 2\n]", operations: [ { operation: "Document" } ], expected: "x = [\n 1,\n 1\n +\n // test\n 2\n]" }, -{ input: "var x =\n function() {\nreturn 1;\n}", operations: [ { operation: "Document" } ], expected: "var x =\n function () {\n return 1;\n }" }, -{ input: "function f() {\n var x }", operations: [ { operation: "Document" } ], expected: "function f() {\n var x\n}" }, -{ input: "switch (a) {\r\n case 1: b++;\r\n break ;\r\n\r\n default: a++;\r\n break;\r\n}", operations: [ { operation: "Enter", point: { position: 46 } } ], expected: "switch (a) {\r\n case 1: b++;\r\n break;\r\n\r\n default: a++;\r\n break;\r\n}" }, -{ input: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n} finally {\r\nx+=2\r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 32 } } ], expected: "function foo() {\r\n try {\r\n x += 2\r\n }\r\ncatch( e){\r\nx+=2\r\n} finally {\r\nx+=2\r\n}\r\n}" }, -{ input: "function f(a, b\n , c){\n}", operations: [ { operation: "CloseBrace", point: { position: 39 } } ], expected: "function f(a, b\n , c) {\n}" }, -{ input: "function add(a, b) { return a + b}", operations: [ { operation: "Document" } ], expected: "function add(a, b) { return a + b }" }, -{ input: "var a = 0 ;\r\n", operations: [ { operation: "Enter", point: { position: 15 } } ], expected: "var a = 0;\r\n" }, -{ input: "var a = function (b) {\r\nb = 0;\r\n}", operations: [ { operation: "CloseBrace", point: { position: 33 } } ], expected: "var a = function (b) {\r\n b = 0;\r\n}" }, -{ input: "\r\nif (\r\n test) {\r\n a;\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\nif (\r\n test) {\r\n a;\r\n}\r\n" }, -{ input: " var a = 0 ;\r\n var b = { } ;\r\n var c = false ;", operations: [ { operation: "Selection", span: { start: 18, length: 34 } } ], expected: " var a = 0 ;\r\n var b = {};\r\n var c = false ;" }, -{ input: "function a() {\r\n return (\r\n function () {\r\n return 0;\r\n }\r\n}", operations: [ { operation: "CloseBrace", point: { position: 93 } } ], expected: "function a() {\r\n return (\r\n function () {\r\n return 0;\r\n }\r\n}" }, -{ input: "function test() {\r\n label1:\r\n a();\r\n b()\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 59 } } ], expected: "function test() {\r\n label1:\r\n a();\r\n b()\r\n\r\n}" }, -{ input: "(function () {\r\n a({\r\n b: 0\r\n });\r\n})();", operations: [ { operation: "Document" } ], expected: "(function () {\r\n a({\r\n b: 0\r\n });\r\n})();" }, -{ input: "function a() {\r\n /**/ }", operations: [ { operation: "Document" } ], expected: "function a() {\r\n /**/\n}" }, -{ input: "for (var i = 0; i < 10; i++) {\r\n for (var j=0;j<10;j++) {\r\nj=i;\r\n }\r\n}", operations: [ { operation: "Semicolon", point: { position: 64 } } ], expected: "for (var i = 0; i < 10; i++) {\r\n for (var j=0;j<10;j++) {\r\n j = i;\r\n }\r\n}" }, -{ input: "function f() {\r\n var x; /*\r\n */ var y = 2;\r\n}", operations: [ { operation: "Document" } ], expected: "function f() {\r\n var x; /*\r\n */ var y = 2;\r\n}" }, -{ input: "foo (1, 2, 3)", operations: [ { operation: "Document" } ], expected: "foo(1, 2, 3)" }, -{ input: "if (typeof a == null);", operations: [ { operation: "Document" } ], expected: "if (typeof a == null);" }, -{ input: "function f() {\r\n var x = \"\\r\n \"; var y = 2;\r\n}", operations: [ { operation: "Document" } ], expected: "function f() {\r\n var x = \"\\r\n \"; var y = 2;\r\n}" }, -{ input: "void x;", operations: [ { operation: "Document" } ], expected: "void x;" }, -{ input: "function f() {\r\n string='string'\r\n }\r\n", operations: [ { operation: "Enter", point: { position: 44 } } ], expected: "function f() {\r\n string='string'\r\n}\r\n" }, -{ input: "do{\r\nfor(var i=0;i<10;i++)\r\ni-=2\r\n}while(1!==1);", operations: [ { operation: "Semicolon", point: { position: 48 } } ], expected: "do {\r\n for (var i = 0; i < 10; i++)\r\n i -= 2\r\n} while (1 !== 1);" }, -{ input: "function test() {\r\n return (\r\n {\r\n a: 1\r\n }\r\n );\r\n}", operations: [ { operation: "Document" } ], expected: "function test() {\r\n return (\r\n {\r\n a: 1\r\n }\r\n );\r\n}" }, -{ input: "for(var i=0;i<10;i++)\r\n{for(var j=0;j<10;j++){j-=i}}", operations: [ { operation: "Enter", point: { position: 23 } } ], expected: "for (var i = 0; i < 10; i++)\r\n{ for (var j = 0; j < 10; j++) { j -= i } }" }, -{ input: "for(var i=0;i<10;i++){\r\nfor(var j=0;j<10;j++){j-=i}}", operations: [ { operation: "Enter", point: { position: 24 } } ], expected: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) { j -= i }\n}" }, -{ input: "do{\r\nfor(var i=0;i<10;i++)\r\ni-=2\r\n}while(1!==1)\r\n", operations: [ { operation: "Enter", point: { position: 49 } } ], expected: "do{\r\nfor(var i=0;i<10;i++)\r\ni-=2\r\n} while (1 !== 1)\r\n" }, -{ input: "if(1===1\r\n&& 2===2)x+=2", operations: [ { operation: "Enter", point: { position: 10 } } ], expected: "if (1 === 1\r\n&& 2 === 2) x += 2" }, -{ input: "\r\n{\r\n\r\n/* test\r\n test2\r\n test3 */\r\nvar a,\r\n // test\r\n // test\r\n b;\r\n\r\nx = {\r\na: 1 +\r\n // test\r\n /* test\r\n test2 */\r\n 2\r\n}\r\n\r\na(1,\r\n 2). // test\r\n test(); /* test */\r\n\r\n/* test\r\n test2\r\n test3 */\r\nfunction foo(a, b,\r\n /* test\r\n test2\r\n test3 */\r\n c) {\r\n}\r\n\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\n{\r\n\r\n /* test\r\n test2\r\n test3 */\r\n var a,\r\n // test\r\n // test\r\n b;\r\n\r\n x = {\r\n a: 1 +\r\n // test\r\n /* test\r\n test2 */\r\n 2\r\n }\r\n\r\n a(1,\r\n 2). // test\r\n test(); /* test */\r\n\r\n /* test\r\n test2\r\n test3 */\r\n function foo(a, b,\r\n /* test\r\n test2\r\n test3 */\r\n c) {\r\n }\r\n\r\n}\r\n" }, -{ input: "\r\n for (var i = 0; i < 10\r\n ; i--) {\r\n test\r\n ;\r\n }\r\n", operations: [ { operation: "Document" } ], expected: "\r\nfor (var i = 0; i < 10\r\n ; i--) {\r\n test\r\n ;\r\n}\r\n" }, -{ input: "if (1)\r\n x++;\r\nelse if (1)\r\n x--;", operations: [ { operation: "Document" } ], expected: "if (1)\r\n x++;\r\nelse if (1)\r\n x--;" }, -{ input: "x = {\n get foo () {\n },\n set foo (val) {\n }\n};", operations: [ { operation: "Document" } ], expected: "x = {\n get foo() {\n },\n set foo(val) {\n }\n};" }, -{ input: "function foo\r\n(a, b, c) {\r\n}", operations: [ { operation: "Document" } ], expected: "function foo\r\n(a, b, c) {\r\n}" }, -{ input: "switch ( a ) {\r\n case 1: x+=2;\r\n case 2:{for(var i=0;i<10;i++){ \r\nx+=2;\r\n }}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 80 } } ], expected: "switch ( a ) {\r\n case 1: x+=2;\r\n case 2: {\n for (var i = 0; i < 10; i++) {\r\n x += 2;\r\n }\n }\r\n}" }, -{ input: "function f() {\r\n'use strict'}", operations: [ { operation: "CloseBrace", point: { position: 29 } } ], expected: "function f() {\r\n 'use strict'\n}" }, -{ input: "foo(1\r\n, 2, 3)", operations: [ { operation: "Document" } ], expected: "foo(1\r\n, 2, 3)" }, -{ input: "do{\r\ndo\r\n{\r\ndo{\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)", operations: [ { operation: "Enter", point: { position: 9 } } ], expected: "do{\r\n do\r\n {\r\ndo{\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)" }, -{ input: "function Sum(a,b,c) {\r\n for(i=0,j=1,k=0,fib=1;i<5;i++,fib=j+k,k=j,j=fib) {\r\n var sparseArray = [1,,,,5]\r\n }\r\n}", operations: [ { operation: "Selection", span: { start: 49, length: 3 } } ], expected: "function Sum(a,b,c) {\r\n for (i = 0, j = 1, k = 0, fib = 1; i < 5; i++, fib = j + k, k = j, j = fib) {\r\n var sparseArray = [1,,,,5]\r\n }\r\n}" }, -{ input: "function a() {\r\n function b() {\r\n\r\n }\r\n}", operations: [ { operation: "Document" } ], expected: "function a() {\r\n function b() {\r\n\r\n }\r\n}" }, -{ input: "", operations: [ { operation: "Document" } ], expected: "" }, -{ input: "function a() {\r\nvar b=\"c\"\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 27 } } ], expected: "function a() {\r\n var b = \"c\"\r\n\r\n}" }, -{ input: " if ( a[\"\r\n\"])\r\nb++;", operations: [ { operation: "Enter", point: { position: 11 } } ], expected: "if ( a[\"\r\n\"])\r\nb++;" }, -{ input: "/* \r\n \r\n*/ ", operations: [ { operation: "Document" } ], expected: "/* \r\n \r\n*/" }, -{ input: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n}finally {\r\nx+=2\r\n}\r\n};", operations: [ { operation: "Semicolon", point: { position: 75 } } ], expected: "function foo() {\r\n try {\r\n x += 2\r\n }\r\n catch (e) {\r\n x += 2\r\n } finally {\r\n x += 2\r\n }\r\n};" }, -{ input: "if (1) if (1) a++;", operations: [ { operation: "Document" } ], expected: "if (1) if (1) a++;" }, -{ input: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n}finally {\r\nx+=2\r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 53 } } ], expected: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\n catch (e) {\r\n x += 2\r\n }finally {\r\nx+=2\r\n}\r\n}" }, -{ input: "function f() {\r\n'use strict'\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 30 } } ], expected: "function f() {\r\n 'use strict'\r\n\r\n}" }, -{ input: " \r\n ", operations: [ { operation: "Document" } ], expected: " \r\n " }, -{ input: "{ var b; }", operations: [ { operation: "Document" } ], expected: "{ var b; }" }, -{ input: "var z = {a: 1};", operations: [ { operation: "Document" } ], expected: "var z = { a: 1 };" }, -{ input: "var z =\n {a: 1};", operations: [ { operation: "Document" } ], expected: "var z =\n { a: 1 };" }, -{ input: "for (var i = 0; i < 10; i++) { var a }", operations: [ { operation: "Document" } ], expected: "for (var i = 0; i < 10; i++) { var a }" }, -{ input: "for (var i = 0; i < 10; i++)\n { var a }", operations: [ { operation: "Document" } ], expected: "for (var i = 0; i < 10; i++)\n{ var a }" }, -{ input: "if (1) { var a }", operations: [ { operation: "Document" } ], expected: "if (1) { var a }" }, -{ input: "if (1)\n { var a }", operations: [ { operation: "Document" } ], expected: "if (1)\n{ var a }" }, -{ input: "while (1) { var a }", operations: [ { operation: "Document" } ], expected: "while (1) { var a }" }, -{ input: "while (1)\n { var a }", operations: [ { operation: "Document" } ], expected: "while (1)\n{ var a }" }, -{ input: "do { var a } while (1)", operations: [ { operation: "Document" } ], expected: "do { var a } while (1)" }, -{ input: "do\n { var a }\n while (1)", operations: [ { operation: "Document" } ], expected: "do\n{ var a }\nwhile (1)" }, -{ input: "for (var a in b) { var a }", operations: [ { operation: "Document" } ], expected: "for (var a in b) { var a }" }, -{ input: "for (var a in b)\n { var a }", operations: [ { operation: "Document" } ], expected: "for (var a in b)\n{ var a }" }, -{ input: "with (x) { var a }", operations: [ { operation: "Document" } ], expected: "with (x) { var a }" }, -{ input: "with (x)\n { var a }", operations: [ { operation: "Document" } ], expected: "with (x)\n{ var a }" }, -{ input: "try { var a } \ncatch (e) { var a } \nfinally { }", operations: [ { operation: "Document" } ], expected: "try { var a }\ncatch (e) { var a }\nfinally { }" }, -{ input: "try\n { var a } \ncatch (e)\n { var a } \nfinally\n { }", operations: [ { operation: "Document" } ], expected: "try\n{ var a }\ncatch (e)\n{ var a }\nfinally\n{ }" }, -{ input: "switch (x) { case 1: { var a } }", operations: [ { operation: "Document" } ], expected: "switch (x) { case 1: { var a } }" }, -{ input: "switch (x)\n { case 1: { var a } }", operations: [ { operation: "Document" } ], expected: "switch (x)\n{ case 1: { var a } }" }, -{ input: "function f() { var x }", operations: [ { operation: "Document" } ], expected: "function f() { var x }" }, -{ input: "function f()\n\n { var x }", operations: [ { operation: "Document" } ], expected: "function f()\n\n{ var x }" }, -{ input: "function test() {\r\nlabel1:\r\nvar a;\r\nvar b;\r\n}", operations: [ { operation: "Document" } ], expected: "function test() {\r\n label1:\r\n var a;\r\n var b;\r\n}" }, -{ input: "{\n x =\nfunction () {\n };\n}", operations: [ { operation: "Document" } ], expected: "{\n x =\nfunction () {\n};\n}" }, -{ input: "switch (a){\r\n case 1: x+=2;\r\ncase 2 : { \r\nx+=2}\r\n}", operations: [ { operation: "Enter", point: { position: 49 } } ], expected: "switch (a){\r\n case 1: x+=2;\r\n case 2: {\r\n x += 2\n }\r\n}" }, -{ input: " // ;", operations: [ { operation: "Semicolon", point: { position: 7 } } ], expected: " // ;" }, -{ input: "// JScript source code\r\nfunction adder(a, b) {\r\n ///Adds two numbers \r\n return a + b;\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 115 } } ], expected: "// JScript source code\r\nfunction adder(a, b) {\r\n ///Adds two numbers \r\n return a + b;\r\n}\r\n" }, -{ input: "function foo4() {\r\n test;\r\n for (; ;) {\r\n test\r\n }\r\n}", operations: [ { operation: "Selection", span: { start: 46, length: 33 } } ], expected: "function foo4() {\r\n test;\r\n for (; ;) {\r\n test\r\n }\r\n}" }, -{ input: "if (a in b) { }", operations: [ { operation: "Document" } ], expected: "if (a in b) { }" }, -{ input: "\r\nfunction f() {\r\nlabel0:\r\nfor (var i = 0; i < 10; i++) {\r\nlabel1: {\r\nfor (var i = 0; i < 10; i++)\r\nx = 2;\r\nlabel2:\r\nfor (var i = 0; i < 10; i++) {\r\nbreak label2\r\n}\r\n}\r\n}\r\n}", operations: [ { operation: "Document" } ], expected: "\r\nfunction f() {\r\n label0:\r\n for (var i = 0; i < 10; i++) {\r\n label1: {\r\n for (var i = 0; i < 10; i++)\r\n x = 2;\r\n label2:\r\n for (var i = 0; i < 10; i++) {\r\n break label2\r\n }\r\n }\r\n }\r\n}" }, -{ input: "function f() {\r\nstring='string'}", operations: [ { operation: "CloseBrace", point: { position: 32 } } ], expected: "function f() {\r\n string = 'string'\n}" }, -{ input: "\r\nfunction a() {\r\nfunction test() /* test */\r\n{\r\nif (test) /* test */\r\n{\r\n}\r\n}\r\n}", operations: [ { operation: "Document" } ], expected: "\r\nfunction a() {\r\n function test() /* test */ {\r\n if (test) /* test */ {\r\n }\r\n }\r\n}" }, -{ input: "that = {\r\n method: function () {\r\n return this.datum;\r\n } , \r\n\r\n datum: 0\r\n};", operations: [ { operation: "Enter", point: { position: 98 } } ], expected: "that = {\r\n method: function () {\r\n return this.datum;\r\n },\r\n\r\n datum: 0\r\n};" }, -{ input: "for (; ;)\n// test\n test;", operations: [ { operation: "Document" } ], expected: "for (; ;)\n // test\n test;" }, -{ input: "(function () {\r\n a({\r\n b: 0\r\n });\r\n\r\n})();", operations: [ { operation: "Enter", point: { position: 50 } } ], expected: "(function () {\r\n a({\r\n b: 0\r\n });\r\n\r\n})();" }, -{ input: "var f = function () {\n mycanvas.onmousedown = function () {\n };\n\n}", operations: [ { operation: "Enter", point: { position: 70 } } ], expected: "var f = function () {\n mycanvas.onmousedown = function () {\n };\n\n}" }, -{ input: "var obj={a:{b:2,c:{d:{e:{}}}}};", operations: [ { operation: "Semicolon", point: { position: 31 } } ], expected: "var obj = { a: { b: 2, c: { d: { e: {} } } } };" }, -{ input: "if (1)\r\n x++;\r\nelse x--;", operations: [ { operation: "Document" } ], expected: "if (1)\r\n x++;\r\nelse x--;" }, -{ input: "do{\r\nfor(var i=0;i<10;i++)i-=2}while(1!==1)", operations: [ { operation: "Enter", point: { position: 5 } } ], expected: "do {\r\n for (var i = 0; i < 10; i++) i -= 2\n} while (1 !== 1)" }, -{ input: "switch (a){\r\n case 1,2,3:\r\n break;\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "switch (a) {\r\n case 1, 2, 3:\r\n break;\r\n}\r\n" }, -{ input: " foo(function (file) {\r\n return 0\r\n })\r\n .then(function (doc) {\r\n return 1\r\n });", operations: [ { operation: "Document" } ], expected: "foo(function (file) {\r\n return 0\r\n})\r\n .then(function (doc) {\r\n return 1\r\n });" }, -{ input: "var a = 1;\nvar f = function () {\n var b = 2;\n}\n", operations: [ { operation: "Enter", point: { position: 50 } } ], expected: "var a = 1;\nvar f = function () {\n var b = 2;\n}\n" }, -{ input: "do{for(var i=0;i<10;i++)i-=2}\r\nwhile(1!==1)", operations: [ { operation: "Enter", point: { position: 31 } } ], expected: "do { for (var i = 0; i < 10; i++) i -= 2 }\r\nwhile (1 !== 1)" }, -{ input: " function a( b,c ) \r\n {\r\n var d=0 ;\r\n }", operations: [ { operation: "Document" } ], expected: "function a(b, c) {\r\n var d = 0;\r\n}" }, -{ input: "function f() {\r\n /*\r\n */ var x\r\n\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 59 } } ], expected: "function f() {\r\n /*\r\n */ var x\r\n\r\n\r\n}" }, -{ input: "if (x!=1^y===2) x+=2\r\n", operations: [ { operation: "Enter", point: { position: 24 } } ], expected: "if (x != 1 ^ y === 2) x += 2\r\n" }, -{ input: "function f() {\n }", operations: [ { operation: "Enter", point: { position: 15 } } ], expected: "function f() {\n}" }, -{ input: "function test() {\r\n try { }\r\n catch (e) { }\r\n finally\r\n}", operations: [ { operation: "Document" } ], expected: "function test() {\r\n try { }\r\n catch (e) { }\r\n finally\r\n }" }, -{ input: "a = [\n // test\n foo(\n // test\n 1),\n 2\n];", operations: [ { operation: "Document" } ], expected: "a = [\n // test\n foo(\n // test\n 1),\n 2\n];" }, -{ input: "if (x!=1^y===2) x+=2;", operations: [ { operation: "Semicolon", point: { position: 23 } } ], expected: "if (x != 1 ^ y === 2) x += 2;" }, -{ input: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n}finally {\r\nx+=2\r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 71 } } ], expected: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n} finally {\r\n x += 2\r\n}\r\n}" }, -{ input: "switch (a) {\n case 1: b++;\n break;\n\n default: a++;\n break;\n}", operations: [ { operation: "Enter", point: { position: 46 } } ], expected: "switch (a) {\n case 1: b++;\n break;\n\n default: a++;\n break;\n}" }, -{ input: "function test() { }\r\n", operations: [ { operation: "Enter", point: { position: 27 } } ], expected: "function test() { }\r\n" }, -{ input: "delete x;", operations: [ { operation: "Document" } ], expected: "delete x;" }, -{ input: "\r\n{\r\n\r\nvar a,\r\n b;\r\n\r\nx = {\r\na: 1 +\r\n 2\r\n}\r\n\r\na(1,\r\n 2).\r\n test();\r\n\r\nfunction foo(a, b,\r\n c) {\r\n}\r\n\r\nfor (i = 0;\r\n i < 1;\r\n i++) {\r\n}\r\n\r\nfor (a\r\n in b) {\r\n}\r\n\r\nwhile (i +\r\n 2) {\r\n}\r\n\r\nswitch (i +\r\n 2) {\r\n\r\n case 1 +\r\n 3:\r\n break;\r\n}\r\n\r\ntry {\r\n}\r\ncatch (\r\n e) {\r\n}\r\n\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\n{\r\n\r\n var a,\r\n b;\r\n\r\n x = {\r\n a: 1 +\r\n 2\r\n }\r\n\r\n a(1,\r\n 2).\r\n test();\r\n\r\n function foo(a, b,\r\n c) {\r\n }\r\n\r\n for (i = 0;\r\n i < 1;\r\n i++) {\r\n }\r\n\r\n for (a\r\n in b) {\r\n }\r\n\r\n while (i +\r\n 2) {\r\n }\r\n\r\n switch (i +\r\n 2) {\r\n\r\n case 1 +\r\n 3:\r\n break;\r\n }\r\n\r\n try {\r\n }\r\n catch (\r\n e) {\r\n }\r\n\r\n}\r\n" }, -{ input: "function f() {\r\n do{\r\nx++ }\r\n}", operations: [ { operation: "CloseBrace", point: { position: 30 } } ], expected: "function f() {\r\n do {\r\n x++\n }\r\n}" }, -{ input: "do\r\n{for(var i=0;i<10;i++)i-=2}while(1!==1)", operations: [ { operation: "Enter", point: { position: 4 } } ], expected: "do\r\n{ for (var i = 0; i < 10; i++) i -= 2 } while (1 !== 1)" }, -{ input: "switch (a){\r\n case 1 :\r\n x+=2\r\n case 2:{\r\n }\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 28 } } ], expected: "switch (a){\r\n case 1:\r\n x += 2\r\n case 2:{\r\n }\r\n}\r\n" }, -{ input: "var x = [\n //comment\n 1,\n 2,\n 3\n]", operations: [ { operation: "Document" } ], expected: "var x = [\n //comment\n 1,\n 2,\n 3\n]" }, -{ input: "switch (a){\r\n case 1: x += 2;\r\n\r\ncase 1 : x+=2;\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 36 } } ], expected: "switch (a){\r\n case 1: x += 2;\r\n\r\n case 1: x += 2;\r\n}\r\n" }, -{ input: " foo(function (file) {\r\n return 0\r\n }).then(function (doc) {\r\n return 1\r\n });", operations: [ { operation: "Document" } ], expected: "foo(function (file) {\r\n return 0\r\n}).then(function (doc) {\r\n return 1\r\n});" }, -{ input: "function f() {\r\nvar s=1 /**/;\r\n}", operations: [ { operation: "Semicolon", point: { position: 30 } } ], expected: "function f() {\r\n var s = 1 /**/;\r\n}" }, -{ input: "switch (a){\r\n case 1: x+=2;\r\n case 2:{\r\n }\r\n \r\n}", operations: [ { operation: "Enter", point: { position: 61 } } ], expected: "switch (a){\r\n case 1: x+=2;\r\n case 2:{\r\n }\r\n\r\n}" }, -{ input: "if(1)\r\nif(1)\r\nx++\r\nelse\r\nif(1)\r\nx+=2\r\nelse\r\nx+=2\r\n\r\n\r\n\r\n;", operations: [ { operation: "Semicolon", point: { position: 57 } } ], expected: "if (1)\r\n if (1)\r\n x++\r\n else\r\n if (1)\r\n x += 2\r\n else\r\n x += 2\r\n\r\n\r\n\r\n;" }, -{ input: "function a() {\r\nvar b = 0;//\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "function a() {\r\n var b = 0;//\r\n\r\n}" }, -{ input: "if (a)\r\ntest;\r\nelse\r\nif (b)\r\ntest;", operations: [ { operation: "Document" } ], expected: "if (a)\r\n test;\r\nelse\r\n if (b)\r\n test;" }, -{ input: "for(var j=0;j<10;j++)j-=i;", operations: [ { operation: "Semicolon", point: { position: 26 } } ], expected: "for (var j = 0; j < 10; j++) j -= i;" }, -{ input: "if(1)\r\nif(1)\r\nx++\r\nelse\r\nif(1)\r\nx+=2\r\nelse\r\nx+=2;", operations: [ { operation: "Semicolon", point: { position: 49 } } ], expected: "if (1)\r\n if (1)\r\n x++\r\n else\r\n if (1)\r\n x += 2\r\n else\r\n x += 2;" }, -{ input: "function test() {\r\n var a\r\n }", operations: [ { operation: "Document" } ], expected: "function test() {\r\n var a\r\n}" }, -{ input: "if (1) {\r\n} else { }", operations: [ { operation: "Document" } ], expected: "if (1) {\r\n} else { }" }, -{ input: "function f() {\r\n /*\r\n\r\n */\r\n}", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "function f() {\r\n /*\r\n\r\n */\r\n}" }, -{ input: "if (x!=1^y===2) \r\n x+=2", operations: [ { operation: "Enter", point: { position: 18 } } ], expected: "if (x != 1 ^ y === 2)\r\n x += 2" }, -{ input: "for (a in b) {\n for (c in d) {\n for (e in f) {\n for (q in w) {}}}}\n", operations: [ { operation: "Enter", point: { position: 88 } } ], expected: "for (a in b) {\n for (c in d) {\n for (e in f) {\n for (q in w) { }\n }\n }\n}\n" }, -{ input: "a=a+\nb+\n c+\n d +\ne +\nm+f;", operations: [ { operation: "Semicolon", point: { position: 100 } } ], expected: "a = a +\nb +\n c +\n d +\ne +\nm + f;" }, -{ input: "x = {\r\n get a() {\r\n\r\n }\r\n}", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "x = {\r\n get a() {\r\n\r\n }\r\n}" }, -{ input: "if(1)\r\n;", operations: [ { operation: "Enter", point: { position: 7 } } ], expected: "if (1)\r\n ;" }, -{ input: "function test() {\r\n return (\r\n [\r\n 1\r\n ]\r\n );\r\n}", operations: [ { operation: "Document" } ], expected: "function test() {\r\n return (\r\n [\r\n 1\r\n ]\r\n );\r\n}" }, -{ input: "string='string+=2\\r\n'", operations: [ { operation: "Enter", point: { position: 20 } } ], expected: "string = 'string+=2\\r\n'" }, -{ input: "if(1)\r\nif(1)\r\nx++\r\nelse\r\n{if(1)\r\nx+=2\r\nelse\r\nx+=2}", operations: [ { operation: "CloseBrace", point: { position: 50 } } ], expected: "if(1)\r\n if (1)\r\n x++\r\n else {\n if (1)\r\n x += 2\r\n else\r\n x += 2\n }" }, -{ input: " function test() { function foo() { function foo3() { function foo4() { function foo5() { function foo6()\r\n{\r\n}\r\n}\r\n}\r\n}\r\n}\r\n}", operations: [ { operation: "Selection", span: { start: 110, length: 19 } } ], expected: " function test() { function foo() { function foo3() { function foo4() { function foo5() { function foo6()\r\n {\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }" }, -{ input: "switch (a){\r\n case 1: x+=2;\r\n case 2 : { x+=2;}\r\n}\r\n", operations: [ { operation: "Semicolon", point: { position: 53 } } ], expected: "switch (a){\r\n case 1: x+=2;\r\n case 2: { x += 2;}\r\n}\r\n" }, -{ input: "// ", operations: [ { operation: "Document" } ], expected: "// " }, -{ input: "for(var i=0;\r\ni<10;i++){for(var j=0;j<10;j++){j-=i}}", operations: [ { operation: "Enter", point: { position: 14 } } ], expected: "for (var i = 0;\r\ni < 10; i++) { for (var j = 0; j < 10; j++) { j -= i } }" }, -{ input: "if (a) if (b) if (c) if (d)\r\ntest;", operations: [ { operation: "Document" } ], expected: "if (a) if (b) if (c) if (d)\r\n test;" }, -{ input: "do{for(var i=0;i<10;i++)i-=2}while(1!==1)", operations: [ { operation: "Semicolon", point: { position: 15 } } ], expected: "do { for (var i = 0;i<10;i++)i-=2}while(1!==1)" }, -{ input: "$ ( '#TextBox1' ) . unbind ( ) ;", operations: [ { operation: "Document" } ], expected: "$('#TextBox1').unbind();" }, -{ input: "do{do{do{}while(a!==b)}while(a!==b)}while(a!==b);", operations: [ { operation: "Semicolon", point: { position: 49 } } ], expected: "do { do { do { } while (a !== b) } while (a !== b) } while (a !== b);" }, -{ input: "do{for(var i=0;i<10;i++)i-=2;}while(1!==1)", operations: [ { operation: "Semicolon", point: { position: 29 } } ], expected: "do { for (var i = 0; i < 10; i++) i -= 2;}while(1!==1)" }, -{ input: "for(var i=0;i<10;i++){\r\nfor(var j=0;j<10;j++){\r\nj-=i\r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 55 } } ], expected: "for(var i=0;i<10;i++){\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\r\n }\r\n}" }, -{ input: "function a() {\r\nfunction b() {\r\nfunction c() {\r\n}}}", operations: [ { operation: "CloseBrace", point: { position: 51 } } ], expected: "function a() {\r\n function b() {\r\n function c() {\r\n }\n }\n}" }, -{ input: " do do do do\r\n test;\r\n while (0)\r\n while (0)\r\n while (0)\r\n while (0)", operations: [ { operation: "Document" } ], expected: "do do do do\r\n test;\r\nwhile (0)\r\nwhile (0)\r\nwhile (0)\r\nwhile (0)" }, -{ input: "/**/ ", operations: [ { operation: "Document" } ], expected: "/**/" }, -{ input: "function a()\n{ var a\n}", operations: [ { operation: "Enter", point: { position: 21 } } ], expected: "function a()\n{\n var a\n}" }, -{ input: "for(var i=0;i<10;i++){for(var j=0;j<10;\r\nj++){j-=i}}", operations: [ { operation: "Enter", point: { position: 41 } } ], expected: "for (var i = 0; i < 10; i++) {\n for (var j = 0; j < 10;\r\n j++) { j -= i }\n}" }, -{ input: "function a() {\r\n if (true) {\r\n }\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 40 } } ], expected: "function a() {\r\n if (true) {\r\n }\r\n\r\n}" }, -{ input: "string='string+=2'\r\n", operations: [ { operation: "Enter", point: { position: 20 } } ], expected: "string = 'string+=2'\r\n" }, -{ input: "for (a in b) {\r\nx++;}\r\n", operations: [ { operation: "Enter", point: { position: 23 } } ], expected: "for (a in b) {\r\n x++;\n}\r\n" }, -{ input: "var obj={a:{b:2,c:{\r\nd:{e:{}}}}}", operations: [ { operation: "Enter", point: { position: 21 } } ], expected: "var obj = {\n a: {\n b: 2, c: {\r\n d: { e: {} }\n }\n }\n}" }, -{ input: "\r\n// test\r\n\r\n{\r\n// test\r\n}\r\n\r\nfunction foo() {\r\n// test\r\n\r\nswitch (a) {\r\n// test\r\ncase 1:\r\n// test\r\ndefault:\r\n// test\r\n}\r\n\r\nif (false)\r\n// test\r\nifblock;\r\n\r\nif (false) {\r\n//test\r\n}\r\n\r\nif (false) test;\r\nelse\r\n// test\r\ntest;\r\n\r\nif (false) test;\r\nelse {\r\n// test\r\ntest;\r\n}\r\n\r\nfor (; ;)\r\n// test\r\ntest;\r\n\r\nfor (; ;) {\r\n// test\r\nforblock;\r\n}\r\n\r\nfor (a in b)\r\n// test\r\ntest;\r\n\r\nfor (a in b) {\r\n// test\r\ntest\r\n}\r\n\r\nwhile (false)\r\n// test\r\ntest;\r\n\r\nwhile (false) {\r\n// test\r\ntest;\r\n}\r\n\r\nwith (a) {\r\n// test\r\n}\r\n\r\ndo\r\n// test\r\ntestl\r\nwhile (false)\r\n\r\ndo {\r\n// test\r\ntest;\r\n} while (false)\r\n\r\ntry {\r\n// test\r\n} catch (e) {\r\n// test\r\n} finally {\r\n// test\r\n}\r\n\r\n(function () {\r\nvar a = function () {\r\nreturn 1;\r\n},\r\n// This is a comment inline with a multiline statement\r\nb = 2,\r\nc = 3;\r\n})();\r\n\r\n\r\nvar a = {\r\n// test\r\nx: 1,\r\ny: 2 +\r\n// test\r\n3 +\r\n4,\r\n}\r\n\r\n\r\nvar a,\r\n// test\r\nb;\r\n\r\nvar a = [\r\n// test\r\n1,\r\n2,\r\n3\r\n];\r\n\r\na = 1 +\r\n// test\r\n2;\r\n\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\n// test\r\n\r\n{\r\n // test\r\n}\r\n\r\nfunction foo() {\r\n // test\r\n\r\n switch (a) {\r\n // test\r\n case 1:\r\n // test\r\n default:\r\n // test\r\n }\r\n\r\n if (false)\r\n // test\r\n ifblock;\r\n\r\n if (false) {\r\n //test\r\n }\r\n\r\n if (false) test;\r\n else\r\n // test\r\n test;\r\n\r\n if (false) test;\r\n else {\r\n // test\r\n test;\r\n }\r\n\r\n for (; ;)\r\n // test\r\n test;\r\n\r\n for (; ;) {\r\n // test\r\n forblock;\r\n }\r\n\r\n for (a in b)\r\n // test\r\n test;\r\n\r\n for (a in b) {\r\n // test\r\n test\r\n }\r\n\r\n while (false)\r\n // test\r\n test;\r\n\r\n while (false) {\r\n // test\r\n test;\r\n }\r\n\r\n with (a) {\r\n // test\r\n }\r\n\r\n do\r\n // test\r\n testl\r\n while (false)\r\n\r\n do {\r\n // test\r\n test;\r\n } while (false)\r\n\r\n try {\r\n // test\r\n } catch (e) {\r\n // test\r\n } finally {\r\n // test\r\n }\r\n\r\n (function () {\r\n var a = function () {\r\n return 1;\r\n },\r\n // This is a comment inline with a multiline statement\r\n b = 2,\r\n c = 3;\r\n })();\r\n\r\n\r\n var a = {\r\n // test\r\n x: 1,\r\n y: 2 +\r\n // test\r\n 3 +\r\n 4,\r\n }\r\n\r\n\r\n var a,\r\n // test\r\n b;\r\n\r\n var a = [\r\n // test\r\n 1,\r\n 2,\r\n 3\r\n ];\r\n\r\n a = 1 +\r\n // test\r\n 2;\r\n\r\n}\r\n" }, -{ input: " \r\n /* \r\n\r\n a \r\n a\r\n a \r\n a \r\na \r\n \r\n\r\n */ \r\n ", operations: [ { operation: "Document" } ], expected: "\r\n/* \r\n\r\n a \r\n a\r\n a \r\na \r\na \r\n\r\n\r\n*/\r\n" }, -{ input: "string='{string +=2}'", operations: [ { operation: "CloseBrace", point: { position: 20 } } ], expected: "string='{string +=2}'" }, -{ input: "var obj={a:{b:2,c:{d:{e:{}}}}}\r\n", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "var obj = { a: { b: 2, c: { d: { e: {} } } } }\r\n" }, -{ input: "string='string\\r\n line2'+'other part'\r\n", operations: [ { operation: "Enter", point: { position: 47 } } ], expected: "string='string\\r\n line2' + 'other part'\r\n" }, -{ input: " switch( a)\r\n{case 1 :x+=2 ;break\r\n case 2:{\r\n }\r\n}", operations: [ { operation: "Enter", point: { position: 13 } } ], expected: "switch (a)\r\n{\n case 1: x += 2; break\r\n case 2:{\r\n }\r\n}" } \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/classes.ts b/src/harness/unittests/services/formatting/testCode/formatting/classes.ts deleted file mode 100644 index e779f69810..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/classes.ts +++ /dev/null @@ -1,79 +0,0 @@ - class a { - constructor ( n : number ) ; - constructor ( s : string ) ; - constructor ( ns : any ) { - - } - - public pgF ( ) { } ; - - public pv ; - public get d ( ) { - return 30 ; - } - public set d ( ) { - } - - public static get p2 ( ) { - return { x : 30 , y : 40 } ; - } - - private static d2 ( ) { - } - private static get p3 ( ) { - return "string" ; - } - private pv3 ; - - private foo ( n : number ) : string ; - private foo ( s : string ) : string ; - private foo ( ns : any ) { - return ns.toString ( ) ; - } -} - - class b extends a { -} - - class m1b { - -} - - interface m1ib { - - } - class c extends m1b { -} - - class ib2 implements m1ib { -} - - declare class aAmbient { - constructor ( n : number ) ; - constructor ( s : string ) ; - public pgF ( ) : void ; - public pv ; - public d : number ; - static p2 : { x : number ; y : number ; } ; - static d2 ( ) ; - static p3 ; - private pv3 ; - private foo ( s ) ; -} - - class d { - private foo ( n : number ) : string ; - private foo ( ns : any ) { - return ns.toString ( ) ; - } - private foo ( s : string ) : string ; -} - - class e { - private foo ( ns : any ) { - return ns.toString ( ) ; - } - private foo ( s : string ) : string ; - private foo ( n : number ) : string ; -} - diff --git a/src/harness/unittests/services/formatting/testCode/formatting/classesBaseline.ts b/src/harness/unittests/services/formatting/testCode/formatting/classesBaseline.ts deleted file mode 100644 index e7e69b4412..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/classesBaseline.ts +++ /dev/null @@ -1,79 +0,0 @@ -class a { - constructor(n: number); - constructor(s: string); - constructor(ns: any) { - - } - - public pgF() { }; - - public pv; - public get d() { - return 30; - } - public set d() { - } - - public static get p2() { - return { x: 30, y: 40 }; - } - - private static d2() { - } - private static get p3() { - return "string"; - } - private pv3; - - private foo(n: number): string; - private foo(s: string): string; - private foo(ns: any) { - return ns.toString(); - } -} - -class b extends a { -} - -class m1b { - -} - -interface m1ib { - -} -class c extends m1b { -} - -class ib2 implements m1ib { -} - -declare class aAmbient { - constructor(n: number); - constructor(s: string); - public pgF(): void; - public pv; - public d: number; - static p2: { x: number; y: number; }; - static d2(); - static p3; - private pv3; - private foo(s); -} - -class d { - private foo(n: number): string; - private foo(ns: any) { - return ns.toString(); - } - private foo(s: string): string; -} - -class e { - private foo(ns: any) { - return ns.toString(); - } - private foo(s: string): string; - private foo(n: number): string; -} - diff --git a/src/harness/unittests/services/formatting/testCode/formatting/colonAndQMark.ts b/src/harness/unittests/services/formatting/testCode/formatting/colonAndQMark.ts deleted file mode 100644 index 5562e14204..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/colonAndQMark.ts +++ /dev/null @@ -1,4 +0,0 @@ -class foo { - constructor (n?: number, m? = 5, o?: string = "") { } - x:number = 1?2:3; -} diff --git a/src/harness/unittests/services/formatting/testCode/formatting/colonAndQMarkBaseline.ts b/src/harness/unittests/services/formatting/testCode/formatting/colonAndQMarkBaseline.ts deleted file mode 100644 index 52bbe56251..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/colonAndQMarkBaseline.ts +++ /dev/null @@ -1,4 +0,0 @@ -class foo { - constructor(n?: number, m? = 5, o?: string = "") { } - x: number = 1 ? 2 : 3; -} diff --git a/src/harness/unittests/services/formatting/testCode/formatting/documentReadyFunction.ts b/src/harness/unittests/services/formatting/testCode/formatting/documentReadyFunction.ts deleted file mode 100644 index 35daa4d895..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/documentReadyFunction.ts +++ /dev/null @@ -1,3 +0,0 @@ -$ ( document ) . ready ( function ( ) { - alert ( 'i am ready' ) ; - } ); \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/documentReadyFunctionBaseLine.ts b/src/harness/unittests/services/formatting/testCode/formatting/documentReadyFunctionBaseLine.ts deleted file mode 100644 index 838ef68220..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/documentReadyFunctionBaseLine.ts +++ /dev/null @@ -1,3 +0,0 @@ -$(document).ready(function() { - alert('i am ready'); -}); \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/emptyBlock.ts b/src/harness/unittests/services/formatting/testCode/formatting/emptyBlock.ts deleted file mode 100644 index 9e26dfeeb6..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/emptyBlock.ts +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/emptyBlockBaseline.ts b/src/harness/unittests/services/formatting/testCode/formatting/emptyBlockBaseline.ts deleted file mode 100644 index 6f31cf5a2e..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/emptyBlockBaseline.ts +++ /dev/null @@ -1 +0,0 @@ -{ } \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/emptyInterfaceLiteral.ts b/src/harness/unittests/services/formatting/testCode/formatting/emptyInterfaceLiteral.ts deleted file mode 100644 index 1feec453d0..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/emptyInterfaceLiteral.ts +++ /dev/null @@ -1,10 +0,0 @@ - function foo ( x : { } ) { } - -foo ( { } ) ; - - - - interface bar { - x : { } ; - y : ( ) => { } ; - } \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/emptyInterfaceLiteralBaseLine.ts b/src/harness/unittests/services/formatting/testCode/formatting/emptyInterfaceLiteralBaseLine.ts deleted file mode 100644 index 04f3c0bc9b..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/emptyInterfaceLiteralBaseLine.ts +++ /dev/null @@ -1,10 +0,0 @@ -function foo(x: {}) { } - -foo({}); - - - -interface bar { - x: {}; - y: () => {}; -} \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/fatArrowFunctions.ts b/src/harness/unittests/services/formatting/testCode/formatting/fatArrowFunctions.ts deleted file mode 100644 index ebbf54557f..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/fatArrowFunctions.ts +++ /dev/null @@ -1,112 +0,0 @@ -// valid - ( ) => 1 ; - ( arg ) => 2 ; - arg => 2 ; - ( arg = 1 ) => 3 ; - ( arg ? ) => 4 ; - ( arg : number ) => 5 ; - ( arg : number = 0 ) => 6 ; - ( arg ? : number ) => 7 ; - ( ... arg : number [ ] ) => 8 ; - ( arg1 , arg2 ) => 12 ; - ( arg1 = 1 , arg2 =3 ) => 13 ; - ( arg1 ? , arg2 ? ) => 14 ; - ( arg1 : number , arg2 : number ) => 15 ; - ( arg1 : number = 0 , arg2 : number = 1 ) => 16 ; - ( arg1 ? : number , arg2 ? : number ) => 17 ; - ( arg1 , ... arg2 : number [ ] ) => 18 ; - ( arg1 , arg2 ? : number ) => 19 ; - -// in paren - ( ( ) => 21 ) ; - ( ( arg ) => 22 ) ; - ( ( arg = 1 ) => 23 ) ; - ( ( arg ? ) => 24 ) ; - ( ( arg : number ) => 25 ) ; - ( ( arg : number = 0 ) => 26 ) ; - ( ( arg ? : number ) => 27 ) ; - ( ( ... arg : number [ ] ) => 28 ) ; - -// in multiple paren - ( ( ( ( ( arg ) => { return 32 ; } ) ) ) ) ; - -// in ternary exression - false ? ( ) => 41 : null ; - false ? ( arg ) => 42 : null ; - false ? ( arg = 1 ) => 43 : null ; - false ? ( arg ? ) => 44 : null ; - false ? ( arg : number ) => 45 : null ; - false ? ( arg ? : number ) => 46 : null ; - false ? ( arg ? : number = 0 ) => 47 : null ; - false ? ( ... arg : number [ ] ) => 48 : null ; - -// in ternary exression within paren - false ? ( ( ) => 51 ) : null ; - false ? ( ( arg ) => 52 ) : null ; - false ? ( ( arg = 1 ) => 53 ) : null ; - false ? ( ( arg ? ) => 54 ) : null ; - false ? ( ( arg : number ) => 55 ) : null ; - false ? ( ( arg ? : number ) => 56 ) : null ; - false ? ( ( arg ? : number = 0 ) => 57 ) : null ; - false ? ( ( ... arg : number [ ] ) => 58 ) : null ; - -// ternary exression's else clause - false ? null : ( ) => 61 ; - false ? null : ( arg ) => 62 ; - false ? null : ( arg = 1 ) => 63 ; - false ? null : ( arg ? ) => 64 ; - false ? null : ( arg : number ) => 65 ; - false ? null : ( arg ? : number ) => 66 ; - false ? null : ( arg ? : number = 0 ) => 67 ; - false ? null : ( ... arg : number [ ] ) => 68 ; - - -// nested ternary expressions - ( a ? ) => { return a ; } ? ( b ? ) => { return b ; } : ( c ? ) => { return c ; } ; - -//multiple levels - ( a ? ) => { return a ; } ? ( b ) => ( c ) => 81 : ( c ) => ( d ) => 82 ; - - -// In Expressions - ( ( arg ) => 90 ) instanceof Function ; - ( ( arg = 1 ) => 91 ) instanceof Function ; - ( ( arg ? ) => 92 ) instanceof Function ; - ( ( arg : number ) => 93 ) instanceof Function ; - ( ( arg : number = 1 ) => 94 ) instanceof Function ; - ( ( arg ? : number ) => 95 ) instanceof Function ; - ( ( ... arg : number [ ] ) => 96 ) instanceof Function ; - -'' + ( arg ) => 100 ; - ( ( arg ) => 0 ) + '' + ( arg ) => 101 ; - ( ( arg = 1 ) => 0 ) + '' + ( arg = 2 ) => 102 ; - ( ( arg ? ) => 0 ) + '' + ( arg ? ) => 103 ; - ( ( arg : number ) => 0 ) + '' + ( arg : number ) => 104 ; - ( ( arg : number = 1 ) => 0 ) + '' + ( arg : number = 2 ) => 105 ; - ( ( arg ? : number = 1 ) => 0 ) + '' + ( arg ? : number = 2 ) => 106 ; - ( ( ... arg : number [ ] ) => 0 ) + '' + ( ... arg : number [ ] ) => 107 ; - ( ( arg1 , arg2 ? ) => 0 ) + '' + ( arg1 , arg2 ? ) => 108 ; - ( ( arg1 , ... arg2 : number [ ] ) => 0 ) + '' + ( arg1 , ... arg2 : number [ ] ) => 108 ; - - -// Function Parameters -function foo ( ... arg : any [ ] ) { } - -foo ( - ( a ) => 110 , - ( ( a ) => 111 ) , - ( a ) => { - return 112 ; - } , - ( a ? ) => 113 , - ( a , b ? ) => 114 , - ( a : number ) => 115 , - ( a : number = 0 ) => 116 , - ( a = 0 ) => 117 , - ( a ? : number = 0 ) => 118 , - ( a ? , b ? : number = 0 ) => 118 , - ( ... a : number [ ] ) => 119 , - ( a , b ? = 0 , ... c : number [ ] ) => 120 , - ( a ) => ( b ) => ( c ) => 121 , - false ? ( a ) => 0 : ( b ) => 122 - ) ; \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/fatArrowFunctionsBaseline.ts b/src/harness/unittests/services/formatting/testCode/formatting/fatArrowFunctionsBaseline.ts deleted file mode 100644 index 7a1ef86f5a..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/fatArrowFunctionsBaseline.ts +++ /dev/null @@ -1,112 +0,0 @@ -// valid -() => 1; -(arg) => 2; -arg => 2; -(arg = 1) => 3; -(arg?) => 4; -(arg: number) => 5; -(arg: number = 0) => 6; -(arg?: number) => 7; -(...arg: number[]) => 8; -(arg1, arg2) => 12; -(arg1 = 1, arg2 = 3) => 13; -(arg1?, arg2?) => 14; -(arg1: number, arg2: number) => 15; -(arg1: number = 0, arg2: number = 1) => 16; -(arg1?: number, arg2?: number) => 17; -(arg1, ...arg2: number[]) => 18; -(arg1, arg2?: number) => 19; - -// in paren -(() => 21); -((arg) => 22); -((arg = 1) => 23); -((arg?) => 24); -((arg: number) => 25); -((arg: number = 0) => 26); -((arg?: number) => 27); -((...arg: number[]) => 28); - -// in multiple paren -(((((arg) => { return 32; })))); - -// in ternary exression -false ? () => 41 : null; -false ? (arg) => 42 : null; -false ? (arg = 1) => 43 : null; -false ? (arg?) => 44 : null; -false ? (arg: number) => 45 : null; -false ? (arg?: number) => 46 : null; -false ? (arg?: number = 0) => 47 : null; -false ? (...arg: number[]) => 48 : null; - -// in ternary exression within paren -false ? (() => 51) : null; -false ? ((arg) => 52) : null; -false ? ((arg = 1) => 53) : null; -false ? ((arg?) => 54) : null; -false ? ((arg: number) => 55) : null; -false ? ((arg?: number) => 56) : null; -false ? ((arg?: number = 0) => 57) : null; -false ? ((...arg: number[]) => 58) : null; - -// ternary exression's else clause -false ? null : () => 61; -false ? null : (arg) => 62; -false ? null : (arg = 1) => 63; -false ? null : (arg?) => 64; -false ? null : (arg: number) => 65; -false ? null : (arg?: number) => 66; -false ? null : (arg?: number = 0) => 67; -false ? null : (...arg: number[]) => 68; - - -// nested ternary expressions -(a?) => { return a; } ? (b?) => { return b; } : (c?) => { return c; }; - -//multiple levels -(a?) => { return a; } ? (b) => (c) => 81 : (c) => (d) => 82; - - -// In Expressions -((arg) => 90) instanceof Function; -((arg = 1) => 91) instanceof Function; -((arg?) => 92) instanceof Function; -((arg: number) => 93) instanceof Function; -((arg: number = 1) => 94) instanceof Function; -((arg?: number) => 95) instanceof Function; -((...arg: number[]) => 96) instanceof Function; - -'' + (arg) => 100; -((arg) => 0) + '' + (arg) => 101; -((arg = 1) => 0) + '' + (arg = 2) => 102; -((arg?) => 0) + '' + (arg?) => 103; -((arg: number) => 0) + '' + (arg: number) => 104; -((arg: number = 1) => 0) + '' + (arg: number = 2) => 105; -((arg?: number = 1) => 0) + '' + (arg?: number = 2) => 106; -((...arg: number[]) => 0) + '' + (...arg: number[]) => 107; -((arg1, arg2?) => 0) + '' + (arg1, arg2?) => 108; -((arg1, ...arg2: number[]) => 0) + '' + (arg1, ...arg2: number[]) => 108; - - -// Function Parameters -function foo(...arg: any[]) { } - -foo( - (a) => 110, - ((a) => 111), - (a) => { - return 112; - }, - (a?) => 113, - (a, b?) => 114, - (a: number) => 115, - (a: number = 0) => 116, - (a = 0) => 117, - (a?: number = 0) => 118, - (a?, b?: number = 0) => 118, - (...a: number[]) => 119, - (a, b? = 0, ...c: number[]) => 120, - (a) => (b) => (c) => 121, - false ? (a) => 0 : (b) => 122 - ); \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/formatDebuggerStatement.ts b/src/harness/unittests/services/formatting/testCode/formatting/formatDebuggerStatement.ts deleted file mode 100644 index 314cd416a8..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/formatDebuggerStatement.ts +++ /dev/null @@ -1,2 +0,0 @@ -if(false){debugger;} - if ( false ) { debugger ; } \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/formatDebuggerStatementBaseline.ts b/src/harness/unittests/services/formatting/testCode/formatting/formatDebuggerStatementBaseline.ts deleted file mode 100644 index c03acf91ec..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/formatDebuggerStatementBaseline.ts +++ /dev/null @@ -1,2 +0,0 @@ -if (false) { debugger; } -if (false) { debugger; } \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/formatvariableDeclarationList.ts b/src/harness/unittests/services/formatting/testCode/formatting/formatvariableDeclarationList.ts deleted file mode 100644 index 956309d2c4..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/formatvariableDeclarationList.ts +++ /dev/null @@ -1,13 +0,0 @@ -var fun1 = function ( ) { - var x = 'foo' , - z = 'bar' ; - return x ; -}, - -fun2 = ( function ( f ) { - var fun = function ( ) { - console . log ( f ( ) ) ; - }, - x = 'Foo' ; - return fun ; -} ( fun1 ) ) ; diff --git a/src/harness/unittests/services/formatting/testCode/formatting/formatvariableDeclarationListBaseline.ts b/src/harness/unittests/services/formatting/testCode/formatting/formatvariableDeclarationListBaseline.ts deleted file mode 100644 index f1d32283fd..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/formatvariableDeclarationListBaseline.ts +++ /dev/null @@ -1,13 +0,0 @@ -var fun1 = function() { - var x = 'foo', - z = 'bar'; - return x; -}, - -fun2 = (function(f) { - var fun = function() { - console.log(f()); - }, - x = 'Foo'; - return fun; -} (fun1)); diff --git a/src/harness/unittests/services/formatting/testCode/formatting/implicitModule.ts b/src/harness/unittests/services/formatting/testCode/formatting/implicitModule.ts deleted file mode 100644 index 352a252593..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/implicitModule.ts +++ /dev/null @@ -1,3 +0,0 @@ - export class A { - - } diff --git a/src/harness/unittests/services/formatting/testCode/formatting/implicitModuleBaseline.ts b/src/harness/unittests/services/formatting/testCode/formatting/implicitModuleBaseline.ts deleted file mode 100644 index df93540466..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/implicitModuleBaseline.ts +++ /dev/null @@ -1,3 +0,0 @@ -export class A { - -} diff --git a/src/harness/unittests/services/formatting/testCode/formatting/importDeclaration.ts b/src/harness/unittests/services/formatting/testCode/formatting/importDeclaration.ts deleted file mode 100644 index afd010fe8b..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/importDeclaration.ts +++ /dev/null @@ -1,6 +0,0 @@ -module Foo { -} - -import bar = Foo; - -import bar2=Foo; diff --git a/src/harness/unittests/services/formatting/testCode/formatting/importDeclarationBaseline.ts b/src/harness/unittests/services/formatting/testCode/formatting/importDeclarationBaseline.ts deleted file mode 100644 index d0a4e190d9..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/importDeclarationBaseline.ts +++ /dev/null @@ -1,6 +0,0 @@ -module Foo { -} - -import bar = Foo; - -import bar2 = Foo; diff --git a/src/harness/unittests/services/formatting/testCode/formatting/main.ts b/src/harness/unittests/services/formatting/testCode/formatting/main.ts deleted file mode 100644 index 7640013af8..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/main.ts +++ /dev/null @@ -1,95 +0,0 @@ - -var a;var c , b;var $d -var $e -var f -a++;b++; - -function f ( ) { - for (i = 0; i < 10; i++) { - k = abc + 123 ^ d; - a = XYZ[m (a[b[c][d]])]; - break; - - switch ( variable){ - case 1: abc += 425; -break; -case 404 : a [x--/2]%=3 ; - break ; - case vari : v[--x ] *=++y*( m + n / k[z]); - for (a in b){ - for (a = 0; a < 10; ++a) { - a++;--a; - if (a == b) { - a++;b--; - } -else -if (a == c){ -++a; -(--c)+=d; -$c = $a + --$b; -} -if (a == b) -if (a != b) { - if (a !== b) - if (a === b) - --a; - else - --a; - else { - a--;++b; -a++ - } - } - } - for (x in y) { -m-=m; -k=1+2+3+4; -} -} - break; - - } - } - var a ={b:function(){}}; - return {a:1,b:2} -} - -var z = 1; - for (i = 0; i < 10; i++) - for (j = 0; j < 10; j++) -for (k = 0; k < 10; ++k) { -z++; -} - -for (k = 0; k < 10; k += 2) { -z++; -} - - $(document).ready (); - - - function pageLoad() { - $('#TextBox1' ) . unbind ( ) ; -$('#TextBox1' ) . datepicker ( ) ; -} - - function pageLoad ( ) { - var webclass=[ - { 'student' : - { 'id': '1', 'name': 'Linda Jones', 'legacySkill': 'Access, VB 5.0' } - } , -{ 'student': -{'id':'2','name':'Adam Davidson','legacySkill':'Cobol,MainFrame'} -} , - { 'student': -{ 'id':'3','name':'Charles Boyer' ,'legacySkill':'HTML, XML'} -} - ]; - -$create(Sys.UI.DataView,{data:webclass},null,null,$get('SList')); - -} - -$( document ).ready(function(){ -alert('hello'); - } ) ; diff --git a/src/harness/unittests/services/formatting/testCode/formatting/mainBaseline.ts b/src/harness/unittests/services/formatting/testCode/formatting/mainBaseline.ts deleted file mode 100644 index 30756f547c..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/mainBaseline.ts +++ /dev/null @@ -1,98 +0,0 @@ - -var a; var c, b; var $d -var $e -var f -a++; b++; - -function f() { - for (i = 0; i < 10; i++) { - k = abc + 123 ^ d; - a = XYZ[m(a[b[c][d]])]; - break; - - switch (variable) { - case 1: abc += 425; - break; - case 404: a[x-- / 2] %= 3; - break; - case vari: v[--x] *= ++y * (m + n / k[z]); - for (a in b) { - for (a = 0; a < 10; ++a) { - a++; --a; - if (a == b) { - a++; b--; - } - else - if (a == c) { - ++a; - (--c) += d; - $c = $a + --$b; - } - if (a == b) - if (a != b) { - if (a !== b) - if (a === b) - --a; - else - --a; - else { - a--; ++b; - a++ - } - } - } - for (x in y) { - m -= m; - k = 1 + 2 + 3 + 4; - } - } - break; - - } - } - var a = { b: function() { } }; - return { a: 1, b: 2 } -} - -var z = 1; -for (i = 0; i < 10; i++) - for (j = 0; j < 10; j++) - for (k = 0; k < 10; ++k) { - z++; - } - -for (k = 0; k < 10; k += 2) { - z++; -} - -$(document).ready(); - - -function pageLoad() { - $('#TextBox1').unbind(); - $('#TextBox1').datepicker(); -} - -function pageLoad() { - var webclass = [ - { - 'student': - { 'id': '1', 'name': 'Linda Jones', 'legacySkill': 'Access, VB 5.0' } - }, -{ - 'student': - { 'id': '2', 'name': 'Adam Davidson', 'legacySkill': 'Cobol,MainFrame' } -}, - { - 'student': - { 'id': '3', 'name': 'Charles Boyer', 'legacySkill': 'HTML, XML' } - } - ]; - - $create(Sys.UI.DataView, { data: webclass }, null, null, $get('SList')); - -} - -$(document).ready(function() { - alert('hello'); -}); diff --git a/src/harness/unittests/services/formatting/testCode/formatting/moduleIndentation.ts b/src/harness/unittests/services/formatting/testCode/formatting/moduleIndentation.ts deleted file mode 100644 index 3030a36630..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/moduleIndentation.ts +++ /dev/null @@ -1,3 +0,0 @@ - module Foo { - export module A . B . C { } - } \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/moduleIndentationBaseline.ts b/src/harness/unittests/services/formatting/testCode/formatting/moduleIndentationBaseline.ts deleted file mode 100644 index 0013b367dc..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/moduleIndentationBaseline.ts +++ /dev/null @@ -1,3 +0,0 @@ -module Foo { - export module A.B.C { } -} \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/modules.ts b/src/harness/unittests/services/formatting/testCode/formatting/modules.ts deleted file mode 100644 index 5ce0d19b63..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/modules.ts +++ /dev/null @@ -1,76 +0,0 @@ - module mod1 { - export class b { - } - class d { - } - - - export interface ib { - } -} - - module m2 { - - export module m3 { - export class c extends mod1.b { - } - export class ib2 implements mod1.ib { - } - } -} - - class c extends mod1.b { -} - - class ib2 implements mod1.ib { -} - - declare export module "m4" { - export class d { - } ; - var x : d ; - export function foo ( ) : d ; -} - - import m4 = module ( "m4" ) ; - export var x4 = m4.x ; - export var d4 = m4.d ; - export var f4 = m4.foo ( ) ; - - export module m1 { - declare export module "m2" { - export class d { - } ; - var x: d ; - export function foo ( ) : d ; - } - import m2 = module ( "m2" ) ; - import m3 = module ( "m4" ) ; - - export var x2 = m2.x ; - export var d2 = m2.d ; - export var f2 = m2.foo ( ) ; - - export var x3 = m3.x ; - export var d3 = m3.d ; - export var f3 = m3.foo ( ) ; -} - - export var x2 = m1.m2.x ; - export var d2 = m1.m2.d ; - export var f2 = m1.m2.foo ( ) ; - - export var x3 = m1.m3.x ; - export var d3 = m1.m3.d ; - export var f3 = m1.m3.foo ( ) ; - - export module m5 { - export var x2 = m1.m2.x ; - export var d2 = m1.m2.d ; - export var f2 = m1.m2.foo ( ) ; - - export var x3 = m1.m3.x ; - export var d3 = m1.m3.d ; - export var f3 = m1.m3.foo ( ) ; -} - diff --git a/src/harness/unittests/services/formatting/testCode/formatting/modulesBaseline.ts b/src/harness/unittests/services/formatting/testCode/formatting/modulesBaseline.ts deleted file mode 100644 index e6f62024fe..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/modulesBaseline.ts +++ /dev/null @@ -1,76 +0,0 @@ -module mod1 { - export class b { - } - class d { - } - - - export interface ib { - } -} - -module m2 { - - export module m3 { - export class c extends mod1.b { - } - export class ib2 implements mod1.ib { - } - } -} - -class c extends mod1.b { -} - -class ib2 implements mod1.ib { -} - -declare export module "m4" { - export class d { - }; - var x: d; - export function foo(): d; -} - -import m4 = module("m4"); -export var x4 = m4.x; -export var d4 = m4.d; -export var f4 = m4.foo(); - -export module m1 { - declare export module "m2" { - export class d { - }; - var x: d; - export function foo(): d; - } - import m2 = module("m2"); - import m3 = module("m4"); - - export var x2 = m2.x; - export var d2 = m2.d; - export var f2 = m2.foo(); - - export var x3 = m3.x; - export var d3 = m3.d; - export var f3 = m3.foo(); -} - -export var x2 = m1.m2.x; -export var d2 = m1.m2.d; -export var f2 = m1.m2.foo(); - -export var x3 = m1.m3.x; -export var d3 = m1.m3.d; -export var f3 = m1.m3.foo(); - -export module m5 { - export var x2 = m1.m2.x; - export var d2 = m1.m2.d; - export var f2 = m1.m2.foo(); - - export var x3 = m1.m3.x; - export var d3 = m1.m3.d; - export var f3 = m1.m3.foo(); -} - diff --git a/src/harness/unittests/services/formatting/testCode/formatting/objectLiteral.ts b/src/harness/unittests/services/formatting/testCode/formatting/objectLiteral.ts deleted file mode 100644 index dbecc4d4fe..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/objectLiteral.ts +++ /dev/null @@ -1,27 +0,0 @@ -var x = {foo: 1, -bar: "tt", -boo: 1 + 5}; - -var x2 = {foo: 1, -bar: "tt",boo:1+5}; - -function Foo() { -var typeICalc = { -clear: { -"()": [1, 2, 3] -} -} -} - -// Rule for object literal members for the "value" of the memebr to follow the indent -// of the member, i.e. the relative position of the value is maintained when the member -// is indented. -var x2 = { - foo: -3, - 'bar': - { a: 1, b : 2} -}; - -var x={ }; -var y = {}; \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/objectLiteralBaseline.ts b/src/harness/unittests/services/formatting/testCode/formatting/objectLiteralBaseline.ts deleted file mode 100644 index 3a7fa63d92..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/objectLiteralBaseline.ts +++ /dev/null @@ -1,31 +0,0 @@ -var x = { - foo: 1, - bar: "tt", - boo: 1 + 5 -}; - -var x2 = { - foo: 1, - bar: "tt", boo: 1 + 5 -}; - -function Foo() { - var typeICalc = { - clear: { - "()": [1, 2, 3] - } - } -} - -// Rule for object literal members for the "value" of the memebr to follow the indent -// of the member, i.e. the relative position of the value is maintained when the member -// is indented. -var x2 = { - foo: - 3, - 'bar': - { a: 1, b: 2 } -}; - -var x = {}; -var y = {}; \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/onClosingBracket.ts b/src/harness/unittests/services/formatting/testCode/formatting/onClosingBracket.ts deleted file mode 100644 index 0161f04308..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/onClosingBracket.ts +++ /dev/null @@ -1,32 +0,0 @@ -function f( ) { -var x = 3; - var z = 2 ; - a = z ++ - 2 * x ; - for ( ; ; ) { - a+=(g +g)*a%t; - b -- ; -} - - switch ( a ) - { - case 1 : { - a ++ ; - b--; - if(a===a) - return; - else - { - for(a in b) - if(a!=a) - { - for(a in b) - { -a++; - } - } - } - } - default: - break; - } -} diff --git a/src/harness/unittests/services/formatting/testCode/formatting/onClosingBracketBaseLine.ts b/src/harness/unittests/services/formatting/testCode/formatting/onClosingBracketBaseLine.ts deleted file mode 100644 index 051a4ebd13..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/onClosingBracketBaseLine.ts +++ /dev/null @@ -1,28 +0,0 @@ -function f() { - var x = 3; - var z = 2; - a = z++ - 2 * x; - for (; ;) { - a += (g + g) * a % t; - b--; - } - - switch (a) { - case 1: { - a++; - b--; - if (a === a) - return; - else { - for (a in b) - if (a != a) { - for (a in b) { - a++; - } - } - } - } - default: - break; - } -} diff --git a/src/harness/unittests/services/formatting/testCode/formatting/onSemiColon.ts b/src/harness/unittests/services/formatting/testCode/formatting/onSemiColon.ts deleted file mode 100644 index 3b5b5456a6..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/onSemiColon.ts +++ /dev/null @@ -1 +0,0 @@ -var a=b+c^d-e*++f; \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/onSemiColonBaseline.ts b/src/harness/unittests/services/formatting/testCode/formatting/onSemiColonBaseline.ts deleted file mode 100644 index 2ba96e4f88..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/onSemiColonBaseline.ts +++ /dev/null @@ -1 +0,0 @@ -var a = b + c ^ d - e * ++f; \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/spaceAfterConstructor.ts b/src/harness/unittests/services/formatting/testCode/formatting/spaceAfterConstructor.ts deleted file mode 100644 index 7d98d5a8f4..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/spaceAfterConstructor.ts +++ /dev/null @@ -1 +0,0 @@ -class test { constructor () { } } \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/spaceAfterConstructorBaseline.ts b/src/harness/unittests/services/formatting/testCode/formatting/spaceAfterConstructorBaseline.ts deleted file mode 100644 index bc124d41ba..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/spaceAfterConstructorBaseline.ts +++ /dev/null @@ -1 +0,0 @@ -class test { constructor() { } } \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/tabAfterCloseCurly.ts b/src/harness/unittests/services/formatting/testCode/formatting/tabAfterCloseCurly.ts deleted file mode 100644 index ec093e0e37..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/tabAfterCloseCurly.ts +++ /dev/null @@ -1,10 +0,0 @@ -module Tools { - export enum NodeType { - Error, - Comment, - } - export enum foob - { - Blah=1, Bleah=2 - } -} \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/tabAfterCloseCurlyBaseline.ts b/src/harness/unittests/services/formatting/testCode/formatting/tabAfterCloseCurlyBaseline.ts deleted file mode 100644 index d0a3db2d51..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/tabAfterCloseCurlyBaseline.ts +++ /dev/null @@ -1,9 +0,0 @@ -module Tools { - export enum NodeType { - Error, - Comment, - } - export enum foob { - Blah = 1, Bleah = 2 - } -} \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/typescriptConstructs.ts b/src/harness/unittests/services/formatting/testCode/formatting/typescriptConstructs.ts deleted file mode 100644 index 43ef3710ef..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/typescriptConstructs.ts +++ /dev/null @@ -1,65 +0,0 @@ - module MyModule - { - module A.B.C { -module F { -} - } -interface Blah -{ -boo: string; -} - - class Foo - { - -} - -class Foo2 { -public foo():number { -return 5 * 6; -} -public foo2() { -if (1 === 2) - - -{ -var y : number= 76; -return y; -} - - while (2 == 3) { - if ( y == null ) { - -} - } -} - -public foo3() { -if (1 === 2) - -//comment preventing line merging -{ -var y = 76; -return y; -} - -} - } - } - -function foo(a:number, b:number):number -{ -return 0; -} - -function bar(a:number, b:number) :number[] { -return []; -} - -module BugFix3 { -declare var f: { - (): any; - (x: number): string; - foo: number; -}; -} diff --git a/src/harness/unittests/services/formatting/testCode/formatting/typescriptConstructsBaseline.ts b/src/harness/unittests/services/formatting/testCode/formatting/typescriptConstructsBaseline.ts deleted file mode 100644 index 929334e473..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/typescriptConstructsBaseline.ts +++ /dev/null @@ -1,58 +0,0 @@ -module MyModule { - module A.B.C { - module F { - } - } - interface Blah { - boo: string; - } - - class Foo { - - } - - class Foo2 { - public foo(): number { - return 5 * 6; - } - public foo2() { - if (1 === 2) { - var y: number = 76; - return y; - } - - while (2 == 3) { - if (y == null) { - - } - } - } - - public foo3() { - if (1 === 2) - - //comment preventing line merging - { - var y = 76; - return y; - } - - } - } -} - -function foo(a: number, b: number): number { - return 0; -} - -function bar(a: number, b: number): number[] { - return []; -} - -module BugFix3 { - declare var f: { - (): any; - (x: number): string; - foo: number; - }; -} diff --git a/src/harness/unittests/services/formatting/testCode/formatting/various.ts b/src/harness/unittests/services/formatting/testCode/formatting/various.ts deleted file mode 100644 index bd814c2348..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/various.ts +++ /dev/null @@ -1,17 +0,0 @@ -function f(a,b,c,d){ -for(var i=0;i<10;i++){ -var a=0; -var b=a+a+a*a%a/2-1; -b+=a; -++b; -f(a,b,c,d); -if(1===1){ -var m=function(e,f){ -return e^f; -} -} -} -} - -for (var i = 0 ; i < this.foo(); i++) { -} \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/variousBaseline.ts b/src/harness/unittests/services/formatting/testCode/formatting/variousBaseline.ts deleted file mode 100644 index a4b5ceeb1c..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/variousBaseline.ts +++ /dev/null @@ -1,17 +0,0 @@ -function f(a, b, c, d) { - for (var i = 0; i < 10; i++) { - var a = 0; - var b = a + a + a * a % a / 2 - 1; - b += a; - ++b; - f(a, b, c, d); - if (1 === 1) { - var m = function(e, f) { - return e ^ f; - } - } - } -} - -for (var i = 0 ; i < this.foo(); i++) { -} \ No newline at end of file diff --git a/src/harness/unittests/services/formatting/testCode/formatting/withStatement.ts b/src/harness/unittests/services/formatting/testCode/formatting/withStatement.ts deleted file mode 100644 index 66ec4bf546..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/withStatement.ts +++ /dev/null @@ -1,9 +0,0 @@ -with (foo.bar) - - { - - } - -with (bar.blah) -{ -} diff --git a/src/harness/unittests/services/formatting/testCode/formatting/withStatementBaseline.ts b/src/harness/unittests/services/formatting/testCode/formatting/withStatementBaseline.ts deleted file mode 100644 index f81378d7f8..0000000000 --- a/src/harness/unittests/services/formatting/testCode/formatting/withStatementBaseline.ts +++ /dev/null @@ -1,6 +0,0 @@ -with (foo.bar) { - -} - -with (bar.blah) { -} diff --git a/tests/cases/fourslash_old/callOrderDependence.ts b/tests/cases/fourslash_old/callOrderDependence.ts deleted file mode 100644 index 3e7100068f..0000000000 --- a/tests/cases/fourslash_old/callOrderDependence.ts +++ /dev/null @@ -1,9 +0,0 @@ -/// - -/////**/ - -diagnostics.setEditValidation(IncrementalEditValidation.None); -edit.replace(0, 0, "function foo(bar) {\n b\n}\n"); -goTo.position(27); -FourSlash.currentTestState.getCompletionListAtCaret().entries - .forEach(entry => FourSlash.currentTestState.getCompletionEntryDetails(entry.name)); diff --git a/tests/cases/fourslash_old/chainedFunctionCallsErrorSpan.ts b/tests/cases/fourslash_old/chainedFunctionCallsErrorSpan.ts deleted file mode 100644 index e4a56c546b..0000000000 --- a/tests/cases/fourslash_old/chainedFunctionCallsErrorSpan.ts +++ /dev/null @@ -1,5 +0,0 @@ -/// - -////'foo'.replace('o', '3')./*1*/replace/*2*/('f', 5); - -verify.errorExistsBetweenMarkers('1', '2'); diff --git a/tests/cases/fourslash_old/completionListGenericConstraintsNames.ts b/tests/cases/fourslash_old/completionListGenericConstraintsNames.ts deleted file mode 100644 index 92d288dcb2..0000000000 --- a/tests/cases/fourslash_old/completionListGenericConstraintsNames.ts +++ /dev/null @@ -1,24 +0,0 @@ -/// - -////interface IBar { -////} -//// -////class BarWrapper { -//// private value: /*1*/; -//// public getValue(v: /*2*/T): /*3*/ { -//// } -////} -////function foo(p1: T, p2: /*21*/U) : /*22*/ { -//// var x : /*23*/ -////} -////class MethodTest { -//// public method(p1: T, p2: U, p3:/*31*/ M): Array { -//// return null; -//// } -////} - -goTo.eachMarker(() => { - verify.memberListContains("T"); - verify.memberListContains("U"); - verify.memberListContains("M"); - }); diff --git a/tests/cases/fourslash_old/completionListInTypedObjectLiterals.ts b/tests/cases/fourslash_old/completionListInTypedObjectLiterals.ts deleted file mode 100644 index ce9c34df64..0000000000 --- a/tests/cases/fourslash_old/completionListInTypedObjectLiterals.ts +++ /dev/null @@ -1,142 +0,0 @@ -/// - -////interface MyPoint { -//// x1: number; -//// y1: number; -////} -////var p1: MyPoint = { -//// /*1*/ -////}; -////var p2: MyPoint = { -//// /*2*/x1: 5, -//// /*3*/ -////}; -////var p3: MyPoint = { -//// x1: /*4*/ -////}; -////var p4: any = { -//// /*5*/ -////} -/////// Cast expressions -////var x = ({ -//// /*6*/x1: 0, -////}); -////// Call expression -////function bar(e: MyPoint) { } -////bar({ -//// /*7*/ -////}); -////// New Expression -////class bar2 { -//// constructor(e: MyPoint) { } -////} -//// -////new bar2({ -//// x1: 0, -//// /*8*/ -////}); -////interface Foo { -//// x: { a: number }; -////} -////var aaa: Foo; -////aaa = {/*9*/ -////aaa.x = { /*10*/ -////var bbb = { /*11*/ -////var bbb = { x: { /*12*/ -////var ccc: Foo = { func: () => ({ /*13*/ }) -////var ddd: Foo = { -//// -//// /*14*/ -////var p15: MyPoint = { -//// "x1": 5, -//// /*15*/ -////}; -////// return statements -////function foo(): MyPoint { -//// return { -//// /*16*/ }; -////} -////interface MyPointCreator { -//// create(): MyPoint; -////} -//// -////function getMyPointCreator(): MyPointCreator { -//// return { -//// create: () => { -//// return { -//// x1: 5, -//// /*17*/ -//// }; -//// }, -//// } -////} -//// var eee:Foo = { /*18*/ - -////interface Foo { -//// x: { a: number }; -////} -//// var fff:Foo = { x: { /*19*/ - -goTo.marker("1"); -verify.memberListContains("x1"); -verify.memberListContains("y1"); - -goTo.marker("2"); -verify.memberListContains("x1"); -verify.memberListContains("y1"); - -goTo.marker("3"); -verify.not.memberListContains("x1"); -verify.memberListContains("y1"); - -goTo.marker("4"); -verify.not.memberListContains("x1"); -verify.not.memberListContains("y1"); - -goTo.marker("5"); -verify.completionListIsEmpty(); - -goTo.marker("6"); -verify.memberListContains("x1"); -verify.memberListContains("y1"); - -goTo.marker("7"); -verify.memberListContains("x1"); -verify.memberListContains("y1"); - -goTo.marker("8"); -verify.not.memberListContains("x1"); -verify.memberListContains("y1"); - -goTo.marker("11"); -verify.memberListContains("x"); -verify.memberListCount(1); - -goTo.marker("12"); -verify.memberListContains("a"); -verify.memberListCount(1); - -goTo.marker("13"); -verify.memberListCount(0); - -goTo.marker("14"); -verify.memberListContains("x"); -verify.memberListCount(1); - -goTo.marker("16"); -verify.memberListContains("x1"); -verify.memberListContains("y1"); -verify.memberListCount(2); - -goTo.marker("17"); -verify.not.memberListContains("x1"); -verify.memberListContains("y1"); -verify.memberListCount(1); - -goTo.marker("18"); -verify.memberListContains("x"); -verify.memberListCount(1); - -goTo.marker("19"); -verify.memberListContains("a"); -verify.memberListCount(1); \ No newline at end of file diff --git a/tests/cases/fourslash_old/constructorOverloadWithoutImplementation.ts b/tests/cases/fourslash_old/constructorOverloadWithoutImplementation.ts deleted file mode 100644 index 79af7af77b..0000000000 --- a/tests/cases/fourslash_old/constructorOverloadWithoutImplementation.ts +++ /dev/null @@ -1,9 +0,0 @@ -/// - -////class C { -//// constructor(); -//// constructor(x); -//// /*1*/constructor/*2*/(x, y); -////} - -verify.errorExistsBetweenMarkers('1', '2'); \ No newline at end of file diff --git a/tests/cases/fourslash_old/constructorOverloadWithoutImplementation2.ts b/tests/cases/fourslash_old/constructorOverloadWithoutImplementation2.ts deleted file mode 100644 index 22ec5dd79c..0000000000 --- a/tests/cases/fourslash_old/constructorOverloadWithoutImplementation2.ts +++ /dev/null @@ -1,9 +0,0 @@ -/// - -////class C { -//// constructor(); -//// constructor(x); -//// /*1*/foo/*2*/(x, y) { } -////} - -verify.errorExistsBetweenMarkers('1', '2'); \ No newline at end of file diff --git a/tests/cases/fourslash_old/exportEqualIncremental.ts b/tests/cases/fourslash_old/exportEqualIncremental.ts deleted file mode 100644 index ee6ed886a4..0000000000 --- a/tests/cases/fourslash_old/exportEqualIncremental.ts +++ /dev/null @@ -1,20 +0,0 @@ -/// - -////interface IPoint { -//// getDist(): number; -////} -////module Shapes { -//// export class Point implements /*1*/IPoint/*2*/ { -//// constructor (public x: number, public y: number) { } -//// getDist() { return Math.sqrt(this.x * this.x + this.y * this.y); } -//// static origin = new Point(0, 0); -//// } -////} -////var p: IPoint = new Shapes.Point(3, 4); -////var dist = p.getDist(); - -verify.numberOfErrorsInCurrentFile(0); -goTo.eof(); -edit.insertLine("export = Shapes"); -verify.numberOfErrorsInCurrentFile(1); -verify.errorExistsBetweenMarkers("1", "2"); diff --git a/tests/cases/fourslash_old/findReferences.ts b/tests/cases/fourslash_old/findReferences.ts deleted file mode 100644 index 71efcf1d14..0000000000 --- a/tests/cases/fourslash_old/findReferences.ts +++ /dev/null @@ -1,62 +0,0 @@ -/// - -////class [|{| "name" : "className" |}foo|] { -//// constructor() { -//// } -//// public get [|{| "name" : "barMethodName" |}bar|]() { -//// return 0; -//// } -//// static [|{| "name" : "staticMethodName" |}method|]() { } -////} -////var n: [|{| "name" : "varTypeName" |}foo|] = new [|{| "name" : "ctorInvocation" |}foo|](); -////var x = n.[|{| "name" : "barMethodInvocation" |}bar|](); -////[|{| "name" : "classNameMethodInvocation" |}foo|].[|{| "name" : "staticMethodInvocation" |}method|](); - -var foo1: FourSlashInterface.Range = test.ranges().filter((range)=> range.marker.data.name === "className")[0]; -var bar1: FourSlashInterface.Range = test.ranges().filter((range)=> range.marker.data.name === "barMethodName")[0]; -var method1: FourSlashInterface.Range = test.ranges().filter((range)=> range.marker.data.name === "staticMethodName")[0]; -var foo2: FourSlashInterface.Range = test.ranges().filter((range)=> range.marker.data.name === "varTypeName")[0]; -var foo3: FourSlashInterface.Range = test.ranges().filter((range)=> range.marker.data.name === "ctorInvocation")[0]; -var bar2: FourSlashInterface.Range = test.ranges().filter((range)=> range.marker.data.name === "barMethodInvocation")[0]; -var foo4: FourSlashInterface.Range = test.ranges().filter((range)=> range.marker.data.name === "classNameMethodInvocation")[0]; -var method2: FourSlashInterface.Range = test.ranges().filter((range)=> range.marker.data.name === "staticMethodInvocation")[0]; - -goTo.marker('className'); -verify.occurrencesAtPositionContains(foo1); -verify.occurrencesAtPositionContains(foo2); -verify.occurrencesAtPositionContains(foo3); -verify.occurrencesAtPositionContains(foo4); - -goTo.marker('barMethodName'); -verify.occurrencesAtPositionContains(bar1); -verify.occurrencesAtPositionContains(bar2); - -goTo.marker('staticMethodName'); -verify.occurrencesAtPositionContains(method1); -verify.occurrencesAtPositionContains(method2); - -goTo.marker('varTypeName'); -verify.occurrencesAtPositionContains(foo1); -verify.occurrencesAtPositionContains(foo2); -verify.occurrencesAtPositionContains(foo3); -verify.occurrencesAtPositionContains(foo4); - -goTo.marker('ctorInvocation'); -verify.occurrencesAtPositionContains(foo1); -verify.occurrencesAtPositionContains(foo2); -verify.occurrencesAtPositionContains(foo3); -verify.occurrencesAtPositionContains(foo4); - -goTo.marker('barMethodInvocation'); -verify.occurrencesAtPositionContains(bar1); -verify.occurrencesAtPositionContains(bar2); - -goTo.marker('classNameMethodInvocation'); -verify.occurrencesAtPositionContains(foo1); -verify.occurrencesAtPositionContains(foo2); -verify.occurrencesAtPositionContains(foo3); -verify.occurrencesAtPositionContains(foo4); - -goTo.marker('staticMethodInvocation'); -verify.occurrencesAtPositionContains(method1); -verify.occurrencesAtPositionContains(method2); \ No newline at end of file diff --git a/tests/cases/fourslash_old/findReferences1.ts b/tests/cases/fourslash_old/findReferences1.ts deleted file mode 100644 index 3d06cacee2..0000000000 --- a/tests/cases/fourslash_old/findReferences1.ts +++ /dev/null @@ -1,28 +0,0 @@ -/// - -//// interface I { -//// (): void; -//// } -//// -//// var i: I; -//// var [|{| "name" : "varName" |}o|]: Object; -//// [|{| "name" : "varName1" |}o|] = i; -//// i = [|{| "name" : "varName2" |}o|]; -//// -//// var a: { -//// (): void -//// } -//// [|{| "name" : "varName3" |}o|] = a; -//// a = [|{| "name" : "varName4" |}o|]; - -var varName: FourSlashInterface.Range = test.ranges().filter(range => range.marker.data.name === "varName")[0]; -var varName1: FourSlashInterface.Range = test.ranges().filter(range => range.marker.data.name === "varName1")[0]; -var varName2: FourSlashInterface.Range = test.ranges().filter(range => range.marker.data.name === "varName2")[0]; -var varName3: FourSlashInterface.Range = test.ranges().filter(range => range.marker.data.name === "varName3")[0]; -var varName4: FourSlashInterface.Range = test.ranges().filter(range => range.marker.data.name === "varName4")[0]; - -goTo.marker('varName'); -verify.occurrencesAtPositionContains(varName1); -verify.occurrencesAtPositionContains(varName2); -verify.occurrencesAtPositionContains(varName3); -verify.occurrencesAtPositionContains(varName4); diff --git a/tests/cases/fourslash_old/findReferencesAliases1.ts b/tests/cases/fourslash_old/findReferencesAliases1.ts deleted file mode 100644 index 0bee382e2b..0000000000 --- a/tests/cases/fourslash_old/findReferencesAliases1.ts +++ /dev/null @@ -1,20 +0,0 @@ -/// - -////declare module mod { -//// class Customer { -//// constructor(name: string); -//// } -////} -////import [|{| "name" : "aliasName1" |}c|] = mod.Customer; -////[|{| "name" : "aliasName2" |}c|].prototype; - -var name1: FourSlashInterface.Range = test.ranges().filter(range => range.marker.data.name === "aliasName1")[0]; -var name2: FourSlashInterface.Range = test.ranges().filter(range => range.marker.data.name === "aliasName2")[0]; - -goTo.marker('aliasName1'); -verify.occurrencesAtPositionContains(name1); -verify.occurrencesAtPositionContains(name2); - -goTo.marker('aliasName2'); -verify.occurrencesAtPositionContains(name1); -verify.occurrencesAtPositionContains(name2); \ No newline at end of file diff --git a/tests/cases/fourslash_old/findReferencesModules1.ts b/tests/cases/fourslash_old/findReferencesModules1.ts deleted file mode 100644 index 5956bd3693..0000000000 --- a/tests/cases/fourslash_old/findReferencesModules1.ts +++ /dev/null @@ -1,27 +0,0 @@ -/// - -////module [|{| "name" : "moduleName1" |}foo|] { -//// export class Point { -//// constructor(public x: number, public y: number) { } -//// } -////} -////var p: [|{| "name" : "moduleName2" |}foo|].Point = new [|{| "name" : "moduleName3" |}foo|].Point(1, 1); - -var foo1: FourSlashInterface.Range = test.ranges().filter(range => range.marker.data.name === "moduleName1")[0]; -var foo2: FourSlashInterface.Range = test.ranges().filter(range => range.marker.data.name === "moduleName2")[0]; -var foo3: FourSlashInterface.Range = test.ranges().filter(range => range.marker.data.name === "moduleName3")[0]; - -goTo.marker('moduleName1'); -verify.occurrencesAtPositionContains(foo1); -verify.occurrencesAtPositionContains(foo2); -verify.occurrencesAtPositionContains(foo3); - -goTo.marker('moduleName2'); -verify.occurrencesAtPositionContains(foo1); -verify.occurrencesAtPositionContains(foo2); -verify.occurrencesAtPositionContains(foo3); - -goTo.marker('moduleName3'); -verify.occurrencesAtPositionContains(foo1); -verify.occurrencesAtPositionContains(foo2); -verify.occurrencesAtPositionContains(foo3); \ No newline at end of file diff --git a/tests/cases/fourslash_old/funduleDefinedInADifferentFile.ts b/tests/cases/fourslash_old/funduleDefinedInADifferentFile.ts deleted file mode 100644 index c605ca0077..0000000000 --- a/tests/cases/fourslash_old/funduleDefinedInADifferentFile.ts +++ /dev/null @@ -1,12 +0,0 @@ -/// - -////function E() { } -////module E { -//// export interface I {} -//// export var value = 1; -////} - -////var x: E.I; -////var y/**/ = E.value; -goTo.marker(); -verify.numberOfErrorsInCurrentFile(0); \ No newline at end of file diff --git a/tests/cases/fourslash_old/funduleDefinedInADifferentFile2.ts b/tests/cases/fourslash_old/funduleDefinedInADifferentFile2.ts deleted file mode 100644 index 5c7aff2bfc..0000000000 --- a/tests/cases/fourslash_old/funduleDefinedInADifferentFile2.ts +++ /dev/null @@ -1,29 +0,0 @@ -/// - -// @Filename: f1.ts -////declare module "q" { -//// export = Q; -////} -////declare function Q(value: T): void; -////declare module Q { -//// -//// interface Deferred { -//// // promise: Promise; -//// resolve(value: T): void; -//// reject(reason: any): void; -//// notify(value: any): void; -//// makeNodeResolver(): (reason: any, value: T) => void; -//// } -//// -////export function defer(): Deferred; -////} - -// @Filename: f2.ts -/////// -////import q = require('q'); -////Q.defer/**/(); - - -goTo.marker(); -verify.completionListContains('defer'); -verify.numberOfErrorsInCurrentFile(0); diff --git a/tests/cases/fourslash_old/genericIncrementalParse.ts b/tests/cases/fourslash_old/genericIncrementalParse.ts deleted file mode 100644 index 73c4c888b1..0000000000 --- a/tests/cases/fourslash_old/genericIncrementalParse.ts +++ /dev/null @@ -1,30 +0,0 @@ -/// - - -//// class C { // it is error to reference T in constraint -//// constructor() { } -//// foo(a: T) { -//// } -//// } -//// -//// interface I1 { -//// a: number; -//// }; -//// -//// interface I2 { -//// a: number; -//// b: string; -//// } -//// -//// var x = new C< { a: number; }, { a: number; b: string; }>(); -//// var y = new C(); -//// /*1*/ - -verify.numberOfErrorsInCurrentFile(1); - -goTo.marker("1"); -edit.insert("var z = new C < I2"); -verify.numberOfErrorsInCurrentFile(2); - -edit.insert(",I1>()"); -verify.numberOfErrorsInCurrentFile(2); diff --git a/tests/cases/fourslash_old/genericStructuralTypeConstraint.ts b/tests/cases/fourslash_old/genericStructuralTypeConstraint.ts deleted file mode 100644 index 458aaaa580..0000000000 --- a/tests/cases/fourslash_old/genericStructuralTypeConstraint.ts +++ /dev/null @@ -1,37 +0,0 @@ -/// - - -//// class C { // it is error to reference T in constraint -//// constructor() { } -//// foo(a: T) { -//// } -//// } -//// -//// interface I1 { -//// a: string;/*1*/ -//// }; -//// -//// interface I2 { -//// a: number; -//// b: string; -//// } -//// -//// var x = new C< { a: number; }, { a: number; b: string; }>(); -//// var y = new C(); -//// var z = new C() -//// /*2*/ - -goTo.marker("2"); -edit.insertLine(""); -// y fails due to a: string in I1, z fails due to I1 not being assignment compatible to I2 -verify.numberOfErrorsInCurrentFile(3); - -goTo.marker("1"); -edit.backspace(10); -edit.insertLine(""); -verify.numberOfErrorsInCurrentFile(2); -// y should be OK now member a is gone, z fails due to I1 not being assignment compatible to I2 - -edit.insert("a: number;"); -// y should be OK with member a the correct type, z still fails due to I1 not being assignment compatible to I2 -verify.numberOfErrorsInCurrentFile(2); diff --git a/tests/cases/fourslash_old/getTypeOfUnresolvedGenericExtension.ts b/tests/cases/fourslash_old/getTypeOfUnresolvedGenericExtension.ts deleted file mode 100644 index 0faf4cbb95..0000000000 --- a/tests/cases/fourslash_old/getTypeOfUnresolvedGenericExtension.ts +++ /dev/null @@ -1,10 +0,0 @@ -/// - -//// class S18 extends S18< A[], { }[] > -//// { -//// } -//// (new S18(123))./**/S18 ; -//// - -goTo.marker(); -diagnostics.validateTypeAtCurrentPosition(); diff --git a/tests/cases/fourslash_old/overloadResolutionErrors.ts b/tests/cases/fourslash_old/overloadResolutionErrors.ts deleted file mode 100644 index ac3a4def8c..0000000000 --- a/tests/cases/fourslash_old/overloadResolutionErrors.ts +++ /dev/null @@ -1,38 +0,0 @@ -/// - -// Tests that the error spans are correct for a signature mismatch - -/////*1*/'foo'.replace('o', '3')./*2*/replace/*3*/('f', 5)/*4*/; -//// -/////*5*/('foo'.replace('o', '3')./*55*/replace/*6*/)/*65*/('f', 5); -////var foo = { -//// fun: () => false, -//// fun2: function () { return true; } -////}; -/////*7*/foo./*8*/fun/*9*/(1); -/////*10*/foo./*11*/fun2/*12*/(1); -//// -////module M { -//// export class C { -//// constructor(x: number) { } -//// public method(x: string); -//// public method(x: number); -//// public method(x) { } -//// } -////} -////var c: M.C = new /*13*/M./*14*/C/*15*/(""); -/////*16*/c./*17*/method/*18*/(c); -/////*19*/(c./*195*/method/*20*/)/*21*/(c); - - -verify.errorExistsBetweenMarkers('2', '3'); -verify.errorExistsBetweenMarkers('8', '9'); -verify.errorExistsBetweenMarkers('11', '12'); -verify.errorExistsBetweenMarkers('14', '15'); -verify.errorExistsBetweenMarkers('17', '18'); -verify.not.errorExistsBetweenMarkers('1', '2'); -verify.not.errorExistsBetweenMarkers('3', '4'); -verify.not.errorExistsBetweenMarkers('7', '8'); -verify.not.errorExistsBetweenMarkers('10', '11'); -verify.not.errorExistsBetweenMarkers('13', '14'); -verify.not.errorExistsBetweenMarkers('16', '17'); diff --git a/tests/cases/fourslash_old/thisRefGotoDef.ts b/tests/cases/fourslash_old/thisRefGotoDef.ts deleted file mode 100644 index ba16a6aa31..0000000000 --- a/tests/cases/fourslash_old/thisRefGotoDef.ts +++ /dev/null @@ -1,12 +0,0 @@ -/// - -//// class Greeter { -//// /*def*/element: HTMLElement; -//// span: HTMLElement; -//// timerToken: number; -//// constructor(element: HTMLElement) { -//// this.element/*ref*/ = element; -//// } -//// } - -verify.goToDefinition("ref", "def"); From 747a6fd4f55f4a13adfa321c161dd8632e0c2ac1 Mon Sep 17 00:00:00 2001 From: Soo Jae Hwang Date: Wed, 22 Mar 2017 09:17:00 +0900 Subject: [PATCH 110/164] Replace "tsc @args.txt" to "tsc --project tsconfig.json" --- lib/tsc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tsc.js b/lib/tsc.js index be8abfb4a0..f7231fcafd 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -53977,7 +53977,7 @@ var ts; var padding = makePadding(marginLength); output.push(getDiagnosticText(ts.Diagnostics.Examples_Colon_0, makePadding(marginLength - examplesLength) + "tsc hello.ts") + ts.sys.newLine); output.push(padding + "tsc --outFile file.js file.ts" + ts.sys.newLine); - output.push(padding + "tsc @args.txt" + ts.sys.newLine); + output.push(padding + "tsc --project tsconfig.json" + ts.sys.newLine); output.push(ts.sys.newLine); output.push(getDiagnosticText(ts.Diagnostics.Options_Colon) + ts.sys.newLine); var optsList = ts.filter(ts.optionDeclarations.slice(), function (v) { return !v.experimental; }); From 5b739cf78ce901ae556c725221873801b45cd1a4 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Tue, 21 Mar 2017 22:54:06 -0700 Subject: [PATCH 111/164] respond to comments --- src/compiler/checker.ts | 118 +++++++++++++----- src/compiler/core.ts | 3 - src/compiler/transformers/es2017.ts | 2 +- src/compiler/transformers/esnext.ts | 4 +- src/compiler/transformers/ts.ts | 2 +- src/compiler/types.ts | 6 +- src/compiler/utilities.ts | 6 +- src/services/codefixes/fixAddMissingMember.ts | 2 +- .../fixClassIncorrectlyImplementsInterface.ts | 2 +- src/services/codefixes/helpers.ts | 40 +++--- ...assExtendAbstractMethodAnonymousClass.1.ts | 33 +++++ ...ClassImplementClassMemberAnonymousClass.ts | 20 +++ ...FixClassImplementClassPropertyTypeQuery.ts | 10 ++ 13 files changed, 180 insertions(+), 68 deletions(-) create mode 100644 tests/cases/fourslash/codeFixClassExtendAbstractMethodAnonymousClass.1.ts create mode 100644 tests/cases/fourslash/codeFixClassImplementClassMemberAnonymousClass.ts create mode 100644 tests/cases/fourslash/codeFixClassImplementClassPropertyTypeQuery.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bb5046a8d6..dabc5407e1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -106,9 +106,9 @@ namespace ts { getParameterType: getTypeAtPosition, getReturnTypeOfSignature, getNonNullableType, - createTypeNode, - createIndexSignatureFromIndexInfo, - createSignatureParts, + typeToTypeNode, + indexInfoToIndexSignatureDeclaration, + signatureToSignatureDeclaration, getSymbolsInScope: (location, meaning) => { location = getParseTreeNode(location); return location ? getSymbolsInScope(location, meaning) : []; @@ -2196,8 +2196,8 @@ namespace ts { return undefined; } - const constraint = createTypeNode(getConstraintFromTypeParameter(type), enclosingDeclaration); - const defaultParameter = createTypeNode(getDefaultFromTypeParameter(type), enclosingDeclaration); + const constraint = typeToTypeNode(getConstraintFromTypeParameter(type), enclosingDeclaration); + const defaultParameter = typeToTypeNode(getDefaultFromTypeParameter(type), enclosingDeclaration); const name = symbolToString(type.symbol); return createTypeParameterDeclaration(name, constraint, defaultParameter); @@ -2206,7 +2206,7 @@ namespace ts { function createParameterDeclarationFromSymbol(parameterSymbol: Symbol, enclosingDeclaration: Node): ParameterDeclaration { const parameterDeclaration = parameterSymbol.declarations[0] as ParameterDeclaration; const parameterType = getTypeOfSymbol(parameterSymbol); - const parameterTypeNode = createTypeNode(parameterType, enclosingDeclaration); + const parameterTypeNode = typeToTypeNode(parameterType, enclosingDeclaration); // TODO: how should we clone members/modifiers? // TODO: check initializer accessibility correctly. const parameterNode = createParameter( @@ -2220,32 +2220,35 @@ namespace ts { return parameterNode; } - function createSignatureParts(signature: Signature, enclosingDeclaration: Node): SignatureParts { - return { - typeParameters: signature.typeParameters && signature.typeParameters.map(parameter => createTypeParameterDeclarationFromType(parameter,enclosingDeclaration)), - parameters: signature.parameters.map(parameter => createParameterDeclarationFromSymbol(parameter,enclosingDeclaration)), - type: createTypeNodeExceptAny(getReturnTypeOfSignature(signature)) - } + function signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node): SignatureDeclaration { + const typeParameters = signature.typeParameters && signature.typeParameters.map(parameter => createTypeParameterDeclarationFromType(parameter, enclosingDeclaration)); + const parameters = signature.parameters.map(parameter => createParameterDeclarationFromSymbol(parameter, enclosingDeclaration)); + const type = createTypeNodeExceptAny(getReturnTypeOfSignature(signature)); + + return createSignatureDeclaration(kind, typeParameters, parameters, type); function createTypeNodeExceptAny(type: Type): TypeNode | undefined { - const typeNode = createTypeNode(type, enclosingDeclaration); + const typeNode = typeToTypeNode(type, enclosingDeclaration); return typeNode && typeNode.kind !== SyntaxKind.AnyKeyword ? typeNode : undefined; } } - function createTypeNode(type: Type, enclosingDeclaration: Node): TypeNode { - let undefinedArgumentIsError = true; + + // function typeToDisplayParts + + function typeToTypeNode(type: Type, enclosingDeclaration: Node, returnNodeOnError?: boolean): TypeNode { let encounteredError = false; let inObjectTypeLiteral = false; let checkAlias = true; let symbolStack: Symbol[] = undefined; const result = createTypeNodeWorker(type); - return encounteredError ? undefined: result; + // returnNodeOnError = true; // TODO: unset. + return encounteredError && !returnNodeOnError ? undefined: result; function createTypeNodeWorker(type: Type): TypeNode { if (!type) { - if (undefinedArgumentIsError) { encounteredError = true; } + encounteredError = true; return undefined; } @@ -2364,7 +2367,7 @@ namespace ts { const typeParameter = getTypeParameterFromMappedType(type); const typeParameterNode = createTypeParameterDeclarationFromType(typeParameter, enclosingDeclaration); - const templateTypeNode = createTypeNode(getTemplateTypeFromMappedType(type), enclosingDeclaration); + const templateTypeNode = typeToTypeNode(getTemplateTypeFromMappedType(type), enclosingDeclaration); const readonlyToken = (type).declaration && (type).declaration.readonlyToken ? createToken(SyntaxKind.ReadonlyKeyword) : undefined; const questionToken = (type).declaration && (type).declaration.questionToken ? createToken(SyntaxKind.QuestionToken) : undefined; @@ -2438,13 +2441,11 @@ namespace ts { if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) { const signature = resolved.callSignatures[0]; - const signatureParts = createSignatureParts(signature, enclosingDeclaration); - return createSignatureDeclaration(SyntaxKind.FunctionType, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type); + return signatureToSignatureDeclaration(signature, SyntaxKind.FunctionType, enclosingDeclaration); } if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) { const signature = resolved.constructSignatures[0]; - const signatureParts = createSignatureParts(signature, enclosingDeclaration); - return createSignatureDeclaration(SyntaxKind.ConstructorType, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type); + return signatureToSignatureDeclaration(signature, SyntaxKind.ConstructorType, enclosingDeclaration); } } @@ -2520,18 +2521,16 @@ namespace ts { function createTypeNodesFromResolvedType(resolvedType: ResolvedType): TypeElement[] { const typeElements: TypeElement[] = []; for (const signature of resolvedType.callSignatures) { - const signatureParts = createSignatureParts(signature, enclosingDeclaration); - typeElements.push(createSignatureDeclaration(SyntaxKind.CallSignature, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type)); + typeElements.push(signatureToSignatureDeclaration(signature, SyntaxKind.CallSignature, enclosingDeclaration)); } for (const signature of resolvedType.constructSignatures) { - const signatureParts = createSignatureParts(signature, enclosingDeclaration); - typeElements.push(createSignatureDeclaration(SyntaxKind.ConstructSignature, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type)); + typeElements.push(signatureToSignatureDeclaration(signature, SyntaxKind.ConstructSignature, enclosingDeclaration)); } if (resolvedType.stringIndexInfo) { - typeElements.push(createIndexSignatureFromIndexInfo(resolvedType.stringIndexInfo, IndexKind.String, enclosingDeclaration)); + typeElements.push(indexInfoToIndexSignatureDeclaration(resolvedType.stringIndexInfo, IndexKind.String, enclosingDeclaration)); } if (resolvedType.numberIndexInfo) { - typeElements.push(createIndexSignatureFromIndexInfo(resolvedType.numberIndexInfo, IndexKind.Number, enclosingDeclaration)); + typeElements.push(indexInfoToIndexSignatureDeclaration(resolvedType.numberIndexInfo, IndexKind.Number, enclosingDeclaration)); } const properties = resolvedType.properties; @@ -2550,8 +2549,8 @@ namespace ts { if (propertySymbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length) { const signatures = getSignaturesOfType(propertyType, SignatureKind.Call); for (const signature of signatures) { - const signatureParts = createSignatureParts(signature, enclosingDeclaration); - const methodDeclaration = createSignatureDeclaration(SyntaxKind.MethodSignature, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type, propertyName, optionalToken); + const methodDeclaration = signatureToSignatureDeclaration(signature, SyntaxKind.MethodSignature, enclosingDeclaration); + methodDeclaration.name = propertyName; methodDeclaration.questionToken = optionalToken; typeElements.push(methodDeclaration); } @@ -2571,7 +2570,6 @@ namespace ts { function createNameFromSymbol(symbol: Symbol): EntityName; function createNameFromSymbol(symbol: Symbol): EntityName { let parentSymbol: Symbol; - symbol; enclosingDeclaration; let meaning: SymbolFlags; // Get qualified name if the symbol is not a type parameter @@ -2580,18 +2578,49 @@ namespace ts { const isTypeParameter = symbol.flags & SymbolFlags.TypeParameter; if (!isTypeParameter && enclosingDeclaration) { chain = getSymbolChain(symbol, meaning, /*endOfChain*/ true); + // TODO: check whether type pointed to by symbol requires type arguments to be printed. Debug.assert(chain && chain.length > 0); } else { chain = [symbol]; } + parentSymbol = undefined; const result = createEntityNameFromSymbolChain(chain, chain.length - 1); return result; function createEntityNameFromSymbolChain(chain: Symbol[], index: number): EntityName { Debug.assert(chain && 0 <= index && index < chain.length); - const identifier = createIdentifier(getNameOfSymbol(chain[index])); + // const parentIndex = index - 1; + const symbol = chain[index]; + let typeParameterString = ""; + if(index > 0) { + // TODO: is the parentSymbol wrong? + const parentSymbol = chain[index - 1]; + let typeParameters: TypeParameter[]; + if(getCheckFlags(symbol) & CheckFlags.Instantiated) { + typeParameters = getTypeParametersOfClassOrInterface(parentSymbol); + } + else { + const targetSymbol = getTargetSymbol(parentSymbol); + if(targetSymbol.flags & (SymbolFlags.Class | SymbolFlags.Interface | SymbolFlags.TypeAlias)) { + typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); + } + } + if(typeParameters && typeParameters.length > 0) { + encounteredError = true; + const writer = getSingleLineStringWriter(); + const displayBuilder = getSymbolDisplayBuilder(); + displayBuilder.buildDisplayForTypeParametersAndDelimiters(typeParameters, writer, enclosingDeclaration, 0); + typeParameterString = writer.string(); + releaseStringWriter(writer); + + } + } + const symbolName = getNameOfSymbol(symbol); + const symbolNameWithTypeParameters = typeParameterString.length > 0 ? `${symbolName}<${typeParameterString}>` : symbolName; + let identifier = createIdentifier(symbolNameWithTypeParameters); + return index > 0 ? createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier; } @@ -2628,10 +2657,31 @@ namespace ts { } } } + + function getNameOfSymbol(symbol: Symbol): string { + if (symbol.declarations && symbol.declarations.length) { + const declaration = symbol.declarations[0]; + if (declaration.name) { + return declarationNameToString(declaration.name); + } + if (declaration.parent && declaration.parent.kind === SyntaxKind.VariableDeclaration) { + return declarationNameToString((declaration.parent).name); + } + encounteredError = true; + switch (declaration.kind) { + case SyntaxKind.ClassExpression: + return "(Anonymous class)"; + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: + return "(Anonymous function)"; + } + } + return symbol.name; + } } } - function createIndexSignatureFromIndexInfo(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node): IndexSignatureDeclaration { + function indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node): IndexSignatureDeclaration { const indexerTypeNode = createKeywordTypeNode(kind === IndexKind.String ? SyntaxKind.StringKeyword : SyntaxKind.NumberKeyword); const name = getNameFromIndexInfo(indexInfo); @@ -2643,7 +2693,7 @@ namespace ts { /*questionToken*/ undefined, indexerTypeNode, /*initializer*/ undefined); - const typeNode = createTypeNode(indexInfo.type, enclosingDeclaration); + const typeNode = typeToTypeNode(indexInfo.type, enclosingDeclaration); return createIndexSignatureDeclaration( [indexingParameter], typeNode, diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 3f466e726d..c380a39611 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1067,9 +1067,6 @@ namespace ts { /** Does nothing. */ export function noop(): void {} - /** Returns its first argument. */ - export function identity(x: X): X { return x; } - /** Throws an error because a function is not implemented. */ export function notImplemented(): never { throw new Error("Not implemented"); diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 9c7bcf5b2a..088c57866d 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -125,7 +125,7 @@ namespace ts { visitNodes(node.modifiers, visitor, isModifier), node.asteriskToken, node.name, - node.questionToken, + /*questionToken*/ undefined, /*typeParameters*/ undefined, visitParameterList(node.parameters, visitor, context), /*type*/ undefined, diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index 2475e51119..83e84e6eab 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -475,7 +475,7 @@ namespace ts { /*modifiers*/ undefined, node.dotDotDotToken, getGeneratedNameForNode(node), - node.questionToken, + /*questionToken*/ undefined, /*type*/ undefined, visitNode(node.initializer, visitor, isExpression) ); @@ -541,7 +541,7 @@ namespace ts { ? undefined : node.asteriskToken, visitNode(node.name, visitor, isPropertyName), - visitNode(node.questionToken, visitor, isToken), + visitNode(/*questionToken*/ undefined, visitor, isToken), /*typeParameters*/ undefined, visitParameterList(node.parameters, visitor, context), /*type*/ undefined, diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index bbc588ee9f..6dc643b954 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2049,7 +2049,7 @@ namespace ts { visitNodes(node.modifiers, modifierVisitor, isModifier), node.asteriskToken, visitPropertyNameOfClassElement(node), - node.questionToken, + /*questionToken*/ undefined, /*typeParameters*/ undefined, visitParameterList(node.parameters, visitor, context), /*type*/ undefined, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 2579ee2eaf..5ccdd79f19 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2473,11 +2473,11 @@ namespace ts { getNonNullableType(type: Type): Type; /** Note that the resulting nodes cannot be checked. */ - createTypeNode(type: Type, enclosingDeclaration: Node): TypeNode; + typeToTypeNode(type: Type, enclosingDeclaration: Node): TypeNode; /** Note that the resulting nodes cannot be checked. */ - createIndexSignatureFromIndexInfo(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node): IndexSignatureDeclaration; + indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node): IndexSignatureDeclaration; /** Note that the resulting nodes cannot be checked. */ - createSignatureParts(signature: Signature, enclosingDeclaration: Node): SignatureParts; + signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node): SignatureDeclaration; getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; getSymbolAtLocation(node: Node): Symbol; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 47642291c2..656b3c5db4 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -744,8 +744,8 @@ namespace ts { // // let a: A.B.C; // - // Calling isPartOfTypeNode would consider the qualified name A.B a type node. Only C or - // A.B.C is a type node. + // Calling isPartOfTypeNode would consider the qualified name A.B a type node. + // Only C and A.B.C are type nodes. if (SyntaxKind.FirstTypeNode <= parent.kind && parent.kind <= SyntaxKind.LastTypeNode) { return true; } @@ -3735,7 +3735,7 @@ namespace ts { * of a TypeNode. */ export function isTypeNode(node: Node): node is TypeNode { - return isTypeNodeKind(node.kind); + return node && isTypeNodeKind(node.kind) && (!node.parent || isPartOfTypeNode(node)); } // Binding patterns diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index a67c6791ba..bf706e7ded 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -38,7 +38,7 @@ namespace ts.codefix { const checker = context.program.getTypeChecker(); const widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(binaryExpression.right))); - typeNode = checker.createTypeNode(widenedType, classDeclaration) || typeNode; + typeNode = checker.typeToTypeNode(widenedType, classDeclaration) || typeNode; } const openBrace = getOpenBraceOfClassLike(classDeclaration, sourceFile); diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts index 365fd35801..3b1b99febb 100644 --- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts +++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts @@ -53,7 +53,7 @@ namespace ts.codefix { if (!indexInfoOfKind) { return; } - const newIndexSignatureDeclaration = checker.createIndexSignatureFromIndexInfo(indexInfoOfKind, kind, classDeclaration); + const newIndexSignatureDeclaration = checker.indexInfoToIndexSignatureDeclaration(indexInfoOfKind, kind, classDeclaration); newNodes.push(newIndexSignatureDeclaration); } diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 4a9ee25228..3b4a75caa7 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -64,7 +64,7 @@ namespace ts.codefix { const declaration = declarations[0] as Declaration; const name = declaration.name ? getSynthesizedDeepClone(declaration.name) as PropertyName : undefined; const visibilityModifier = createVisibilityModifier(getModifierFlags(declaration)); - const modifiers = visibilityModifier ? [visibilityModifier] : undefined; + const modifiers = visibilityModifier ? createNodeArray([visibilityModifier]) : undefined; const type = checker.getWidenedType(checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration)); switch (declaration.kind) { @@ -72,7 +72,7 @@ namespace ts.codefix { case SyntaxKind.SetAccessor: case SyntaxKind.PropertySignature: case SyntaxKind.PropertyDeclaration: - const typeNode = checker.createTypeNode(type, enclosingDeclaration); + const typeNode = checker.typeToTypeNode(type, enclosingDeclaration); const property = createProperty( /*decorators*/undefined, modifiers, @@ -99,30 +99,32 @@ namespace ts.codefix { if (declarations.length === 1) { Debug.assert(signatures.length === 1); const signature = signatures[0]; - const signatureParts = checker.createSignatureParts(signature, enclosingDeclaration); - return createStubbedMethod(modifiers, name, optional, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type); + const signatureDeclaration = checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration) as MethodDeclaration; + signatureDeclaration.modifiers = modifiers; + signatureDeclaration.name = name; + signatureDeclaration.questionToken = optional ? createToken(SyntaxKind.QuestionToken) : undefined; + signatureDeclaration.body = createStubbedMethodBody(); + return signatureDeclaration; } let signatureDeclarations = []; for (let i = 0; i < signatures.length; i++) { const signature = signatures[i]; - const signatureParts = checker.createSignatureParts(signature, enclosingDeclaration); - signatureDeclarations.push(createMethod( - /*decorators*/ undefined, - modifiers, - /*asteriskToken*/ undefined, - name, - optional ? createToken(SyntaxKind.QuestionToken) : undefined, - signatureParts.typeParameters, - signatureParts.parameters, - signatureParts.type, - /*body*/undefined)); + const signatureDeclaration = checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration) as MethodDeclaration; + signatureDeclaration.modifiers = modifiers; + signatureDeclaration.name = name; + signatureDeclaration.questionToken = optional ? createToken(SyntaxKind.QuestionToken) : undefined; + signatureDeclarations.push(signatureDeclaration); } if (declarations.length > signatures.length) { let signature = checker.getSignatureFromDeclaration(declarations[declarations.length - 1] as SignatureDeclaration); - const signatureParts = checker.createSignatureParts(signature, enclosingDeclaration); - signatureDeclarations.push(createStubbedMethod(modifiers, name, optional, signatureParts.typeParameters, signatureParts.parameters, signatureParts.type)); + const signatureDeclaration = checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration) as MethodDeclaration; + signatureDeclaration.modifiers = modifiers; + signatureDeclaration.name = name; + signatureDeclaration.questionToken = optional ? createToken(SyntaxKind.QuestionToken) : undefined; + signatureDeclaration.body = createStubbedMethodBody(); + signatureDeclarations.push(signatureDeclaration); } else { Debug.assert(declarations.length === signatures.length); @@ -195,9 +197,9 @@ namespace ts.codefix { export function createStubbedMethod(modifiers: Modifier[], name: PropertyName, optional: boolean, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], returnType: TypeNode | undefined) { return createMethod( - /*decorators*/undefined, + /*decorators*/ undefined, modifiers, - /*asteriskToken*/undefined, + /*asteriskToken*/ undefined, name, optional ? createToken(SyntaxKind.QuestionToken) : undefined, typeParameters, diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractMethodAnonymousClass.1.ts b/tests/cases/fourslash/codeFixClassExtendAbstractMethodAnonymousClass.1.ts new file mode 100644 index 0000000000..134ce17376 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassExtendAbstractMethodAnonymousClass.1.ts @@ -0,0 +1,33 @@ +/// + +class A { + foo() { + return class { x: number; } + } + bar() { + return new class { x: number; } + } +} +class B { + foo() { + return class { + x: X; + } + } +} + + +class D extends A { } + +verify.rangeAfterCodeFix(` + f(a: number, b: string): boolean; + f(a: number, b: string): this; + f(a: string, b: number): Function; + f(a: string): Function; + f(a: any, b?: any) { + throw new Error("Method not implemented."); + } + foo(): number { + throw new Error("Method not implemented."); + } +`); diff --git a/tests/cases/fourslash/codeFixClassImplementClassMemberAnonymousClass.ts b/tests/cases/fourslash/codeFixClassImplementClassMemberAnonymousClass.ts new file mode 100644 index 0000000000..a8a024d194 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementClassMemberAnonymousClass.ts @@ -0,0 +1,20 @@ +/// + +//// class A { +//// foo() { +//// return class { x: number; } +//// } +//// bar() { +//// return new class { x: number; } +//// } +//// } +//// class C implements A {[| |]} + +verify.rangeAfterCodeFix(` + foo() { + throw new Error("Method not implemented."); + } + bar() { + throw new Error("Method not implemented."); + } +`); diff --git a/tests/cases/fourslash/codeFixClassImplementClassPropertyTypeQuery.ts b/tests/cases/fourslash/codeFixClassImplementClassPropertyTypeQuery.ts new file mode 100644 index 0000000000..4a5663a8ba --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementClassPropertyTypeQuery.ts @@ -0,0 +1,10 @@ +/// + +//// class A { +//// A: typeof A; +//// } +//// class D implements A {[| |]} + +verify.rangeAfterCodeFix(` + A: typeof A; +`); From 1511dd9c241cf4f0f85fddaa2ebb5840ee27f16e Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Thu, 2 Mar 2017 17:43:02 +0100 Subject: [PATCH 112/164] Fix parent type of JsxAttributes --- src/compiler/types.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 759d3cd41e..42b8a140e4 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1504,6 +1504,7 @@ namespace ts { export type JsxTagNameExpression = PrimaryExpression | PropertyAccessExpression; export interface JsxAttributes extends ObjectLiteralExpressionBase { + parent?: JsxOpeningLikeElement; } /// The opening element of a ... JsxElement @@ -1523,7 +1524,7 @@ namespace ts { export interface JsxAttribute extends ObjectLiteralElement { kind: SyntaxKind.JsxAttribute; - parent?: JsxOpeningLikeElement; + parent?: JsxAttributes; name: Identifier; /// JSX attribute initializers are optional; is sugar for initializer?: StringLiteral | JsxExpression; @@ -1531,7 +1532,7 @@ namespace ts { export interface JsxSpreadAttribute extends ObjectLiteralElement { kind: SyntaxKind.JsxSpreadAttribute; - parent?: JsxOpeningLikeElement; + parent?: JsxAttributes; expression: Expression; } From 6e086980a4955d2b539d61ba00ddd40afa0e0413 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Mon, 20 Mar 2017 22:07:15 +0100 Subject: [PATCH 113/164] Also fix type of NewExpression#arguments --- src/compiler/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 42b8a140e4..6a42c57cd6 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1450,7 +1450,7 @@ namespace ts { kind: SyntaxKind.NewExpression; expression: LeftHandSideExpression; typeArguments?: NodeArray; - arguments: NodeArray; + arguments?: NodeArray; } export interface TaggedTemplateExpression extends MemberExpression { From fcca27c03eb11d45691433b9fcaf60d94e118f13 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Tue, 21 Mar 2017 20:21:43 +0100 Subject: [PATCH 114/164] Fix type of HeritageClause#types --- src/compiler/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 6a42c57cd6..ba383ed1bc 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1778,7 +1778,7 @@ namespace ts { kind: SyntaxKind.HeritageClause; parent?: InterfaceDeclaration | ClassDeclaration | ClassExpression; token: SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword; - types?: NodeArray; + types: NodeArray; } export interface TypeAliasDeclaration extends DeclarationStatement { From eb8972d5ff9eec8dc3ad9c29a8d4b57fb6d0533b Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Wed, 22 Mar 2017 15:28:51 +0100 Subject: [PATCH 115/164] Add parent types to class elements --- src/compiler/types.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ba383ed1bc..78425c9eac 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -815,18 +815,21 @@ namespace ts { export interface ConstructorDeclaration extends FunctionLikeDeclaration, ClassElement { kind: SyntaxKind.Constructor; + parent?: ClassDeclaration | ClassExpression; body?: FunctionBody; } // For when we encounter a semicolon in a class declaration. ES6 allows these as class elements. export interface SemicolonClassElement extends ClassElement { kind: SyntaxKind.SemicolonClassElement; + parent?: ClassDeclaration | ClassExpression; } // See the comment on MethodDeclaration for the intuition behind GetAccessorDeclaration being a // ClassElement and an ObjectLiteralElement. export interface GetAccessorDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement { kind: SyntaxKind.GetAccessor; + parent?: ClassDeclaration | ClassExpression | ObjectLiteralExpression; name: PropertyName; body: FunctionBody; } @@ -835,6 +838,7 @@ namespace ts { // ClassElement and an ObjectLiteralElement. export interface SetAccessorDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement { kind: SyntaxKind.SetAccessor; + parent?: ClassDeclaration | ClassExpression | ObjectLiteralExpression; name: PropertyName; body: FunctionBody; } @@ -843,6 +847,7 @@ namespace ts { export interface IndexSignatureDeclaration extends SignatureDeclaration, ClassElement, TypeElement { kind: SyntaxKind.IndexSignature; + parent?: ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeLiteralNode; } export interface TypeNode extends Node { @@ -937,6 +942,7 @@ namespace ts { export interface MappedTypeNode extends TypeNode, Declaration { kind: SyntaxKind.MappedType; + parent?: TypeAliasDeclaration; readonlyToken?: ReadonlyToken; typeParameter: TypeParameterDeclaration; questionToken?: QuestionToken; From d906e91236c6363e22154ae5fa18f5b179b1f036 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 22 Mar 2017 12:01:08 -0700 Subject: [PATCH 116/164] Code review comments --- src/compiler/commandLineParser.ts | 58 +++++++++---------- src/compiler/diagnosticMessages.json | 30 +++++----- .../tsconfig.json | 14 ++--- .../tsconfig.json | 14 ++--- .../tsconfig.json | 14 ++--- .../tsconfig.json | 14 ++--- .../tsconfig.json | 14 ++--- .../tsconfig.json | 14 ++--- .../tsconfig.json | 14 ++--- .../tsconfig.json | 14 ++--- 10 files changed, 100 insertions(+), 100 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index bc9d090edd..598906cb05 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -15,7 +15,7 @@ namespace ts { shortName: "h", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.CommandLine_Options, + category: Diagnostics.Command_line_Options, description: Diagnostics.Print_this_message, }, { @@ -27,7 +27,7 @@ namespace ts { name: "all", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.CommandLine_Options, + category: Diagnostics.Command_line_Options, description: Diagnostics.Show_all_compiler_options, }, { @@ -35,14 +35,14 @@ namespace ts { shortName: "v", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.CommandLine_Options, + category: Diagnostics.Command_line_Options, description: Diagnostics.Print_the_compiler_s_version, }, { name: "init", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.CommandLine_Options, + category: Diagnostics.Command_line_Options, description: Diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file, }, { @@ -51,7 +51,7 @@ namespace ts { type: "string", isFilePath: true, showInSimplifiedHelpView: true, - category: Diagnostics.CommandLine_Options, + category: Diagnostics.Command_line_Options, paramType: Diagnostics.FILE_OR_DIRECTORY, description: Diagnostics.Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json, }, @@ -59,7 +59,7 @@ namespace ts { name: "pretty", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.CommandLine_Options, + category: Diagnostics.Command_line_Options, description: Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental }, { @@ -67,7 +67,7 @@ namespace ts { shortName: "w", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.CommandLine_Options, + category: Diagnostics.Command_line_Options, description: Diagnostics.Watch_input_files, }, @@ -230,13 +230,13 @@ namespace ts { name: "downlevelIteration", type: "boolean", category: Diagnostics.Basic_Options, - description: Diagnostics.Use_full_down_level_iteration_for_iterables_and_arrays_for_for_of_spread_and_destructuring_in_ES5_Slash3 + description: Diagnostics.Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3 }, { name: "isolatedModules", type: "boolean", category: Diagnostics.Basic_Options, - description: Diagnostics.Unconditionally_emit_imports_for_unresolved_files + description: Diagnostics.Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule }, // Strict Type Checks @@ -244,35 +244,35 @@ namespace ts { name: "strict", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.Strict_Type_Checks, - description: Diagnostics.Enable_all_strict_type_checks + category: Diagnostics.Strict_Type_Checking_Options, + description: Diagnostics.Enable_all_strict_type_checking_options }, { name: "noImplicitAny", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.Strict_Type_Checks, + category: Diagnostics.Strict_Type_Checking_Options, description: Diagnostics.Raise_error_on_expressions_and_declarations_with_an_implied_any_type, }, { name: "strictNullChecks", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.Strict_Type_Checks, + category: Diagnostics.Strict_Type_Checking_Options, description: Diagnostics.Enable_strict_null_checks }, { name: "noImplicitThis", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.Strict_Type_Checks, + category: Diagnostics.Strict_Type_Checking_Options, description: Diagnostics.Raise_error_on_this_expressions_with_an_implied_any_type, }, { name: "alwaysStrict", type: "boolean", showInSimplifiedHelpView: true, - category: Diagnostics.Strict_Type_Checks, + category: Diagnostics.Strict_Type_Checking_Options, description: Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file }, @@ -331,7 +331,7 @@ namespace ts { type: "object", isTSConfigOnly: true, category: Diagnostics.Module_Resolution_Options, - description: Diagnostics.List_of_path_mapping_entries_for_module_names_to_locations_relative_to_the_baseUrl + description: Diagnostics.A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl }, { @@ -346,7 +346,7 @@ namespace ts { isFilePath: true }, category: Diagnostics.Module_Resolution_Options, - description: Diagnostics.List_of_root_folders_whose_combined_content_represent_the_structure_of_the_project_at_runtime + description: Diagnostics.List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime }, { name: "typeRoots", @@ -383,7 +383,7 @@ namespace ts { type: "string", isFilePath: true, paramType: Diagnostics.LOCATION, - category: Diagnostics.SourceMap_Options, + category: Diagnostics.Source_Map_Options, description: Diagnostics.Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations, }, { @@ -391,19 +391,19 @@ namespace ts { type: "string", isFilePath: true, paramType: Diagnostics.LOCATION, - category: Diagnostics.SourceMap_Options, + category: Diagnostics.Source_Map_Options, description: Diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations, }, { name: "inlineSourceMap", type: "boolean", - category: Diagnostics.SourceMap_Options, + category: Diagnostics.Source_Map_Options, description: Diagnostics.Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file }, { name: "inlineSources", type: "boolean", - category: Diagnostics.SourceMap_Options, + category: Diagnostics.Source_Map_Options, description: Diagnostics.Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set }, @@ -438,7 +438,7 @@ namespace ts { name: "extendedDiagnostics", type: "boolean", category: Diagnostics.Advanced_Options, - description: Diagnostics.Show_extended_diagnostic_information + description: Diagnostics.Show_verbose_diagnostic_information }, { name: "traceResolution", @@ -496,7 +496,7 @@ namespace ts { name: "locale", type: "string", category: Diagnostics.Advanced_Options, - description: Diagnostics.The_locale_to_use_to_show_error_messages_e_g_en_us + description: Diagnostics.The_locale_used_when_displaying_messages_to_the_user_e_g_en_us }, { name: "newLine", @@ -512,7 +512,7 @@ namespace ts { name: "noErrorTruncation", type: "boolean", category: Diagnostics.Advanced_Options, - description: Diagnostics.Do_not_truncation_error_messages + description: Diagnostics.Do_not_truncate_error_messages }, { name: "noLib", @@ -524,7 +524,7 @@ namespace ts { name: "noResolve", type: "boolean", category: Diagnostics.Advanced_Options, - description: Diagnostics.Do_not_add_triple_slash_references_or_module_import_targets_to_the_list_of_compiled_files + description: Diagnostics.Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files }, { name: "stripInternal", @@ -536,7 +536,7 @@ namespace ts { name: "disableSizeLimit", type: "boolean", category: Diagnostics.Advanced_Options, - description: Diagnostics.Disable_size_limitation_on_JavaScript_project + description: Diagnostics.Disable_size_limitations_on_JavaScript_projects }, { name: "noImplicitUseStrict", @@ -621,7 +621,7 @@ namespace ts { name: "plugin", type: "object" }, - description: Diagnostics.List_of_Language_Service_plugins + description: Diagnostics.List_of_language_service_plugins } ]; @@ -932,7 +932,7 @@ namespace ts { if (hasProperty(options, name)) { // tsconfig only options cannot be specified via command line, // so we can assume that only types that can appear here string | number | boolean - if (optionsNameMap.has(name) && optionsNameMap.get(name).category === Diagnostics.CommandLine_Options) { + if (optionsNameMap.has(name) && optionsNameMap.get(name).category === Diagnostics.Command_line_Options) { continue; } const value = options[name]; @@ -987,7 +987,7 @@ namespace ts { function writeConfigurations() { // Filter applicable options to place in the file const categorizedOptions = reduceLeft( - filter(optionDeclarations, o => o.category !== Diagnostics.CommandLine_Options && o.category !== Diagnostics.Advanced_Options), + filter(optionDeclarations, o => o.category !== Diagnostics.Command_line_Options && o.category !== Diagnostics.Advanced_Options), (memo, value) => { if (value.category) { const name = getLocaleSpecificMessage(value.category); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index b60f49076e..92812604b8 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3045,7 +3045,7 @@ "category": "Message", "code": 6149 }, - "Show extended diagnostic information.": { + "Show verbose diagnostic information.": { "category": "Message", "code": 6150 }, @@ -3057,7 +3057,7 @@ "category": "Message", "code": 6152 }, - "Unconditionally emit imports for unresolved files.": { + "Transpile each file as a separate module (similar to 'ts.transpileModule').": { "category": "Message", "code": 6153 }, @@ -3069,11 +3069,11 @@ "category": "Message", "code": 6155 }, - "The locale to use to show error messages, e.g. 'en-us'.": { + "The locale used when displaying messages to the user (e.g. 'en-us')": { "category": "Message", "code": 6156 }, - "Do not generate custom helper functions like __extends in compiled output.": { + "Do not generate custom helper functions like '__extends' in compiled output.": { "category": "Message", "code": 6157 }, @@ -3081,7 +3081,7 @@ "category": "Message", "code": 6158 }, - "Do not add triple-slash references or module import targets to the list of compiled files.": { + "Do not add triple-slash references or imported modules to the list of compiled files.": { "category": "Message", "code": 6159 }, @@ -3093,7 +3093,7 @@ "category": "Message", "code": 6161 }, - "Disable size limitation on JavaScript project.": { + "Disable size limitations on JavaScript projects.": { "category": "Message", "code": 6162 }, @@ -3105,7 +3105,7 @@ "category": "Message", "code": 6164 }, - "Do not truncation error messages.": { + "Do not truncate error messages.": { "category": "Message", "code": 6165 }, @@ -3113,11 +3113,11 @@ "category": "Message", "code": 6166 }, - "List of path mapping entries for module names to locations relative to the 'baseUrl'.": { + "A series of entries which re-map imports to lookup locations relative to the 'baseUrl'.": { "category": "Message", "code": 6167 }, - "List of root folders whose combined content represent the structure of the project at runtime.": { + "List of root folders whose combined content represents the structure of the project at runtime.": { "category": "Message", "code": 6168 }, @@ -3129,7 +3129,7 @@ "category": "Message", "code": 6170 }, - "CommandLine Options": { + "Command-line Options": { "category": "Message", "code": 6171 }, @@ -3137,7 +3137,7 @@ "category": "Message", "code": 6172 }, - "Strict Type Checks": { + "Strict Type-Checking Options": { "category": "Message", "code": 6173 }, @@ -3145,7 +3145,7 @@ "category": "Message", "code": 6174 }, - "SourceMap Options": { + "Source Map Options": { "category": "Message", "code": 6175 }, @@ -3161,15 +3161,15 @@ "category": "Message", "code": 6178 }, - "Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3.": { + "Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'.": { "category": "Message", "code": 6179 }, - "Enable all strict type checks.": { + "Enable all strict type-checking options.": { "category": "Message", "code": 6180 }, - "List of Language Service plugins.": { + "List of language service plugins.": { "category": "Message", "code": 6181 }, diff --git a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json index f26b471d2c..5918c273ce 100644 --- a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json @@ -14,11 +14,11 @@ // "removeComments": true, /* Do not emit comments to output. */ // "noEmit": true, /* Do not emit outputs. */ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ - // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - /* Strict Type Checks */ - "strict": true /* Enable all strict type checks. */ + /* Strict Type-Checking Options */ + "strict": true /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ @@ -33,13 +33,13 @@ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - /* SourceMap Options */ + /* Source Map Options */ // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json index 2dc7f0564b..38c4542b40 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json @@ -14,11 +14,11 @@ // "removeComments": true, /* Do not emit comments to output. */ // "noEmit": true, /* Do not emit outputs. */ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ - // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - /* Strict Type Checks */ - "strict": true, /* Enable all strict type checks. */ + /* Strict Type-Checking Options */ + "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ @@ -33,13 +33,13 @@ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - /* SourceMap Options */ + /* Source Map Options */ // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json index 48a7fd7784..d948b64815 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json @@ -14,11 +14,11 @@ // "removeComments": true, /* Do not emit comments to output. */ // "noEmit": true, /* Do not emit outputs. */ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ - // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - /* Strict Type Checks */ - "strict": true /* Enable all strict type checks. */ + /* Strict Type-Checking Options */ + "strict": true /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ @@ -33,13 +33,13 @@ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - /* SourceMap Options */ + /* Source Map Options */ // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json index a2f4e6bd99..70870f296e 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json @@ -14,11 +14,11 @@ // "removeComments": true, /* Do not emit comments to output. */ // "noEmit": true, /* Do not emit outputs. */ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ - // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - /* Strict Type Checks */ - "strict": true /* Enable all strict type checks. */ + /* Strict Type-Checking Options */ + "strict": true /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ @@ -33,13 +33,13 @@ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - /* SourceMap Options */ + /* Source Map Options */ // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json index 62bfc7ca26..3eabb0894f 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json @@ -14,11 +14,11 @@ // "removeComments": true, /* Do not emit comments to output. */ // "noEmit": true, /* Do not emit outputs. */ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ - // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - /* Strict Type Checks */ - "strict": true /* Enable all strict type checks. */ + /* Strict Type-Checking Options */ + "strict": true /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ @@ -33,13 +33,13 @@ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - /* SourceMap Options */ + /* Source Map Options */ // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json index f26b471d2c..5918c273ce 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json @@ -14,11 +14,11 @@ // "removeComments": true, /* Do not emit comments to output. */ // "noEmit": true, /* Do not emit outputs. */ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ - // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - /* Strict Type Checks */ - "strict": true /* Enable all strict type checks. */ + /* Strict Type-Checking Options */ + "strict": true /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ @@ -33,13 +33,13 @@ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - /* SourceMap Options */ + /* Source Map Options */ // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json index 02a1724add..b88ac604c1 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json @@ -14,11 +14,11 @@ // "removeComments": true, /* Do not emit comments to output. */ // "noEmit": true, /* Do not emit outputs. */ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ - // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - /* Strict Type Checks */ - "strict": true /* Enable all strict type checks. */ + /* Strict Type-Checking Options */ + "strict": true /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ @@ -33,13 +33,13 @@ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - /* SourceMap Options */ + /* Source Map Options */ // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json index b1e048551d..db838e21d2 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json @@ -14,11 +14,11 @@ // "removeComments": true, /* Do not emit comments to output. */ // "noEmit": true, /* Do not emit outputs. */ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3. */ - // "isolatedModules": true, /* Unconditionally emit imports for unresolved files. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - /* Strict Type Checks */ - "strict": true, /* Enable all strict type checks. */ + /* Strict Type-Checking Options */ + "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ @@ -33,13 +33,13 @@ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* List of path mapping entries for module names to locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represent the structure of the project at runtime. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ "types": ["jquery","mocha"] /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - /* SourceMap Options */ + /* Source Map Options */ // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ From 88b88e10551be40c78b083b84f422f71ae125124 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 22 Mar 2017 12:41:11 -0700 Subject: [PATCH 117/164] Remove BOM --- src/compiler/commandLineParser.ts | 2 +- src/harness/unittests/initializeTSConfig.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 598906cb05..41d71c79ac 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1,4 +1,4 @@ -/// +/// /// /// /// diff --git a/src/harness/unittests/initializeTSConfig.ts b/src/harness/unittests/initializeTSConfig.ts index 4f193d358f..d0bc72d430 100644 --- a/src/harness/unittests/initializeTSConfig.ts +++ b/src/harness/unittests/initializeTSConfig.ts @@ -1,4 +1,4 @@ -/// +/// /// namespace ts { From ae1983bce1a65ecb736c3ce752eb228a4e3227b9 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 22 Mar 2017 12:45:36 -0700 Subject: [PATCH 118/164] Show help if `--all` is specifided without `--help` --- src/compiler/tsc.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index a62bad393a..4fd3ecb02b 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -225,7 +225,7 @@ namespace ts { return sys.exit(ExitStatus.Success); } - if (commandLine.options.help) { + if (commandLine.options.help || commandLine.options.all) { printVersion(); printHelp(commandLine.options.all); return sys.exit(ExitStatus.Success); From c4ddc5bffad8ab3609270a17ac6be40aaaa1ab7b Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Wed, 22 Mar 2017 12:54:51 -0700 Subject: [PATCH 119/164] Respond to more comments --- src/compiler/checker.ts | 72 ++++++++++--------- src/compiler/factory.ts | 20 ++---- src/services/codefixes/fixAddMissingMember.ts | 4 +- src/services/codefixes/helpers.ts | 2 +- src/services/textChanges.ts | 6 +- 5 files changed, 50 insertions(+), 54 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index dabc5407e1..c4eaed3fde 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2191,7 +2191,7 @@ namespace ts { return result; } - function createTypeParameterDeclarationFromType(type: TypeParameter, enclosingDeclaration: Node): TypeParameterDeclaration { + function typeParameterToDeclaration(type: TypeParameter, enclosingDeclaration?: Node): TypeParameterDeclaration { if (!(type && type.symbol && type.flags & TypeFlags.TypeParameter)) { return undefined; } @@ -2199,35 +2199,36 @@ namespace ts { const constraint = typeToTypeNode(getConstraintFromTypeParameter(type), enclosingDeclaration); const defaultParameter = typeToTypeNode(getDefaultFromTypeParameter(type), enclosingDeclaration); + // TODO: use method internal to typeToTypeNode. const name = symbolToString(type.symbol); return createTypeParameterDeclaration(name, constraint, defaultParameter); } - function createParameterDeclarationFromSymbol(parameterSymbol: Symbol, enclosingDeclaration: Node): ParameterDeclaration { + function symbolToParameterDeclaration(parameterSymbol: Symbol, enclosingDeclaration?: Node): ParameterDeclaration { const parameterDeclaration = parameterSymbol.declarations[0] as ParameterDeclaration; const parameterType = getTypeOfSymbol(parameterSymbol); const parameterTypeNode = typeToTypeNode(parameterType, enclosingDeclaration); // TODO: how should we clone members/modifiers? // TODO: check initializer accessibility correctly. const parameterNode = createParameter( - parameterDeclaration.decorators && parameterDeclaration.decorators.map(getSynthesizedDeepClone), - parameterDeclaration.modifiers && parameterDeclaration.modifiers.map(getSynthesizedDeepClone), + parameterDeclaration.decorators, + parameterDeclaration.modifiers, parameterDeclaration.dotDotDotToken && createToken(SyntaxKind.DotDotDotToken), - getSynthesizedDeepClone(parameterDeclaration.name), + parameterDeclaration.name, parameterDeclaration.questionToken && createToken(SyntaxKind.QuestionToken), parameterTypeNode, - parameterDeclaration.initializer && getSynthesizedDeepClone(parameterDeclaration.initializer)); + parameterDeclaration.initializer); return parameterNode; } - function signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node): SignatureDeclaration { - const typeParameters = signature.typeParameters && signature.typeParameters.map(parameter => createTypeParameterDeclarationFromType(parameter, enclosingDeclaration)); - const parameters = signature.parameters.map(parameter => createParameterDeclarationFromSymbol(parameter, enclosingDeclaration)); - const type = createTypeNodeExceptAny(getReturnTypeOfSignature(signature)); + function signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node): SignatureDeclaration { + const typeParameters = signature.typeParameters && signature.typeParameters.map(parameter => typeParameterToDeclaration(parameter, enclosingDeclaration)); + const parameters = signature.parameters.map(parameter => symbolToParameterDeclaration(parameter, enclosingDeclaration)); + const type = typeToTypeNodeExceptAny(getReturnTypeOfSignature(signature)); return createSignatureDeclaration(kind, typeParameters, parameters, type); - function createTypeNodeExceptAny(type: Type): TypeNode | undefined { + function typeToTypeNodeExceptAny(type: Type): TypeNode | undefined { const typeNode = typeToTypeNode(type, enclosingDeclaration); return typeNode && typeNode.kind !== SyntaxKind.AnyKeyword ? typeNode : undefined; } @@ -2236,17 +2237,17 @@ namespace ts { // function typeToDisplayParts - function typeToTypeNode(type: Type, enclosingDeclaration: Node, returnNodeOnError?: boolean): TypeNode { + function typeToTypeNode(type: Type, enclosingDeclaration?: Node, returnNodeOnError?: boolean): TypeNode { let encounteredError = false; let inObjectTypeLiteral = false; let checkAlias = true; let symbolStack: Symbol[] = undefined; - const result = createTypeNodeWorker(type); + const result = typeToTypeNodeWorker(type); // returnNodeOnError = true; // TODO: unset. return encounteredError && !returnNodeOnError ? undefined: result; - function createTypeNodeWorker(type: Type): TypeNode { + function typeToTypeNodeWorker(type: Type): TypeNode { if (!type) { encounteredError = true; return undefined; @@ -2308,7 +2309,7 @@ namespace ts { if (objectFlags & ObjectFlags.Reference) { Debug.assert(!!(type.flags & TypeFlags.Object)); - return createTypeReferenceNodeFromType(type); + return typeReferenceToTypeReferenceNode(type); } if (objectFlags & ObjectFlags.ClassOrInterface) { Debug.assert(!!(type.flags & TypeFlags.Object)); @@ -2347,25 +2348,25 @@ namespace ts { if (type.flags & TypeFlags.Index) { const indexedType = (type).type; - const indexTypeNode = createTypeNodeWorker(indexedType); + const indexTypeNode = typeToTypeNodeWorker(indexedType); return createTypeOperatorNode(indexTypeNode); } if (type.flags & TypeFlags.IndexedAccess) { - const objectTypeNode = createTypeNodeWorker((type).objectType); - const indexTypeNode = createTypeNodeWorker((type).indexType); + const objectTypeNode = typeToTypeNodeWorker((type).objectType); + const indexTypeNode = typeToTypeNodeWorker((type).indexType); return createIndexedAccessTypeNode(objectTypeNode, indexTypeNode); } Debug.fail("Should be unreachable."); function mapToTypeNodeArray(types: Type[]): NodeArray { - return types && asNodeArray(types.map(createTypeNodeWorker) as TypeNode[]); + return types && asNodeArray(types.map(typeToTypeNodeWorker) as TypeNode[]); } function createMappedTypeNodeFromType(type: MappedType) { Debug.assert(!!(type.flags & TypeFlags.Object)); const typeParameter = getTypeParameterFromMappedType(type); - const typeParameterNode = createTypeParameterDeclarationFromType(typeParameter, enclosingDeclaration); + const typeParameterNode = typeParameterToDeclaration(typeParameter, enclosingDeclaration); const templateTypeNode = typeToTypeNode(getTemplateTypeFromMappedType(type), enclosingDeclaration); const readonlyToken = (type).declaration && (type).declaration.readonlyToken ? createToken(SyntaxKind.ReadonlyKeyword) : undefined; @@ -2464,10 +2465,10 @@ namespace ts { } } - function createTypeReferenceNodeFromType(type: TypeReference) { + function typeReferenceToTypeReferenceNode(type: TypeReference) { const typeArguments: Type[] = type.typeArguments || emptyArray; if (type.target === globalArrayType) { - const elementType = createTypeNodeWorker(typeArguments[0]); + const elementType = typeToTypeNodeWorker(typeArguments[0]); return createArrayTypeNode(elementType); } else if (type.target.objectFlags & ObjectFlags.Tuple) { @@ -2489,21 +2490,20 @@ namespace ts { // When type parameters are their own type arguments for the whole group (i.e. we have // the default outer type arguments), we don't show the group. if (!rangeEquals(outerTypeParameters, typeArguments, start, i)) { - const name = createNameFromSymbol(parent); - const qualifiedNamePart = name; + const qualifiedNamePart = createNameFromSymbol(parent, /*mustBeIdentifier*/ true); if (!qualifiedName) { - qualifiedName = createQualifiedName(qualifiedNamePart, /*right*/undefined); + qualifiedName = createQualifiedName(qualifiedNamePart, /*right*/ undefined); } else { Debug.assert(!qualifiedName.right); qualifiedName.right = qualifiedNamePart; - qualifiedName = createQualifiedName(qualifiedName, /*right*/undefined); + qualifiedName = createQualifiedName(qualifiedName, /*right*/ undefined); } } } } let entityName: EntityName = undefined; - const nameIdentifier = createNameFromSymbol(type.symbol); + const nameIdentifier = createNameFromSymbol(type.symbol, /*mustBeIdentifier*/ true); if (qualifiedName) { Debug.assert(!qualifiedName.right); qualifiedName.right = nameIdentifier; @@ -2544,7 +2544,7 @@ namespace ts { if (!oldDeclaration) { return; } - const propertyName = getSynthesizedDeepClone(oldDeclaration.name); + const propertyName = oldDeclaration.name; const optionalToken = propertySymbol.flags & SymbolFlags.Optional ? createToken(SyntaxKind.QuestionToken) : undefined;; if (propertySymbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length) { const signatures = getSignaturesOfType(propertyType, SignatureKind.Call); @@ -2559,16 +2559,16 @@ namespace ts { typeElements.push(createPropertySignature( propertyName, optionalToken, - createTypeNodeWorker(propertyType), + typeToTypeNodeWorker(propertyType), /*initializer*/undefined)); } } return typeElements.length ? typeElements : undefined; } - function createNameFromSymbol(symbol: Symbol): Identifier; - function createNameFromSymbol(symbol: Symbol): EntityName; - function createNameFromSymbol(symbol: Symbol): EntityName { + function createNameFromSymbol(symbol: Symbol, mustBeIdentifier: true): Identifier; + function createNameFromSymbol(symbol: Symbol, mustBeIdentifier?: false): EntityName; + function createNameFromSymbol(symbol: Symbol, mustBeIdentifier: boolean | undefined): EntityName { let parentSymbol: Symbol; let meaning: SymbolFlags; @@ -2586,8 +2586,12 @@ namespace ts { } parentSymbol = undefined; - const result = createEntityNameFromSymbolChain(chain, chain.length - 1); - return result; + if(mustBeIdentifier && chain.length !== 1) { + encounteredError = true; + // TODO: failing to get an identifier when we expect one generates an unprintable node. + // Should error handling be more severe? + } + return createEntityNameFromSymbolChain(chain, chain.length - 1); function createEntityNameFromSymbolChain(chain: Symbol[], index: number): EntityName { Debug.assert(chain && 0 <= index && index < chain.length); diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index e60ed0009e..0ae4245970 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -67,15 +67,6 @@ namespace ts { return clone; } - /* @internal */ - export function getSynthesizedDeepClone(node: T | undefined): T { - if (node === undefined) { - return undefined; - } - const clone = visitEachChild(node, getSynthesizedDeepClone, nullTransformationContext); - return clone === node ? getSynthesizedClone(node) : clone; - } - // Literals export function createLiteral(value: string): StringLiteral; @@ -227,9 +218,7 @@ namespace ts { // Type Elements - export function createConstructSignature() { - throw new Error("not implemented."); - } + // TODO: add signatures // Types @@ -251,7 +240,7 @@ namespace ts { export function createTypeReferenceNode(typeName: string | EntityName, typeArguments: NodeArray | undefined) { const typeReference = createSynthesizedNode(SyntaxKind.TypeReference) as TypeReferenceNode; - typeReference.typeName = isQualifiedName(typeName) ? typeName : asName(typeName); + typeReference.typeName = asName(typeName); typeReference.typeArguments = typeArguments; return typeReference; } @@ -388,7 +377,7 @@ namespace ts { : node; } - // TODO: ask if we should have multiple implementations. Some T's can't have question token. + // TODO: Split according to AST nodes. export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined): T; export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined): T; export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, name?: string | PropertyName, questionToken?: QuestionToken): T { @@ -2030,7 +2019,8 @@ namespace ts { function asName(name: string | Identifier): Identifier; function asName(name: string | BindingName): BindingName; function asName(name: string | PropertyName): PropertyName; - function asName(name: string | Identifier | BindingName | PropertyName) { + function asName(name: string | EntityName): EntityName; + function asName(name: string | Identifier | BindingName | PropertyName | QualifiedName) { return typeof name === "string" ? createIdentifier(name) : name; } diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index bf706e7ded..4ef9fce067 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -31,7 +31,7 @@ namespace ts.codefix { return undefined; } - let typeNode: TypeNode = createKeywordTypeNode(SyntaxKind.AnyKeyword); + let typeNode: TypeNode; if (token.parent.parent.kind === SyntaxKind.BinaryExpression) { const binaryExpression = token.parent.parent as BinaryExpression; @@ -41,6 +41,8 @@ namespace ts.codefix { typeNode = checker.typeToTypeNode(widenedType, classDeclaration) || typeNode; } + typeNode = typeNode ? typeNode : createKeywordTypeNode(SyntaxKind.AnyKeyword); + const openBrace = getOpenBraceOfClassLike(classDeclaration, sourceFile); const property = createProperty( diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 3b4a75caa7..b3635f89f6 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -62,7 +62,7 @@ namespace ts.codefix { } const declaration = declarations[0] as Declaration; - const name = declaration.name ? getSynthesizedDeepClone(declaration.name) as PropertyName : undefined; + const name = declaration.name; const visibilityModifier = createVisibilityModifier(getModifierFlags(declaration)); const modifiers = visibilityModifier ? createNodeArray([visibilityModifier]) : undefined; const type = checker.getWidenedType(checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration)); diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index ddcbf2fa2f..cc304c0751 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -275,8 +275,8 @@ namespace ts.textChanges { /** * This function should be used to insert nodes in lists when nodes don't carry separators as the part of the node range, - * i.e. arguments in arguments lists, parameters in parameter lists etc. Statements or class elements are different in sense that - * for them separators are treated as the part of the node. + * i.e. arguments in arguments lists, parameters in parameter lists etc. + * Separators are treated as part of the node for statements and class elements. */ public insertNodeInListAfter(sourceFile: SourceFile, after: Node, newNode: Node) { const containingList = formatting.SmartIndenter.getContainingList(after, sourceFile); @@ -484,7 +484,7 @@ namespace ts.textChanges { private static normalize(changes: Change[]) { // order changes by start position const normalized = stableSort(changes, (a, b) => a.range.pos - b.range.pos); - // verify that end position of the change is less than start position of the next change + // verify that change intervals to not overlap, except possible at end points. for (let i = 0; i < normalized.length - 2; i++) { Debug.assert(normalized[i].range.end <= normalized[i + 1].range.pos); } From 11d1409f5fd07bd90e64e6128ef90171d2a5b099 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 22 Mar 2017 13:01:53 -0700 Subject: [PATCH 120/164] Format else clauses --- Jakefile.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Jakefile.js b/Jakefile.js index fa5aa141d6..fa4869c192 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -29,7 +29,8 @@ var thirdParty = "ThirdPartyNoticeText.txt"; var nodeModulesPathPrefix = path.resolve("./node_modules/.bin/") + path.delimiter; if (process.env.path !== undefined) { process.env.path = nodeModulesPathPrefix + process.env.path; -} else if (process.env.PATH !== undefined) { +} +else if (process.env.PATH !== undefined) { process.env.PATH = nodeModulesPathPrefix + process.env.PATH; } @@ -312,13 +313,15 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts if (useDebugMode) { if (opts.inlineSourceMap) { options += " --inlineSourceMap --inlineSources"; - } else { + } + else { options += " -sourcemap"; if (!opts.noMapRoot) { options += " -mapRoot file:///" + path.resolve(path.dirname(outFile)); } } - } else { + } + else { options += " --newLine LF"; } @@ -748,7 +751,8 @@ function exec(cmd, completeHandler, errorHandler) { ex.addListener("error", function (e, status) { if (errorHandler) { errorHandler(e, status); - } else { + } + else { fail("Process exited with code " + status); } }); @@ -1021,7 +1025,8 @@ function acceptBaseline(sourceFolder, targetFolder) { if (filename.substr(filename.length - deleteEnding.length) === deleteEnding) { filename = filename.substr(0, filename.length - deleteEnding.length); fs.unlinkSync(path.join(targetFolder, filename)); - } else { + } + else { var target = path.join(targetFolder, filename); if (fs.existsSync(target)) { fs.unlinkSync(target); From 2958649a9594641fe6d59f8342888372871405fa Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Wed, 22 Mar 2017 14:33:49 -0700 Subject: [PATCH 121/164] Enum and enum literal --- src/compiler/checker.ts | 6 ++++-- .../codeFixClassImplementInterfacePropertyEnum.ts | 13 +++++++++++++ ...FixClassImplementInterfacePropertyEnumLiteral.ts | 13 +++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 tests/cases/fourslash/codeFixClassImplementInterfacePropertyEnum.ts create mode 100644 tests/cases/fourslash/codeFixClassImplementInterfacePropertyEnumLiteral.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c4eaed3fde..2790d03934 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2266,7 +2266,8 @@ namespace ts { return createKeywordTypeNode(SyntaxKind.BooleanKeyword); } if (type.flags & TypeFlags.Enum) { - throw new Error ("enums not implemented") + const name = createNameFromSymbol(type.symbol); + return createTypeReferenceNode(name, /*typeArguments*/ undefined); } if (type.flags & (TypeFlags.StringLiteral)) { return createLiteralTypeNode((createLiteral((type).text))); @@ -2278,7 +2279,8 @@ namespace ts { return (type).intrinsicName === "true" ? createTrue() : createFalse(); } if (type.flags & TypeFlags.EnumLiteral) { - throw new Error("enum literal not implemented"); + const name = createNameFromSymbol(type.symbol); + return createTypeReferenceNode(name, /*typeArguments*/ undefined); } if (type.flags & TypeFlags.Void) { return createKeywordTypeNode(SyntaxKind.VoidKeyword); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfacePropertyEnum.ts b/tests/cases/fourslash/codeFixClassImplementInterfacePropertyEnum.ts new file mode 100644 index 0000000000..8b04e4a4b4 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterfacePropertyEnum.ts @@ -0,0 +1,13 @@ +/// + +// @lib: es2017 + +//// enum E { a,b,c } +//// interface I { +//// a: E; +//// } +//// class C implements I {[| |]} + +verify.rangeAfterCodeFix(` + a: E; +`); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixClassImplementInterfacePropertyEnumLiteral.ts b/tests/cases/fourslash/codeFixClassImplementInterfacePropertyEnumLiteral.ts new file mode 100644 index 0000000000..720acc1ccc --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterfacePropertyEnumLiteral.ts @@ -0,0 +1,13 @@ +/// + +// @lib: es2017 + +//// enum E { a,b,c } +//// interface I { +//// a: E.a +//// } +//// class C implements I {[| |]} + +verify.rangeAfterCodeFix(` + a: E.a; +`); \ No newline at end of file From 43e01f282b5172152a9b9c3cac2c5b058fa94a8e Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Wed, 22 Mar 2017 14:50:01 -0700 Subject: [PATCH 122/164] remove trivia --- src/compiler/checker.ts | 4 +-- src/services/codefixes/helpers.ts | 11 ++++++- ...assExtendAbstractMethodAnonymousClass.1.ts | 33 ------------------- .../codeFixClassImplementInterfaceComments.ts | 25 ++++++++++---- 4 files changed, 31 insertions(+), 42 deletions(-) delete mode 100644 tests/cases/fourslash/codeFixClassExtendAbstractMethodAnonymousClass.1.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2790d03934..b681d1298d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2208,13 +2208,13 @@ namespace ts { const parameterDeclaration = parameterSymbol.declarations[0] as ParameterDeclaration; const parameterType = getTypeOfSymbol(parameterSymbol); const parameterTypeNode = typeToTypeNode(parameterType, enclosingDeclaration); - // TODO: how should we clone members/modifiers? // TODO: check initializer accessibility correctly. const parameterNode = createParameter( parameterDeclaration.decorators, parameterDeclaration.modifiers, parameterDeclaration.dotDotDotToken && createToken(SyntaxKind.DotDotDotToken), - parameterDeclaration.name, + // Clone name to remove trivia. + getSynthesizedClone(parameterDeclaration.name), parameterDeclaration.questionToken && createToken(SyntaxKind.QuestionToken), parameterTypeNode, parameterDeclaration.initializer); diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index b3635f89f6..da72921508 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -62,7 +62,8 @@ namespace ts.codefix { } const declaration = declarations[0] as Declaration; - const name = declaration.name; + // Clone name to remove leading trivia. + const name = getSynthesizedClone(declaration.name); const visibilityModifier = createVisibilityModifier(getModifierFlags(declaration)); const modifiers = visibilityModifier ? createNodeArray([visibilityModifier]) : undefined; const type = checker.getWidenedType(checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration)); @@ -227,4 +228,12 @@ namespace ts.codefix { } return undefined; } + + function stripComments(node: Node): Node { + if(node === undefined) { + return node; + } + const strippedChildren = visitEachChild(node, stripComments, nullTransformationContext); + return strippedChildren === node ? getSynthesizedClone(strippedChildren) : strippedChildren; + } } \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractMethodAnonymousClass.1.ts b/tests/cases/fourslash/codeFixClassExtendAbstractMethodAnonymousClass.1.ts deleted file mode 100644 index 134ce17376..0000000000 --- a/tests/cases/fourslash/codeFixClassExtendAbstractMethodAnonymousClass.1.ts +++ /dev/null @@ -1,33 +0,0 @@ -/// - -class A { - foo() { - return class { x: number; } - } - bar() { - return new class { x: number; } - } -} -class B { - foo() { - return class { - x: X; - } - } -} - - -class D extends A { } - -verify.rangeAfterCodeFix(` - f(a: number, b: string): boolean; - f(a: number, b: string): this; - f(a: string, b: number): Function; - f(a: string): Function; - f(a: any, b?: any) { - throw new Error("Method not implemented."); - } - foo(): number { - throw new Error("Method not implemented."); - } -`); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceComments.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceComments.ts index 56d56a5a50..f082074f16 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceComments.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceComments.ts @@ -2,13 +2,26 @@ // @lib: es2017 -//// /** interface prefix */ -//// interface /**interface name prefix */ I /**open-brace prefix*/{ -//// /** property prefix*/ x /**colon prefix*/: /**number prefix*/ number; -//// +//// namespace N { +//// /**enum prefix */ +//// export enum /**enum identifier prefix */ E /**open-brace prefix*/ { +//// /* literal prefix */ a /** comma prefix */, +//// /* literal prefix */ b /** comma prefix */, +//// /* literal prefix */ c +//// /** close brace prefix */ } +//// /** interface prefix */ +//// export interface /**interface name prefix */ I /**open-brace prefix*/ { +//// /** property prefix */ a /** colon prefix */: /** enum literal prefix 1*/ E /** dot prefix */. /** enum literal prefix 2*/a; +//// /** property prefix */ b /** colon prefix */: /** enum prefix */ E; +//// /**method signature prefix */foo /**open angle prefix */< /**type parameter name prefix */ X /** closing angle prefix */> /**open paren prefix */(/** parameter prefix */ a/** colon prefix */: /** parameter type prefix */ X /** close paren prefix */) /** colon prefix */: /** return type prefix */ string /** semicolon prefix */; +//// /**close-brace prefix*/ } //// /**close-brace prefix*/ } -//// class C implements I {[| |]} +//// class C implements N.I {[| |]} verify.rangeAfterCodeFix(` - x: number; + a: N.E.a; + b: N.E; + foo(a: X): string { + throw new Error("Method not implemented."); + } `); From db6c96967cb856c6eeadae5b87ca34178664aca2 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 22 Mar 2017 16:23:21 -0700 Subject: [PATCH 123/164] Change ingore diagonstic comment to `// @ts-ignore` --- src/compiler/core.ts | 2 +- src/compiler/diagnosticMessages.json | 2 +- src/compiler/program.ts | 10 +++++----- src/harness/fourslash.ts | 2 +- src/services/codefixes/disableJsDiagnostics.ts | 16 ++++++++-------- src/services/codefixes/fixAddMissingMember.ts | 2 +- .../checkJsFiles_skipDiagnostics.symbols | 10 +++++----- .../reference/checkJsFiles_skipDiagnostics.types | 10 +++++----- .../Default initialized TSConfig/tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../compiler/checkJsFiles_skipDiagnostics.ts | 10 +++++----- .../codeFixDisableJsDiagnosticsInFile3.ts | 2 +- .../codeFixDisableJsDiagnosticsInFile4.ts | 2 +- .../codeFixDisableJsDiagnosticsInFile5.ts | 2 +- .../codeFixDisableJsDiagnosticsInFile6.ts | 2 +- .../codeFixDisableJsDiagnosticsInFile7.ts | 2 +- .../codeFixDisableJsDiagnosticsInFile8.ts | 2 +- 23 files changed, 46 insertions(+), 38 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 14aeb35dc8..a56f1004d2 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1,4 +1,4 @@ -/// +/// /// namespace ts { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 0aed8bf2be..983e128ec7 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3484,7 +3484,7 @@ "category": "Message", "code": 90018 }, - "Suppress this error message.": { + "Ignore this error message.": { "category": "Message", "code": 90019 }, diff --git a/src/compiler/program.ts b/src/compiler/program.ts index b4b93c0d21..31fc665649 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1,10 +1,10 @@ -/// +/// /// /// namespace ts { const emptyArray: any[] = []; - const suppressDiagnosticCommentRegEx = /(^\s*$)|(^\s*\/\/\/?\s*(@ts-suppress)?)/; + const ignoreDiagnosticCommentRegEx = /(^\s*$)|(^\s*\/\/\/?\s*(@ts-ignore)?)/; export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string { while (true) { @@ -926,7 +926,7 @@ namespace ts { } /** - * Skip errors if previous line start with '// @ts-suppress' comment, not counting non-empty non-comment lines + * Skip errors if previous line start with '// @ts-ignore' comment, not counting non-empty non-comment lines */ function shouldReportDiagnostic(diagnostic: Diagnostic) { const { file, start } = diagnostic; @@ -934,13 +934,13 @@ namespace ts { let { line } = computeLineAndCharacterOfPosition(lineStarts, start); while (line > 0) { const previousLineText = file.text.slice(lineStarts[line - 1], lineStarts[line]); - const result = suppressDiagnosticCommentRegEx.exec(previousLineText); + const result = ignoreDiagnosticCommentRegEx.exec(previousLineText); if (!result) { // non-empty line return true; } if (result[3]) { - // @ts-suppress + // @ts-ignore return false; } line--; diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 0285cdc51f..aa07407b0f 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1,4 +1,4 @@ -// +// // Copyright (c) Microsoft Corporation. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/services/codefixes/disableJsDiagnostics.ts b/src/services/codefixes/disableJsDiagnostics.ts index 621555cf84..7fa5c5bf23 100644 --- a/src/services/codefixes/disableJsDiagnostics.ts +++ b/src/services/codefixes/disableJsDiagnostics.ts @@ -1,4 +1,4 @@ -/* @internal */ +/* @internal */ namespace ts.codefix { registerCodeFix({ errorCodes: getApplicableDiagnosticCodes(), @@ -12,12 +12,12 @@ namespace ts.codefix { .map(d => allDiagnostcs[d].code); } - function getSuppressCommentLocationForLocation(sourceFile: SourceFile, position: number, newLineCharacter: string) { - let { line } = getLineAndCharacterOfPosition(sourceFile, position); + function getIgnoreCommentLocationForLocation(sourceFile: SourceFile, position: number, newLineCharacter: string) { + const { line } = getLineAndCharacterOfPosition(sourceFile, position); const lineStartPosition = getStartPositionOfLine(line, sourceFile); const startPosition = getFirstNonSpaceCharacterPosition(sourceFile.text, lineStartPosition); - // First try to see if we can put the '// @ts-suppress' on the previous line. + // First try to see if we can put the '// @ts-ignore' on the previous line. // We need to make sure that we are not in the middle of a string literal or a comment. // We also want to check if the previous line holds a comment for a node on the next line // if so, we do not want to separate the node from its comment if we can. @@ -27,7 +27,7 @@ namespace ts.codefix { if (!tokenLeadingCommnets || !tokenLeadingCommnets.length || tokenLeadingCommnets[0].pos >= startPosition) { return { span: { start: startPosition, length: 0 }, - newText: `// @ts-suppress${newLineCharacter}` + newText: `// @ts-ignore${newLineCharacter}` }; } } @@ -35,7 +35,7 @@ namespace ts.codefix { // If all fails, add an extra new line immediatlly before the error span. return { span: { start: position, length: 0 }, - newText: `${position === startPosition ? "" : newLineCharacter}// @ts-suppress${newLineCharacter}` + newText: `${position === startPosition ? "" : newLineCharacter}// @ts-ignore${newLineCharacter}` }; } @@ -47,10 +47,10 @@ namespace ts.codefix { } return [{ - description: getLocaleSpecificMessage(Diagnostics.Suppress_this_error_message), + description: getLocaleSpecificMessage(Diagnostics.Ignore_this_error_message), changes: [{ fileName: sourceFile.fileName, - textChanges: [getSuppressCommentLocationForLocation(sourceFile, span.start, newLineCharacter)] + textChanges: [getIgnoreCommentLocationForLocation(sourceFile, span.start, newLineCharacter)] }] }, { diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index 765ffa818b..1934de11f3 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -1,4 +1,4 @@ -/* @internal */ +/* @internal */ namespace ts.codefix { registerCodeFix({ errorCodes: [Diagnostics.Property_0_does_not_exist_on_type_1.code], diff --git a/tests/baselines/reference/checkJsFiles_skipDiagnostics.symbols b/tests/baselines/reference/checkJsFiles_skipDiagnostics.symbols index a0f2200048..eb2afaf436 100644 --- a/tests/baselines/reference/checkJsFiles_skipDiagnostics.symbols +++ b/tests/baselines/reference/checkJsFiles_skipDiagnostics.symbols @@ -4,15 +4,15 @@ var x = 0; >x : Symbol(x, Decl(a.js, 1, 3)) -/// @ts-suppress +/// @ts-ignore x(); >x : Symbol(x, Decl(a.js, 1, 3)) -/// @ts-suppress +/// @ts-ignore x(); >x : Symbol(x, Decl(a.js, 1, 3)) -/// @ts-suppress +/// @ts-ignore x( >x : Symbol(x, Decl(a.js, 1, 3)) @@ -21,7 +21,7 @@ x( -// @ts-suppress +// @ts-ignore // come comment // some other comment @@ -32,7 +32,7 @@ x(); -// @ts-suppress: no call signature +// @ts-ignore: no call signature x(); >x : Symbol(x, Decl(a.js, 1, 3)) diff --git a/tests/baselines/reference/checkJsFiles_skipDiagnostics.types b/tests/baselines/reference/checkJsFiles_skipDiagnostics.types index 69105a3112..aa24f1f054 100644 --- a/tests/baselines/reference/checkJsFiles_skipDiagnostics.types +++ b/tests/baselines/reference/checkJsFiles_skipDiagnostics.types @@ -5,17 +5,17 @@ var x = 0; >0 : 0 -/// @ts-suppress +/// @ts-ignore x(); >x() : any >x : number -/// @ts-suppress +/// @ts-ignore x(); >x() : any >x : number -/// @ts-suppress +/// @ts-ignore x( >x( 2, 3) : any >x : number @@ -28,7 +28,7 @@ x( -// @ts-suppress +// @ts-ignore // come comment // some other comment @@ -40,7 +40,7 @@ x(); -// @ts-suppress: no call signature +// @ts-ignore: no call signature x(); >x() : any >x : number diff --git a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json index 5918c273ce..97f59dea8e 100644 --- a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json @@ -5,6 +5,7 @@ "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ // "lib": [], /* Specify library files to be included in the compilation: */ // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ // "declaration": true, /* Generates corresponding '.d.ts' file. */ // "sourceMap": true, /* Generates corresponding '.map' file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json index 38c4542b40..b90e3fc6c5 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json @@ -5,6 +5,7 @@ "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ // "lib": [], /* Specify library files to be included in the compilation: */ // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ // "declaration": true, /* Generates corresponding '.d.ts' file. */ // "sourceMap": true, /* Generates corresponding '.map' file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json index d948b64815..482cfa6a9d 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json @@ -5,6 +5,7 @@ "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ // "lib": [], /* Specify library files to be included in the compilation: */ // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ "jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ // "declaration": true, /* Generates corresponding '.d.ts' file. */ // "sourceMap": true, /* Generates corresponding '.map' file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json index 70870f296e..c6a26629da 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json @@ -5,6 +5,7 @@ "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ // "lib": [], /* Specify library files to be included in the compilation: */ // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ // "declaration": true, /* Generates corresponding '.d.ts' file. */ // "sourceMap": true, /* Generates corresponding '.map' file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json index 3eabb0894f..72289dd178 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json @@ -5,6 +5,7 @@ "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ "lib": ["es5","es2015.promise"], /* Specify library files to be included in the compilation: */ // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ // "declaration": true, /* Generates corresponding '.d.ts' file. */ // "sourceMap": true, /* Generates corresponding '.map' file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json index 5918c273ce..97f59dea8e 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json @@ -5,6 +5,7 @@ "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ // "lib": [], /* Specify library files to be included in the compilation: */ // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ // "declaration": true, /* Generates corresponding '.d.ts' file. */ // "sourceMap": true, /* Generates corresponding '.map' file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json index b88ac604c1..1ac7c8c54d 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json @@ -5,6 +5,7 @@ "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ "lib": ["es5","es2015.core"], /* Specify library files to be included in the compilation: */ // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ // "declaration": true, /* Generates corresponding '.d.ts' file. */ // "sourceMap": true, /* Generates corresponding '.map' file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json index db838e21d2..33a9ecc5cd 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json @@ -5,6 +5,7 @@ "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ // "lib": [], /* Specify library files to be included in the compilation: */ // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ // "declaration": true, /* Generates corresponding '.d.ts' file. */ // "sourceMap": true, /* Generates corresponding '.map' file. */ diff --git a/tests/cases/compiler/checkJsFiles_skipDiagnostics.ts b/tests/cases/compiler/checkJsFiles_skipDiagnostics.ts index bcbcc815e7..48364c6a59 100644 --- a/tests/cases/compiler/checkJsFiles_skipDiagnostics.ts +++ b/tests/cases/compiler/checkJsFiles_skipDiagnostics.ts @@ -6,20 +6,20 @@ var x = 0; -/// @ts-suppress +/// @ts-ignore x(); -/// @ts-suppress +/// @ts-ignore x(); -/// @ts-suppress +/// @ts-ignore x( 2, 3); -// @ts-suppress +// @ts-ignore // come comment // some other comment @@ -29,5 +29,5 @@ x(); -// @ts-suppress: no call signature +// @ts-ignore: no call signature x(); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile3.ts b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile3.ts index f486a7e171..5cace44485 100644 --- a/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile3.ts +++ b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile3.ts @@ -10,5 +10,5 @@ // Disable checking for next line verify.rangeAfterCodeFix(`var x = ""; -// @ts-suppress +// @ts-ignore x = 1;`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); diff --git a/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile4.ts b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile4.ts index cadbda2c27..1319325a3d 100644 --- a/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile4.ts +++ b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile4.ts @@ -13,6 +13,6 @@ // Disable checking for next line verify.rangeAfterCodeFix(`"test \\ "; -// @ts-suppress +// @ts-ignore x = 1;`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); diff --git a/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile5.ts b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile5.ts index 56b9fbf20d..3a4b619a7f 100644 --- a/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile5.ts +++ b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile5.ts @@ -12,6 +12,6 @@ // Disable checking for next line verify.rangeAfterCodeFix(`/** comment */ -// @ts-suppress +// @ts-ignore x = 1;`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); diff --git a/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile6.ts b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile6.ts index a0497b4deb..5b93f4953d 100644 --- a/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile6.ts +++ b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile6.ts @@ -12,6 +12,6 @@ ////} // Disable checking for next line -verify.rangeAfterCodeFix(`// @ts-suppress +verify.rangeAfterCodeFix(`// @ts-ignore f(x());`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); diff --git a/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile7.ts b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile7.ts index ad8377e129..767fa98430 100644 --- a/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile7.ts +++ b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile7.ts @@ -12,6 +12,6 @@ ////} // Disable checking for next line -verify.rangeAfterCodeFix(`// @ts-suppress +verify.rangeAfterCodeFix(`// @ts-ignore x();`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); diff --git a/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile8.ts b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile8.ts index 8ec350479a..3df5864f19 100644 --- a/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile8.ts +++ b/tests/cases/fourslash/codeFixDisableJsDiagnosticsInFile8.ts @@ -14,6 +14,6 @@ // Disable checking for next line verify.rangeAfterCodeFix(`f( - // @ts-suppress + // @ts-ignore x());`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); From abd14ef18586c91c1d08c7fd87e0a82b4746e9fc Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Wed, 22 Mar 2017 19:10:56 -0700 Subject: [PATCH 124/164] temp --- src/compiler/checker.ts | 955 +++++++++++++++++++++------------------- src/compiler/types.ts | 20 +- 2 files changed, 510 insertions(+), 465 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b681d1298d..e004a0ca39 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -61,6 +61,7 @@ namespace ts { const noImplicitThis = compilerOptions.noImplicitThis === undefined ? compilerOptions.strict : compilerOptions.noImplicitThis; const emitResolver = createResolver(); + let nodeBuilderCache: NodeBuilder | undefined; const undefinedSymbol = createSymbol(SymbolFlags.Property, "undefined"); undefinedSymbol.declarations = []; @@ -106,9 +107,9 @@ namespace ts { getParameterType: getTypeAtPosition, getReturnTypeOfSignature, getNonNullableType, - typeToTypeNode, - indexInfoToIndexSignatureDeclaration, - signatureToSignatureDeclaration, + typeToTypeNode: getNodeBuilder().typeToTypeNode, + indexInfoToIndexSignatureDeclaration: getNodeBuilder().indexInfoToIndexSignatureDeclaration, + signatureToSignatureDeclaration: getNodeBuilder().signatureToSignatureDeclaration, getSymbolsInScope: (location, meaning) => { location = getParseTreeNode(location); return location ? getSymbolsInScope(location, meaning) : []; @@ -2191,476 +2192,526 @@ namespace ts { return result; } - function typeParameterToDeclaration(type: TypeParameter, enclosingDeclaration?: Node): TypeParameterDeclaration { - if (!(type && type.symbol && type.flags & TypeFlags.TypeParameter)) { - return undefined; + function unwrapNodeBuilderResult(result: NodeBuilderResult, returnValueOnError: boolean): T | undefined { + return !result.error || returnValueOnError ? result.value : undefined; + } + + function getNodeBuilder(): NodeBuilder { + if (nodeBuilderCache) { + return nodeBuilderCache; } - const constraint = typeToTypeNode(getConstraintFromTypeParameter(type), enclosingDeclaration); - const defaultParameter = typeToTypeNode(getDefaultFromTypeParameter(type), enclosingDeclaration); - - // TODO: use method internal to typeToTypeNode. - const name = symbolToString(type.symbol); - return createTypeParameterDeclaration(name, constraint, defaultParameter); - } - - function symbolToParameterDeclaration(parameterSymbol: Symbol, enclosingDeclaration?: Node): ParameterDeclaration { - const parameterDeclaration = parameterSymbol.declarations[0] as ParameterDeclaration; - const parameterType = getTypeOfSymbol(parameterSymbol); - const parameterTypeNode = typeToTypeNode(parameterType, enclosingDeclaration); - // TODO: check initializer accessibility correctly. - const parameterNode = createParameter( - parameterDeclaration.decorators, - parameterDeclaration.modifiers, - parameterDeclaration.dotDotDotToken && createToken(SyntaxKind.DotDotDotToken), - // Clone name to remove trivia. - getSynthesizedClone(parameterDeclaration.name), - parameterDeclaration.questionToken && createToken(SyntaxKind.QuestionToken), - parameterTypeNode, - parameterDeclaration.initializer); - return parameterNode; - } - - function signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node): SignatureDeclaration { - const typeParameters = signature.typeParameters && signature.typeParameters.map(parameter => typeParameterToDeclaration(parameter, enclosingDeclaration)); - const parameters = signature.parameters.map(parameter => symbolToParameterDeclaration(parameter, enclosingDeclaration)); - const type = typeToTypeNodeExceptAny(getReturnTypeOfSignature(signature)); - - return createSignatureDeclaration(kind, typeParameters, parameters, type); - - function typeToTypeNodeExceptAny(type: Type): TypeNode | undefined { - const typeNode = typeToTypeNode(type, enclosingDeclaration); - return typeNode && typeNode.kind !== SyntaxKind.AnyKeyword ? typeNode : undefined; - } - } - - - // function typeToDisplayParts - - function typeToTypeNode(type: Type, enclosingDeclaration?: Node, returnNodeOnError?: boolean): TypeNode { let encounteredError = false; - let inObjectTypeLiteral = false; - let checkAlias = true; - let symbolStack: Symbol[] = undefined; + nodeBuilderCache = { + typeToTypeNode, + indexInfoToIndexSignatureDeclaration, + signatureToSignatureDeclaration + } - const result = typeToTypeNodeWorker(type); - // returnNodeOnError = true; // TODO: unset. - return encounteredError && !returnNodeOnError ? undefined: result; + return nodeBuilderCache; - function typeToTypeNodeWorker(type: Type): TypeNode { - if (!type) { - encounteredError = true; + function typeToTypeNode(type: Type, enclosingDeclaration?: Node, emitNodeOnError?: boolean): NodeBuilderResult { + let toNodeEncounteredErrorCache = encounteredError; + encounteredError = false; + let inObjectTypeLiteral = false; + let checkAlias = true; + let symbolStack: Symbol[] = undefined; + + const resultingNode = typeToTypeNodeWorker(type); + const result = encounteredError && !emitNodeOnError ? undefined : resultingNode; + encounteredError = toNodeEncounteredErrorCache; + return result; + + function typeToTypeNodeWorker(type: Type): NodeBuilderResult { + if (!type) { + encounteredError = true; + return undefined; + } + + if (type.flags & TypeFlags.Any) { + return createKeywordTypeNode(SyntaxKind.AnyKeyword); + } + if (type.flags & TypeFlags.String) { + return createKeywordTypeNode(SyntaxKind.StringKeyword); + } + if (type.flags & TypeFlags.Number) { + return createKeywordTypeNode(SyntaxKind.NumberKeyword); + } + if (type.flags & TypeFlags.Boolean) { + return createKeywordTypeNode(SyntaxKind.BooleanKeyword); + } + if (type.flags & TypeFlags.Enum) { + const name = symbolToName(type.symbol, enclosingDeclaration); + return createTypeReferenceNode(name, /*typeArguments*/ undefined); + } + if (type.flags & (TypeFlags.StringLiteral)) { + return createLiteralTypeNode((createLiteral((type).text))); + } + if (type.flags & (TypeFlags.NumberLiteral)) { + return createLiteralTypeNode((createNumericLiteral((type).text))); + } + if (type.flags & TypeFlags.BooleanLiteral) { + return (type).intrinsicName === "true" ? createTrue() : createFalse(); + } + if (type.flags & TypeFlags.EnumLiteral) { + const name = symbolToName(type.symbol, enclosingDeclaration); + return createTypeReferenceNode(name, /*typeArguments*/ undefined); + } + if (type.flags & TypeFlags.Void) { + return createKeywordTypeNode(SyntaxKind.VoidKeyword); + } + if (type.flags & TypeFlags.Undefined) { + return createKeywordTypeNode(SyntaxKind.UndefinedKeyword); + } + if (type.flags & TypeFlags.Null) { + return createKeywordTypeNode(SyntaxKind.NullKeyword); + } + if (type.flags & TypeFlags.Never) { + return createKeywordTypeNode(SyntaxKind.NeverKeyword); + } + if (type.flags & TypeFlags.ESSymbol) { + throw new Error("ESSymbol not implemented"); + } + if (type.flags & TypeFlags.NonPrimitive) { + throw new Error("Non primitive not implemented"); + } + if (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType) { + if (inObjectTypeLiteral) { + encounteredError = true; + } + return createThis(); + } + + const objectFlags = getObjectFlags(type); + + if (objectFlags & ObjectFlags.Reference) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + return typeReferenceToTypeReferenceNode(type); + } + if (objectFlags & ObjectFlags.ClassOrInterface) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + const name = symbolToName(type.symbol, enclosingDeclaration); + // TODO(aozgaa): handle type arguments. + return createTypeReferenceNode(name, /*typeArguments*/ undefined); + } + if (type.flags & TypeFlags.TypeParameter) { + const name = symbolToName(type.symbol, enclosingDeclaration); + // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. + return createTypeReferenceNode(name, /*typeArguments*/ undefined); + } + + if (checkAlias && type.aliasSymbol) { + const name = symbolToName(type.aliasSymbol, enclosingDeclaration); + const typeArgumentNodes = mapToTypeNodeArray(type.aliasTypeArguments); + return createTypeReferenceNode(name, typeArgumentNodes); + } + checkAlias = false; + + if (type.flags & TypeFlags.Union) { + return createUnionOrIntersectionTypeNode(SyntaxKind.UnionType, mapToTypeNodeArray(formatUnionTypes((type).types))); + } + + if (type.flags & TypeFlags.Intersection) { + return createUnionOrIntersectionTypeNode(SyntaxKind.IntersectionType, mapToTypeNodeArray((type as UnionType).types)); + } + + if (objectFlags & (ObjectFlags.Anonymous | ObjectFlags.Mapped)) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + // The type is an object literal type. + return createAnonymousTypeNode(type); + } + + if (type.flags & TypeFlags.Index) { + const indexedType = (type).type; + const indexTypeNode = typeToTypeNodeWorker(indexedType); + return createTypeOperatorNode(indexTypeNode); + } + if (type.flags & TypeFlags.IndexedAccess) { + const objectTypeNode = typeToTypeNodeWorker((type).objectType); + const indexTypeNode = typeToTypeNodeWorker((type).indexType); + return createIndexedAccessTypeNode(objectTypeNode, indexTypeNode); + } + + Debug.fail("Should be unreachable."); + + function mapToTypeNodeArray(types: Type[]): NodeArray { + return types && asNodeArray(types.map(typeToTypeNodeWorker) as TypeNode[]); + } + + function createMappedTypeNodeFromType(type: MappedType) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + const typeParameter = getTypeParameterFromMappedType(type); + const typeParameterNode = typeParameterToDeclaration(typeParameter, enclosingDeclaration); + + const templateTypeNode = typeToTypeNodeWorker(getTemplateTypeFromMappedType(type)); + const readonlyToken = (type).declaration && (type).declaration.readonlyToken ? createToken(SyntaxKind.ReadonlyKeyword) : undefined; + const questionToken = (type).declaration && (type).declaration.questionToken ? createToken(SyntaxKind.QuestionToken) : undefined; + + return createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode); + } + + function createAnonymousTypeNode(type: ObjectType): TypeNode { + const symbol = type.symbol; + if (symbol) { + // Always use 'typeof T' for type of class, enum, and module objects + if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) || + symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule) || + shouldWriteTypeOfFunctionSymbol()) { + return createTypeQueryNodeFromType(type); + } + else if (contains(symbolStack, symbol)) { + // If type is an anonymous type literal in a type alias declaration, use type alias name + const typeAlias = getTypeAliasForTypeLiteral(type); + if (typeAlias) { + // The specified symbol flags need to be reinterpreted as type flags + const entityName = symbolToName(typeAlias, enclosingDeclaration); + return createTypeReferenceNode(entityName, /*typeArguments*/ undefined); + } + else { + return createKeywordTypeNode(SyntaxKind.AnyKeyword); + } + } + else { + // Since instantiations of the same anonymous type have the same symbol, tracking symbols instead + // of types allows us to catch circular references to instantiations of the same anonymous type + if (!symbolStack) { + symbolStack = []; + } + symbolStack.push(symbol); + let result = createTypeNodeFromObjectType(type); + symbolStack.pop(); + return result; + } + } + else { + // Anonymous types without a symbol are never circular. + return createTypeNodeFromObjectType(type); + } + + function shouldWriteTypeOfFunctionSymbol() { + const isStaticMethodSymbol = !!(symbol.flags & SymbolFlags.Method && // typeof static method + forEach(symbol.declarations, declaration => getModifierFlags(declaration) & ModifierFlags.Static)); + const isNonLocalFunctionSymbol = !!(symbol.flags & SymbolFlags.Function) && + (symbol.parent || // is exported function symbol + forEach(symbol.declarations, declaration => + declaration.parent.kind === SyntaxKind.SourceFile || declaration.parent.kind === SyntaxKind.ModuleBlock)); + if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { + // typeof is allowed only for static/non local functions + return contains(symbolStack, symbol); // it is type of the symbol uses itself recursively + } + } + } + + function createTypeNodeFromObjectType(type: ObjectType): TypeNode { + if (type.objectFlags & ObjectFlags.Mapped) { + if (getConstraintTypeFromMappedType(type).flags & (TypeFlags.TypeParameter | TypeFlags.Index)) { + return createMappedTypeNodeFromType(type); + } + } + + const resolved = resolveStructuredTypeMembers(type); + if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { + if (!resolved.callSignatures.length && !resolved.constructSignatures.length) { + return createTypeLiteralNode(/*members*/ undefined); + } + + if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) { + const signature = resolved.callSignatures[0]; + return signatureToSignatureDeclaration(signature, SyntaxKind.FunctionType, enclosingDeclaration, emitNodeOnError); + } + if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) { + const signature = resolved.constructSignatures[0]; + return signatureToSignatureDeclaration(signature, SyntaxKind.ConstructorType, enclosingDeclaration, emitNodeOnError); + } + } + + const saveInObjectTypeLiteral = inObjectTypeLiteral; + inObjectTypeLiteral = true; + const members = createTypeNodesFromResolvedType(resolved); + inObjectTypeLiteral = saveInObjectTypeLiteral; + return createTypeLiteralNode(members); + } + + function createTypeQueryNodeFromType(type: Type) { + const symbol = type.symbol; + if (symbol) { + const entityName = symbolToName(symbol, enclosingDeclaration); + return createTypeQueryNode(entityName); + } + } + + function typeReferenceToTypeReferenceNode(type: TypeReference) { + const typeArguments: Type[] = type.typeArguments || emptyArray; + if (type.target === globalArrayType) { + const elementType = typeToTypeNodeWorker(typeArguments[0]); + return createArrayTypeNode(elementType); + } + else if (type.target.objectFlags & ObjectFlags.Tuple) { + return createTupleTypeNode(typeArguments.length > 0 ? mapToTypeNodeArray(typeArguments.slice(0, getTypeReferenceArity(type))) : undefined); + } + else { + const outerTypeParameters = type.target.outerTypeParameters; + let i = 0; + let qualifiedName: QualifiedName | undefined = undefined; + if (outerTypeParameters) { + const length = outerTypeParameters.length; + while (i < length) { + // Find group of type arguments for type parameters with the same declaring container. + const start = i; + const parent = getParentSymbolOfTypeParameter(outerTypeParameters[i]); + do { + i++; + } while (i < length && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent); + // When type parameters are their own type arguments for the whole group (i.e. we have + // the default outer type arguments), we don't show the group. + if (!rangeEquals(outerTypeParameters, typeArguments, start, i)) { + const qualifiedNamePart = symbolToName(parent, enclosingDeclaration, /*mustBeIdentifier*/ true); + if (!qualifiedName) { + qualifiedName = createQualifiedName(qualifiedNamePart, /*right*/ undefined); + } + else { + Debug.assert(!qualifiedName.right); + qualifiedName.right = qualifiedNamePart; + qualifiedName = createQualifiedName(qualifiedName, /*right*/ undefined); + } + } + } + } + let entityName: EntityName = undefined; + const nameIdentifier = symbolToName(type.symbol, enclosingDeclaration, /*mustBeIdentifier*/ true); + if (qualifiedName) { + Debug.assert(!qualifiedName.right); + qualifiedName.right = nameIdentifier; + entityName = qualifiedName; + } + else { + entityName = nameIdentifier; + } + const typeParameterCount = (type.target.typeParameters || emptyArray).length; + const typeArgumentNodes = mapToTypeNodeArray(typeArguments.length > 0 ? typeArguments.slice(i, typeParameterCount - i) : undefined); + return createTypeReferenceNode(entityName, typeArgumentNodes); + } + } + + function createTypeNodesFromResolvedType(resolvedType: ResolvedType): TypeElement[] { + const typeElements: TypeElement[] = []; + for (const signature of resolvedType.callSignatures) { + typeElements.push(signatureToSignatureDeclaration(signature, SyntaxKind.CallSignature, enclosingDeclaration, emitNodeOnError)); + } + for (const signature of resolvedType.constructSignatures) { + typeElements.push(signatureToSignatureDeclaration(signature, SyntaxKind.ConstructSignature, enclosingDeclaration, emitNodeOnError)); + } + if (resolvedType.stringIndexInfo) { + typeElements.push(indexInfoToIndexSignatureDeclaration(resolvedType.stringIndexInfo, IndexKind.String, enclosingDeclaration, emitNodeOnError)); + } + if (resolvedType.numberIndexInfo) { + typeElements.push(indexInfoToIndexSignatureDeclaration(resolvedType.numberIndexInfo, IndexKind.Number, enclosingDeclaration, emitNodeOnError)); + } + + const properties = resolvedType.properties; + if (!properties) { + return typeElements; + } + + for (const propertySymbol of properties) { + const propertyType = getTypeOfSymbol(propertySymbol); + const oldDeclaration = propertySymbol.declarations && propertySymbol.declarations[0] as TypeElement; + if (!oldDeclaration) { + return; + } + const propertyName = oldDeclaration.name; + const optionalToken = propertySymbol.flags & SymbolFlags.Optional ? createToken(SyntaxKind.QuestionToken) : undefined;; + if (propertySymbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length) { + const signatures = getSignaturesOfType(propertyType, SignatureKind.Call); + for (const signature of signatures) { + const methodDeclaration = signatureToSignatureDeclaration(signature, SyntaxKind.MethodSignature, enclosingDeclaration, emitNodeOnError); + methodDeclaration.name = propertyName; + methodDeclaration.questionToken = optionalToken; + typeElements.push(methodDeclaration); + } + } + else { + typeElements.push(createPropertySignature( + propertyName, + optionalToken, + typeToTypeNodeWorker(propertyType), + /*initializer*/undefined)); + } + } + return typeElements.length ? typeElements : undefined; + } + } + } + + function indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node, emitNodeOnError?: boolean): IndexSignatureDeclaration { + const encounteredErrorCache = encounteredError; + encounteredError = false; + + const indexerTypeNode = createKeywordTypeNode(kind === IndexKind.String ? SyntaxKind.StringKeyword : SyntaxKind.NumberKeyword); + + const name = getNameFromIndexInfo(indexInfo); + const indexingParameter = createParameter( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, + name, + /*questionToken*/ undefined, + indexerTypeNode, + /*initializer*/ undefined); + const typeNode = typeToTypeNode(indexInfo.type, enclosingDeclaration, emitNodeOnError); + const result = !encounteredError || emitNodeOnError ? createIndexSignatureDeclaration( + [indexingParameter], + typeNode, + /*decorators*/ undefined, + indexInfo.isReadonly ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined) + : undefined; + encounteredError = encounteredErrorCache; + return result; + } + + function signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, emitNodeOnError?: boolean): SignatureDeclaration { + const encounteredErrorCache = encounteredError; + encounteredError = false; + + const typeParameters = signature.typeParameters && signature.typeParameters.map(parameter => typeParameterToDeclaration(parameter, enclosingDeclaration)); + const parameters = signature.parameters.map(parameter => symbolToParameterDeclaration(parameter, enclosingDeclaration)); + const type = typeToTypeNodeExceptAny(getReturnTypeOfSignature(signature)); + + const result = !encounteredError || emitNodeOnError ? createSignatureDeclaration(kind, typeParameters, parameters, type) : undefined; + encounteredError = encounteredErrorCache; + return result; + + function typeToTypeNodeExceptAny(type: Type): TypeNode | undefined { + const typeNode = typeToTypeNode(type, enclosingDeclaration, emitNodeOnError); + return typeNode && typeNode.kind !== SyntaxKind.AnyKeyword ? typeNode : undefined; + } + } + + function typeParameterToDeclaration(type: TypeParameter, enclosingDeclaration?: Node, returnNodeOnError?: boolean): TypeParameterDeclaration { + if (!(type && type.symbol && type.flags & TypeFlags.TypeParameter)) { return undefined; } - if (type.flags & TypeFlags.Any) { - return createKeywordTypeNode(SyntaxKind.AnyKeyword); + const constraint = typeToTypeNode(getConstraintFromTypeParameter(type), enclosingDeclaration); + const defaultParameter = typeToTypeNode(getDefaultFromTypeParameter(type), enclosingDeclaration); + + let toNodeEncounteredErrorCache = encounteredError; + encounteredError = false; + const name = symbolToName(type.symbol, enclosingDeclaration, /*mustBeIdentifier*/ true); + let result = encounteredError && !returnNodeOnError ? undefined : createTypeParameterDeclaration(name, constraint, defaultParameter); + encounteredError = toNodeEncounteredErrorCache; + return result; + } + + function symbolToParameterDeclaration(parameterSymbol: Symbol, enclosingDeclaration?: Node): ParameterDeclaration { + const parameterDeclaration = parameterSymbol.declarations[0] as ParameterDeclaration; + const parameterType = getTypeOfSymbol(parameterSymbol); + const parameterTypeNode = typeToTypeNode(parameterType, enclosingDeclaration); + // TODO(aozgaa): check initializer accessibility correctly. + const parameterNode = createParameter( + parameterDeclaration.decorators, + parameterDeclaration.modifiers, + parameterDeclaration.dotDotDotToken && createToken(SyntaxKind.DotDotDotToken), + // Clone name to remove trivia. + getSynthesizedClone(parameterDeclaration.name), + parameterDeclaration.questionToken && createToken(SyntaxKind.QuestionToken), + parameterTypeNode, + parameterDeclaration.initializer); + return parameterNode; + } + + function symbolToName(symbol: Symbol, enclosingDeclaration: Node | undefined, mustBeIdentifier: true): Identifier; + function symbolToName(symbol: Symbol, enclosingDeclaration?: Node, mustBeIdentifier?: false): EntityName; + function symbolToName(symbol: Symbol, enclosingDeclaration: Node | undefined, mustBeIdentifier: boolean | undefined): EntityName { + let parentSymbol: Symbol; + let meaning: SymbolFlags; + + // Get qualified name if the symbol is not a type parameter + // and there is an enclosing declaration. + let chain: Symbol[]; + const isTypeParameter = symbol.flags & SymbolFlags.TypeParameter; + if (!isTypeParameter && enclosingDeclaration) { + chain = getSymbolChain(symbol, meaning, /*endOfChain*/ true); + // TODO: check whether type pointed to by symbol requires type arguments to be printed. + Debug.assert(chain && chain.length > 0); } - if (type.flags & TypeFlags.String) { - return createKeywordTypeNode(SyntaxKind.StringKeyword); - } - if (type.flags & TypeFlags.Number) { - return createKeywordTypeNode(SyntaxKind.NumberKeyword); - } - if(type.flags & TypeFlags.Boolean) { - return createKeywordTypeNode(SyntaxKind.BooleanKeyword); - } - if (type.flags & TypeFlags.Enum) { - const name = createNameFromSymbol(type.symbol); - return createTypeReferenceNode(name, /*typeArguments*/ undefined); - } - if (type.flags & (TypeFlags.StringLiteral)) { - return createLiteralTypeNode((createLiteral((type).text))); - } - if (type.flags & (TypeFlags.NumberLiteral)) { - return createLiteralTypeNode((createNumericLiteral((type).text))); - } - if(type.flags & TypeFlags.BooleanLiteral) { - return (type).intrinsicName === "true" ? createTrue() : createFalse(); - } - if (type.flags & TypeFlags.EnumLiteral) { - const name = createNameFromSymbol(type.symbol); - return createTypeReferenceNode(name, /*typeArguments*/ undefined); - } - if (type.flags & TypeFlags.Void) { - return createKeywordTypeNode(SyntaxKind.VoidKeyword); - } - if (type.flags & TypeFlags.Undefined) { - return createKeywordTypeNode(SyntaxKind.UndefinedKeyword); - } - if (type.flags & TypeFlags.Null) { - return createKeywordTypeNode(SyntaxKind.NullKeyword); - } - if (type.flags & TypeFlags.Never) { - return createKeywordTypeNode(SyntaxKind.NeverKeyword); - } - if (type.flags & TypeFlags.ESSymbol) { - throw new Error("ESSymbol not implemented"); - } - if (type.flags & TypeFlags.NonPrimitive) { - throw new Error("Non primitive not implemented"); - } - if (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType) { - if (inObjectTypeLiteral) { - encounteredError = true; - } - return createThis(); + else { + chain = [symbol]; } - const objectFlags = getObjectFlags(type); - - if (objectFlags & ObjectFlags.Reference) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - return typeReferenceToTypeReferenceNode(type); - } - if (objectFlags & ObjectFlags.ClassOrInterface) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - const name = createNameFromSymbol(type.symbol); - // TODO: handle type arguments. - return createTypeReferenceNode(name, /*typeArguments*/ undefined); - } - if (type.flags & TypeFlags.TypeParameter) { - const name = createNameFromSymbol(type.symbol); - // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. - return createTypeReferenceNode(name, /*typeArguments*/ undefined); + parentSymbol = undefined; + if (mustBeIdentifier && chain.length !== 1) { + encounteredError = true; + // TODO: failing to get an identifier when we expect one generates an unprintable node. + // Should error handling be more severe? } + return createEntityNameFromSymbolChain(chain, chain.length - 1); - if (checkAlias && type.aliasSymbol) { - const name = createNameFromSymbol(type.aliasSymbol); - const typeArgumentNodes = mapToTypeNodeArray(type.aliasTypeArguments); - return createTypeReferenceNode(name, typeArgumentNodes); - } - checkAlias = false; - - if (type.flags & TypeFlags.Union) { - return createUnionOrIntersectionTypeNode(SyntaxKind.UnionType, mapToTypeNodeArray(formatUnionTypes((type).types))); - } - - if (type.flags & TypeFlags.Intersection) { - return createUnionOrIntersectionTypeNode(SyntaxKind.IntersectionType, mapToTypeNodeArray((type as UnionType).types)); - } - - if (objectFlags & (ObjectFlags.Anonymous | ObjectFlags.Mapped)) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - // The type is an object literal type. - return createAnonymousTypeNode(type); - } - - // TODO (aozgaa): implement string and number literals here once there is a testable case. - - if (type.flags & TypeFlags.Index) { - const indexedType = (type).type; - const indexTypeNode = typeToTypeNodeWorker(indexedType); - return createTypeOperatorNode(indexTypeNode); - } - if (type.flags & TypeFlags.IndexedAccess) { - const objectTypeNode = typeToTypeNodeWorker((type).objectType); - const indexTypeNode = typeToTypeNodeWorker((type).indexType); - return createIndexedAccessTypeNode(objectTypeNode, indexTypeNode); - } - - Debug.fail("Should be unreachable."); - - function mapToTypeNodeArray(types: Type[]): NodeArray { - return types && asNodeArray(types.map(typeToTypeNodeWorker) as TypeNode[]); - } - - function createMappedTypeNodeFromType(type: MappedType) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - const typeParameter = getTypeParameterFromMappedType(type); - const typeParameterNode = typeParameterToDeclaration(typeParameter, enclosingDeclaration); - - const templateTypeNode = typeToTypeNode(getTemplateTypeFromMappedType(type), enclosingDeclaration); - const readonlyToken = (type).declaration && (type).declaration.readonlyToken ? createToken(SyntaxKind.ReadonlyKeyword) : undefined; - const questionToken = (type).declaration && (type).declaration.questionToken ? createToken(SyntaxKind.QuestionToken) : undefined; - - return createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode); - } - - function createAnonymousTypeNode(type: ObjectType): TypeNode { - const symbol = type.symbol; - if (symbol) { - // Always use 'typeof T' for type of class, enum, and module objects - if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) || - symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule) || - shouldWriteTypeOfFunctionSymbol()) { - return createTypeQueryNodeFromType(type); - } - else if (contains(symbolStack, symbol)) { - // If type is an anonymous type literal in a type alias declaration, use type alias name - const typeAlias = getTypeAliasForTypeLiteral(type); - if (typeAlias) { - // The specified symbol flags need to be reinterpreted as type flags - const entityName = createNameFromSymbol(typeAlias); - return createTypeReferenceNode(entityName, /*typeArguments*/ undefined); - } - else { - return createKeywordTypeNode(SyntaxKind.AnyKeyword); - } + function createEntityNameFromSymbolChain(chain: Symbol[], index: number): EntityName { + Debug.assert(chain && 0 <= index && index < chain.length); + // const parentIndex = index - 1; + const symbol = chain[index]; + let typeParameterString = ""; + if (index > 0) { + // TODO: is the parentSymbol wrong? + const parentSymbol = chain[index - 1]; + let typeParameters: TypeParameter[]; + if (getCheckFlags(symbol) & CheckFlags.Instantiated) { + typeParameters = getTypeParametersOfClassOrInterface(parentSymbol); } else { - // Since instantiations of the same anonymous type have the same symbol, tracking symbols instead - // of types allows us to catch circular references to instantiations of the same anonymous type - if (!symbolStack) { - symbolStack = []; + const targetSymbol = getTargetSymbol(parentSymbol); + if (targetSymbol.flags & (SymbolFlags.Class | SymbolFlags.Interface | SymbolFlags.TypeAlias)) { + typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); } - symbolStack.push(symbol); - let result = createTypeNodeFromObjectType(type); - symbolStack.pop(); - return result; } - } - else { - // Anonymous types without a symbol are never circular. - return createTypeNodeFromObjectType(type); - } + if (typeParameters && typeParameters.length > 0) { + encounteredError = true; + const writer = getSingleLineStringWriter(); + const displayBuilder = getSymbolDisplayBuilder(); + displayBuilder.buildDisplayForTypeParametersAndDelimiters(typeParameters, writer, enclosingDeclaration, 0); + typeParameterString = writer.string(); + releaseStringWriter(writer); - function shouldWriteTypeOfFunctionSymbol() { - const isStaticMethodSymbol = !!(symbol.flags & SymbolFlags.Method && // typeof static method - forEach(symbol.declarations, declaration => getModifierFlags(declaration) & ModifierFlags.Static)); - const isNonLocalFunctionSymbol = !!(symbol.flags & SymbolFlags.Function) && - (symbol.parent || // is exported function symbol - forEach(symbol.declarations, declaration => - declaration.parent.kind === SyntaxKind.SourceFile || declaration.parent.kind === SyntaxKind.ModuleBlock)); - if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { - // typeof is allowed only for static/non local functions - return contains(symbolStack, symbol); // it is type of the symbol uses itself recursively } } + const symbolName = getNameOfSymbol(symbol); + const symbolNameWithTypeParameters = typeParameterString.length > 0 ? `${symbolName}<${typeParameterString}>` : symbolName; + let identifier = createIdentifier(symbolNameWithTypeParameters); + + return index > 0 ? createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier; } - function createTypeNodeFromObjectType(type: ObjectType): TypeNode { - if (type.objectFlags & ObjectFlags.Mapped) { - if (getConstraintTypeFromMappedType(type).flags & (TypeFlags.TypeParameter | TypeFlags.Index)) { - return createMappedTypeNodeFromType(type); - } - } + /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */ + function getSymbolChain(symbol: Symbol, meaning: SymbolFlags, endOfChain: boolean): Symbol[] | undefined { + let accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, /*useOnlyExternalAliasing*/false); - const resolved = resolveStructuredTypeMembers(type); - if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { - if (!resolved.callSignatures.length && !resolved.constructSignatures.length) { - return createTypeLiteralNode(/*members*/ undefined); - } + if (!accessibleSymbolChain || + needsQualification(accessibleSymbolChain[0], enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) { - if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) { - const signature = resolved.callSignatures[0]; - return signatureToSignatureDeclaration(signature, SyntaxKind.FunctionType, enclosingDeclaration); - } - if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) { - const signature = resolved.constructSignatures[0]; - return signatureToSignatureDeclaration(signature, SyntaxKind.ConstructorType, enclosingDeclaration); - } - } - - const saveInObjectTypeLiteral = inObjectTypeLiteral; - inObjectTypeLiteral = true; - const members = createTypeNodesFromResolvedType(resolved); - inObjectTypeLiteral = saveInObjectTypeLiteral; - return createTypeLiteralNode(members); - } - - function createTypeQueryNodeFromType(type: Type) { - const symbol = type.symbol; - if (symbol) { - const entityName = createNameFromSymbol(symbol); - return createTypeQueryNode(entityName); - } - } - - function typeReferenceToTypeReferenceNode(type: TypeReference) { - const typeArguments: Type[] = type.typeArguments || emptyArray; - if (type.target === globalArrayType) { - const elementType = typeToTypeNodeWorker(typeArguments[0]); - return createArrayTypeNode(elementType); - } - else if (type.target.objectFlags & ObjectFlags.Tuple) { - return createTupleTypeNode(typeArguments.length > 0 ? mapToTypeNodeArray(typeArguments.slice(0, getTypeReferenceArity(type))) : undefined); - } - else { - const outerTypeParameters = type.target.outerTypeParameters; - let i = 0; - let qualifiedName: QualifiedName | undefined = undefined; - if (outerTypeParameters) { - const length = outerTypeParameters.length; - while (i < length) { - // Find group of type arguments for type parameters with the same declaring container. - const start = i; - const parent = getParentSymbolOfTypeParameter(outerTypeParameters[i]); - do { - i++; - } while (i < length && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent); - // When type parameters are their own type arguments for the whole group (i.e. we have - // the default outer type arguments), we don't show the group. - if (!rangeEquals(outerTypeParameters, typeArguments, start, i)) { - const qualifiedNamePart = createNameFromSymbol(parent, /*mustBeIdentifier*/ true); - if (!qualifiedName) { - qualifiedName = createQualifiedName(qualifiedNamePart, /*right*/ undefined); - } - else { - Debug.assert(!qualifiedName.right); - qualifiedName.right = qualifiedNamePart; - qualifiedName = createQualifiedName(qualifiedName, /*right*/ undefined); - } - } + // Go up and add our parent. + const parent = getParentOfSymbol(accessibleSymbolChain ? accessibleSymbolChain[0] : symbol); + if (parent) { + const parentChain = getSymbolChain(parent, getQualifiedLeftMeaning(meaning), /*endOfChain*/ false); + if (parentChain) { + accessibleSymbolChain = parentChain.concat(accessibleSymbolChain || [symbol]); } } - let entityName: EntityName = undefined; - const nameIdentifier = createNameFromSymbol(type.symbol, /*mustBeIdentifier*/ true); - if (qualifiedName) { - Debug.assert(!qualifiedName.right); - qualifiedName.right = nameIdentifier; - entityName = qualifiedName; - } - else { - entityName = nameIdentifier; - } - const typeParameterCount = (type.target.typeParameters || emptyArray).length; - const typeArgumentNodes = mapToTypeNodeArray(typeArguments.length > 0 ? typeArguments.slice(i, typeParameterCount - i) : undefined); - return createTypeReferenceNode(entityName, typeArgumentNodes); - } - } - - function createTypeNodesFromResolvedType(resolvedType: ResolvedType): TypeElement[] { - const typeElements: TypeElement[] = []; - for (const signature of resolvedType.callSignatures) { - typeElements.push(signatureToSignatureDeclaration(signature, SyntaxKind.CallSignature, enclosingDeclaration)); - } - for (const signature of resolvedType.constructSignatures) { - typeElements.push(signatureToSignatureDeclaration(signature, SyntaxKind.ConstructSignature, enclosingDeclaration)); - } - if (resolvedType.stringIndexInfo) { - typeElements.push(indexInfoToIndexSignatureDeclaration(resolvedType.stringIndexInfo, IndexKind.String, enclosingDeclaration)); - } - if (resolvedType.numberIndexInfo) { - typeElements.push(indexInfoToIndexSignatureDeclaration(resolvedType.numberIndexInfo, IndexKind.Number, enclosingDeclaration)); } - const properties = resolvedType.properties; - if (!properties) { - return typeElements; + if (accessibleSymbolChain) { + return accessibleSymbolChain; } - for (const propertySymbol of properties) { - const propertyType = getTypeOfSymbol(propertySymbol); - const oldDeclaration = propertySymbol.declarations && propertySymbol.declarations[0] as TypeElement; - if (!oldDeclaration) { - return; - } - const propertyName = oldDeclaration.name; - const optionalToken = propertySymbol.flags & SymbolFlags.Optional ? createToken(SyntaxKind.QuestionToken) : undefined;; - if (propertySymbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length) { - const signatures = getSignaturesOfType(propertyType, SignatureKind.Call); - for (const signature of signatures) { - const methodDeclaration = signatureToSignatureDeclaration(signature, SyntaxKind.MethodSignature, enclosingDeclaration); - methodDeclaration.name = propertyName; - methodDeclaration.questionToken = optionalToken; - typeElements.push(methodDeclaration); - } - } - else { - typeElements.push(createPropertySignature( - propertyName, - optionalToken, - typeToTypeNodeWorker(propertyType), - /*initializer*/undefined)); - } - } - return typeElements.length ? typeElements : undefined; - } + else if ( + // If this is the last part of outputting the symbol, always output. The cases apply only to parent symbols. + endOfChain || + // If a parent symbol is an external module, don't write it. (We prefer just `x` vs `"foo/bar".x`.) + !(!parentSymbol && ts.forEach(symbol.declarations, hasExternalModuleSymbol)) && + // If a parent symbol is an anonymous type, don't write it. + !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral))) { - function createNameFromSymbol(symbol: Symbol, mustBeIdentifier: true): Identifier; - function createNameFromSymbol(symbol: Symbol, mustBeIdentifier?: false): EntityName; - function createNameFromSymbol(symbol: Symbol, mustBeIdentifier: boolean | undefined): EntityName { - let parentSymbol: Symbol; - let meaning: SymbolFlags; - - // Get qualified name if the symbol is not a type parameter - // and there is an enclosing declaration. - let chain: Symbol[]; - const isTypeParameter = symbol.flags & SymbolFlags.TypeParameter; - if (!isTypeParameter && enclosingDeclaration) { - chain = getSymbolChain(symbol, meaning, /*endOfChain*/ true); - // TODO: check whether type pointed to by symbol requires type arguments to be printed. - Debug.assert(chain && chain.length > 0); - } - else { - chain = [symbol]; - } - - parentSymbol = undefined; - if(mustBeIdentifier && chain.length !== 1) { - encounteredError = true; - // TODO: failing to get an identifier when we expect one generates an unprintable node. - // Should error handling be more severe? - } - return createEntityNameFromSymbolChain(chain, chain.length - 1); - - function createEntityNameFromSymbolChain(chain: Symbol[], index: number): EntityName { - Debug.assert(chain && 0 <= index && index < chain.length); - // const parentIndex = index - 1; - const symbol = chain[index]; - let typeParameterString = ""; - if(index > 0) { - // TODO: is the parentSymbol wrong? - const parentSymbol = chain[index - 1]; - let typeParameters: TypeParameter[]; - if(getCheckFlags(symbol) & CheckFlags.Instantiated) { - typeParameters = getTypeParametersOfClassOrInterface(parentSymbol); - } - else { - const targetSymbol = getTargetSymbol(parentSymbol); - if(targetSymbol.flags & (SymbolFlags.Class | SymbolFlags.Interface | SymbolFlags.TypeAlias)) { - typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); - } - } - if(typeParameters && typeParameters.length > 0) { - encounteredError = true; - const writer = getSingleLineStringWriter(); - const displayBuilder = getSymbolDisplayBuilder(); - displayBuilder.buildDisplayForTypeParametersAndDelimiters(typeParameters, writer, enclosingDeclaration, 0); - typeParameterString = writer.string(); - releaseStringWriter(writer); - - } - } - const symbolName = getNameOfSymbol(symbol); - const symbolNameWithTypeParameters = typeParameterString.length > 0 ? `${symbolName}<${typeParameterString}>` : symbolName; - let identifier = createIdentifier(symbolNameWithTypeParameters); - - return index > 0 ? createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier; - } - - /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */ - function getSymbolChain(symbol: Symbol, meaning: SymbolFlags, endOfChain: boolean): Symbol[] | undefined { - let accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, /*useOnlyExternalAliasing*/false); - - if (!accessibleSymbolChain || - needsQualification(accessibleSymbolChain[0], enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) { - - // Go up and add our parent. - const parent = getParentOfSymbol(accessibleSymbolChain ? accessibleSymbolChain[0] : symbol); - if (parent) { - const parentChain = getSymbolChain(parent, getQualifiedLeftMeaning(meaning), /*endOfChain*/ false); - if (parentChain) { - accessibleSymbolChain = parentChain.concat(accessibleSymbolChain || [symbol]); - } - } - } - - if (accessibleSymbolChain) { - return accessibleSymbolChain; - } - - else if ( - // If this is the last part of outputting the symbol, always output. The cases apply only to parent symbols. - endOfChain || - // If a parent symbol is an external module, don't write it. (We prefer just `x` vs `"foo/bar".x`.) - !(!parentSymbol && ts.forEach(symbol.declarations, hasExternalModuleSymbol)) && - // If a parent symbol is an anonymous type, don't write it. - !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral))) { - - return [symbol]; - } + return [symbol]; } } @@ -2687,26 +2738,6 @@ namespace ts { } } - function indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node): IndexSignatureDeclaration { - const indexerTypeNode = createKeywordTypeNode(kind === IndexKind.String ? SyntaxKind.StringKeyword : SyntaxKind.NumberKeyword); - - const name = getNameFromIndexInfo(indexInfo); - const indexingParameter = createParameter( - /*decorators*/ undefined, - /*modifiers*/ undefined, - /*dotDotDotToken*/ undefined, - name, - /*questionToken*/ undefined, - indexerTypeNode, - /*initializer*/ undefined); - const typeNode = typeToTypeNode(indexInfo.type, enclosingDeclaration); - return createIndexSignatureDeclaration( - [indexingParameter], - typeNode, - /*decorators*/ undefined, - indexInfo.isReadonly ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined); - } - function typePredicateToString(typePredicate: TypePredicate, enclosingDeclaration?: Declaration, flags?: TypeFormatFlags): string { const writer = getSingleLineStringWriter(); getSymbolDisplayBuilder().buildTypePredicateDisplay(typePredicate, writer, enclosingDeclaration, flags); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 5ccdd79f19..288d0942b7 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2473,11 +2473,11 @@ namespace ts { getNonNullableType(type: Type): Type; /** Note that the resulting nodes cannot be checked. */ - typeToTypeNode(type: Type, enclosingDeclaration: Node): TypeNode; + typeToTypeNode(type: Type, enclosingDeclaration?: Node, returnNodeOnError?: boolean): TypeNode; /** Note that the resulting nodes cannot be checked. */ - indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node): IndexSignatureDeclaration; + signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, returnNodeOnError?: boolean): SignatureDeclaration; /** Note that the resulting nodes cannot be checked. */ - signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node): SignatureDeclaration; + indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, returnNodeOnError?: boolean): IndexSignatureDeclaration; getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; getSymbolAtLocation(node: Node): Symbol; @@ -2530,6 +2530,20 @@ namespace ts { /* @internal */ getTypeCount(): number; } + /** Note that the resulting nodes cannot be checked. */ + /* @internal */ + export interface NodeBuilder { + typeToTypeNode(type: Type, enclosingDeclaration?: Node, returnNodeOnError?: boolean): NodeBuilderResult; + signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node): NodeBuilderResult; + indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node): NodeBuilderResult; + } + + /* @internal */ + export interface NodeBuilderResult { + value: T; + error?: boolean; + } + export interface SymbolDisplayBuilder { buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void; From 868802b223a03114ea5d5aaed972d17725830251 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 23 Mar 2017 00:41:07 -0700 Subject: [PATCH 125/164] Port updated dom files (#14805) --- src/lib/dom.generated.d.ts | 41 +++++++++++++++++++++++++------- src/lib/webworker.generated.d.ts | 19 +++++++++++++++ 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/lib/dom.generated.d.ts b/src/lib/dom.generated.d.ts index 5d4bb9ce6e..348e52246a 100644 --- a/src/lib/dom.generated.d.ts +++ b/src/lib/dom.generated.d.ts @@ -1396,6 +1396,7 @@ interface AudioNode extends EventTarget { readonly numberOfInputs: number; readonly numberOfOutputs: number; connect(destination: AudioNode, output?: number, input?: number): AudioNode; + connect(destination: AudioParam, output?: number): void; disconnect(output?: number): void; disconnect(destination: AudioNode, output?: number, input?: number): void; disconnect(destination: AudioParam, output?: number): void; @@ -2152,7 +2153,9 @@ interface CanvasRenderingContext2D extends Object, CanvasPathMethods { createPattern(image: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement, repetition: string): CanvasPattern; createRadialGradient(x0: number, y0: number, r0: number, x1: number, y1: number, r1: number): CanvasGradient; drawFocusIfNeeded(element: Element): void; - drawImage(image: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement, offsetX: number, offsetY: number, width?: number, height?: number, canvasOffsetX?: number, canvasOffsetY?: number, canvasImageWidth?: number, canvasImageHeight?: number): void; + drawImage(image: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap, dstX: number, dstY: number): void; + drawImage(image: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap, dstX: number, dstY: number, dstW: number, dstH: number): void; + drawImage(image: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap, srcX: number, srcY: number, srcW: number, srcH: number, dstX: number, dstY: number, dstW: number, dstH: number): void; fill(fillRule?: string): void; fillRect(x: number, y: number, w: number, h: number): void; fillText(text: string, x: number, y: number, maxWidth?: number): void; @@ -2449,10 +2452,10 @@ declare var DOMException: { } interface DOMImplementation { - createDocument(namespaceURI: string | null, qualifiedName: string | null, doctype: DocumentType): Document; + createDocument(namespaceURI: string | null, qualifiedName: string | null, doctype: DocumentType | null): Document; createDocumentType(qualifiedName: string, publicId: string, systemId: string): DocumentType; createHTMLDocument(title: string): Document; - hasFeature(): boolean; + hasFeature(feature: string | null, version: string | null): boolean; } declare var DOMImplementation: { @@ -3449,6 +3452,7 @@ declare var Document: { } interface DocumentFragment extends Node, NodeSelector, ParentNode { + getElementById(elementId: string): HTMLElement | null; } declare var DocumentFragment: { @@ -11837,7 +11841,7 @@ interface URL { protocol: string; search: string; username: string; - readonly searchparams: URLSearchParams; + readonly searchParams: URLSearchParams; toString(): string; } @@ -12161,12 +12165,12 @@ interface WebGLRenderingContext { stencilMaskSeparate(face: number, mask: number): void; stencilOp(fail: number, zfail: number, zpass: number): void; stencilOpSeparate(face: number, fail: number, zfail: number, zpass: number): void; - texImage2D(target: number, level: number, internalformat: number, width: number, height: number, border: number, format: number, type: number, pixels?: ArrayBufferView): void; - texImage2D(target: number, level: number, internalformat: number, format: number, type: number, pixels?: ImageData | HTMLVideoElement | HTMLImageElement | HTMLCanvasElement): void; + texImage2D(target: number, level: number, internalformat: number, width: number, height: number, border: number, format: number, type: number, pixels: ArrayBufferView | null): void; + texImage2D(target: number, level: number, internalformat: number, format: number, type: number, pixels: ImageBitmap | ImageData | HTMLVideoElement | HTMLImageElement | HTMLCanvasElement): void; texParameterf(target: number, pname: number, param: number): void; texParameteri(target: number, pname: number, param: number): void; - texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, width: number, height: number, format: number, type: number, pixels?: ArrayBufferView): void; - texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, pixels?: ImageData | HTMLVideoElement | HTMLImageElement | HTMLCanvasElement): void; + texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, width: number, height: number, format: number, type: number, pixels: ArrayBufferView | null): void; + texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, pixels: ImageBitmap | ImageData | HTMLVideoElement | HTMLImageElement | HTMLCanvasElement): void; uniform1f(location: WebGLUniformLocation | null, x: number): void; uniform1fv(location: WebGLUniformLocation, v: Float32Array | number[]): void; uniform1i(location: WebGLUniformLocation | null, x: number): void; @@ -13260,6 +13264,8 @@ interface Window extends EventTarget, WindowTimers, WindowSessionStorage, Window webkitConvertPointFromNodeToPage(node: Node, pt: WebKitPoint): WebKitPoint; webkitConvertPointFromPageToNode(node: Node, pt: WebKitPoint): WebKitPoint; webkitRequestAnimationFrame(callback: FrameRequestCallback): number; + createImageBitmap(image: HTMLImageElement | SVGImageElement | HTMLVideoElement | HTMLCanvasElement | ImageBitmap | ImageData | Blob, options?: ImageBitmapOptions): Promise; + createImageBitmap(image: HTMLImageElement | SVGImageElement | HTMLVideoElement | HTMLCanvasElement | ImageBitmap | ImageData | Blob, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise; scroll(options?: ScrollToOptions): void; scrollTo(options?: ScrollToOptions): void; scrollBy(options?: ScrollToOptions): void; @@ -13473,6 +13479,7 @@ interface Body { blob(): Promise; json(): Promise; text(): Promise; + formData(): Promise; } interface CanvasPathMethods { @@ -13835,6 +13842,21 @@ interface Canvas2DContextAttributes { [attribute: string]: boolean | string | undefined; } +interface ImageBitmapOptions { + imageOrientation?: "none" | "flipY"; + premultiplyAlpha?: "none" | "premultiply" | "default"; + colorSpaceConversion?: "none" | "default"; + resizeWidth?: number; + resizeHeight?: number; + resizeQuality?: "pixelated" | "low" | "medium" | "high"; +} + +interface ImageBitmap { + readonly width: number; + readonly height: number; + close(): void; +} + interface URLSearchParams { /** * Appends a specified key/value pair as a new search parameter. @@ -13879,6 +13901,7 @@ interface NodeListOf extends NodeList { interface HTMLCollectionOf extends HTMLCollection { item(index: number): T; namedItem(name: string): T; + [index: number]: T; } interface BlobPropertyBag { @@ -14840,6 +14863,8 @@ declare function webkitCancelAnimationFrame(handle: number): void; declare function webkitConvertPointFromNodeToPage(node: Node, pt: WebKitPoint): WebKitPoint; declare function webkitConvertPointFromPageToNode(node: Node, pt: WebKitPoint): WebKitPoint; declare function webkitRequestAnimationFrame(callback: FrameRequestCallback): number; +declare function createImageBitmap(image: HTMLImageElement | SVGImageElement | HTMLVideoElement | HTMLCanvasElement | ImageBitmap | ImageData | Blob, options?: ImageBitmapOptions): Promise; +declare function createImageBitmap(image: HTMLImageElement | SVGImageElement | HTMLVideoElement | HTMLCanvasElement | ImageBitmap | ImageData | Blob, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise; declare function scroll(options?: ScrollToOptions): void; declare function scrollTo(options?: ScrollToOptions): void; declare function scrollBy(options?: ScrollToOptions): void; diff --git a/src/lib/webworker.generated.d.ts b/src/lib/webworker.generated.d.ts index e9563db1bc..326a3a9546 100644 --- a/src/lib/webworker.generated.d.ts +++ b/src/lib/webworker.generated.d.ts @@ -1407,6 +1407,8 @@ interface WorkerGlobalScope extends EventTarget, WorkerUtils, WindowConsole, Glo readonly performance: Performance; readonly self: WorkerGlobalScope; msWriteProfilerMark(profilerMarkName: string): void; + createImageBitmap(image: ImageBitmap | ImageData | Blob, options?: ImageBitmapOptions): Promise; + createImageBitmap(image: ImageBitmap | ImageData | Blob, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise; addEventListener(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -1467,6 +1469,21 @@ interface ErrorEventInit { error?: any; } +interface ImageBitmapOptions { + imageOrientation?: "none" | "flipY"; + premultiplyAlpha?: "none" | "premultiply" | "default"; + colorSpaceConversion?: "none" | "default"; + resizeWidth?: number; + resizeHeight?: number; + resizeQuality?: "pixelated" | "low" | "medium" | "high"; +} + +interface ImageBitmap { + readonly width: number; + readonly height: number; + close(): void; +} + interface BlobPropertyBag { type?: string; endings?: string; @@ -1697,6 +1714,8 @@ declare var onerror: (this: DedicatedWorkerGlobalScope, ev: ErrorEvent) => any; declare var performance: Performance; declare var self: WorkerGlobalScope; declare function msWriteProfilerMark(profilerMarkName: string): void; +declare function createImageBitmap(image: ImageBitmap | ImageData | Blob, options?: ImageBitmapOptions): Promise; +declare function createImageBitmap(image: ImageBitmap | ImageData | Blob, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise; declare function dispatchEvent(evt: Event): boolean; declare function removeEventListener(type: string, listener?: EventListenerOrEventListenerObject, useCapture?: boolean): void; declare var indexedDB: IDBFactory; From 1f3029d4f15e8d6fa8617318a8655c71756ce2bf Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Thu, 23 Mar 2017 08:34:58 -0700 Subject: [PATCH 126/164] error handling --- src/compiler/checker.ts | 960 +++++++++++++++++++++------------------- src/compiler/types.ts | 23 +- 2 files changed, 517 insertions(+), 466 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b681d1298d..c981d0673b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -61,6 +61,7 @@ namespace ts { const noImplicitThis = compilerOptions.noImplicitThis === undefined ? compilerOptions.strict : compilerOptions.noImplicitThis; const emitResolver = createResolver(); + let nodeBuilderCache: NodeBuilder | undefined; const undefinedSymbol = createSymbol(SymbolFlags.Property, "undefined"); undefinedSymbol.declarations = []; @@ -106,9 +107,9 @@ namespace ts { getParameterType: getTypeAtPosition, getReturnTypeOfSignature, getNonNullableType, - typeToTypeNode, - indexInfoToIndexSignatureDeclaration, - signatureToSignatureDeclaration, + typeToTypeNode: getNodeBuilder().typeToTypeNode, + indexInfoToIndexSignatureDeclaration: getNodeBuilder().indexInfoToIndexSignatureDeclaration, + signatureToSignatureDeclaration: getNodeBuilder().signatureToSignatureDeclaration, getSymbolsInScope: (location, meaning) => { location = getParseTreeNode(location); return location ? getSymbolsInScope(location, meaning) : []; @@ -2191,476 +2192,529 @@ namespace ts { return result; } - function typeParameterToDeclaration(type: TypeParameter, enclosingDeclaration?: Node): TypeParameterDeclaration { - if (!(type && type.symbol && type.flags & TypeFlags.TypeParameter)) { - return undefined; + function getNodeBuilder(): NodeBuilder { + if (nodeBuilderCache) { + return nodeBuilderCache; } - const constraint = typeToTypeNode(getConstraintFromTypeParameter(type), enclosingDeclaration); - const defaultParameter = typeToTypeNode(getDefaultFromTypeParameter(type), enclosingDeclaration); - - // TODO: use method internal to typeToTypeNode. - const name = symbolToString(type.symbol); - return createTypeParameterDeclaration(name, constraint, defaultParameter); - } - - function symbolToParameterDeclaration(parameterSymbol: Symbol, enclosingDeclaration?: Node): ParameterDeclaration { - const parameterDeclaration = parameterSymbol.declarations[0] as ParameterDeclaration; - const parameterType = getTypeOfSymbol(parameterSymbol); - const parameterTypeNode = typeToTypeNode(parameterType, enclosingDeclaration); - // TODO: check initializer accessibility correctly. - const parameterNode = createParameter( - parameterDeclaration.decorators, - parameterDeclaration.modifiers, - parameterDeclaration.dotDotDotToken && createToken(SyntaxKind.DotDotDotToken), - // Clone name to remove trivia. - getSynthesizedClone(parameterDeclaration.name), - parameterDeclaration.questionToken && createToken(SyntaxKind.QuestionToken), - parameterTypeNode, - parameterDeclaration.initializer); - return parameterNode; - } - - function signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node): SignatureDeclaration { - const typeParameters = signature.typeParameters && signature.typeParameters.map(parameter => typeParameterToDeclaration(parameter, enclosingDeclaration)); - const parameters = signature.parameters.map(parameter => symbolToParameterDeclaration(parameter, enclosingDeclaration)); - const type = typeToTypeNodeExceptAny(getReturnTypeOfSignature(signature)); - - return createSignatureDeclaration(kind, typeParameters, parameters, type); - - function typeToTypeNodeExceptAny(type: Type): TypeNode | undefined { - const typeNode = typeToTypeNode(type, enclosingDeclaration); - return typeNode && typeNode.kind !== SyntaxKind.AnyKeyword ? typeNode : undefined; - } - } - - - // function typeToDisplayParts - - function typeToTypeNode(type: Type, enclosingDeclaration?: Node, returnNodeOnError?: boolean): TypeNode { let encounteredError = false; - let inObjectTypeLiteral = false; - let checkAlias = true; - let symbolStack: Symbol[] = undefined; - const result = typeToTypeNodeWorker(type); - // returnNodeOnError = true; // TODO: unset. - return encounteredError && !returnNodeOnError ? undefined: result; + nodeBuilderCache = { + typeToTypeNode, + indexInfoToIndexSignatureDeclaration, + signatureToSignatureDeclaration + } - function typeToTypeNodeWorker(type: Type): TypeNode { - if (!type) { - encounteredError = true; + return nodeBuilderCache; + + function typeToTypeNode(type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeNode { + const helper = () => typeToTypeNodeHelper(type, enclosingDeclaration, flags); + return callHelperWithErrorHandling(helper); + } + + function indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration { + const helper = () => indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, enclosingDeclaration, flags); + return callHelperWithErrorHandling(helper); + } + + function signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): SignatureDeclaration { + const helper = () => signatureToSignatureDeclarationHelper(signature, kind, enclosingDeclaration, flags); + return callHelperWithErrorHandling(helper); + } + + function callHelperWithErrorHandling(nodeBuilderHelper: () => T): T | undefined { + const encounteredErrorCache = encounteredError; + const resultingNode = nodeBuilderHelper(); + const result = encounteredError ? undefined : resultingNode; + encounteredError = encounteredErrorCache; + return result; + } + + function typeToTypeNodeHelper(type: Type, enclosingDeclaration: Node, flags: NodeBuilderFlags): TypeNode { + let inObjectTypeLiteral = false; + let checkAlias = true; + let symbolStack: Symbol[] = undefined; + + return typeToTypeNodeWorker(type, flags); + + function typeToTypeNodeWorker(type: Type, flags: NodeBuilderFlags): TypeNode { + if (!type) { + encounteredError = encounteredError || !(flags & NodeBuilderFlags.allowUndefinedNode); + return undefined; + } + flags = flags & ~NodeBuilderFlags.allowUndefinedNode; + + if (type.flags & TypeFlags.Any) { + return createKeywordTypeNode(SyntaxKind.AnyKeyword); + } + if (type.flags & TypeFlags.String) { + return createKeywordTypeNode(SyntaxKind.StringKeyword); + } + if (type.flags & TypeFlags.Number) { + return createKeywordTypeNode(SyntaxKind.NumberKeyword); + } + if (type.flags & TypeFlags.Boolean) { + return createKeywordTypeNode(SyntaxKind.BooleanKeyword); + } + if (type.flags & TypeFlags.Enum) { + const name = symbolToName(type.symbol, enclosingDeclaration, /*mustBeIdentifier*/ false, flags); + return createTypeReferenceNode(name, /*typeArguments*/ undefined); + } + if (type.flags & (TypeFlags.StringLiteral)) { + return createLiteralTypeNode((createLiteral((type).text))); + } + if (type.flags & (TypeFlags.NumberLiteral)) { + return createLiteralTypeNode((createNumericLiteral((type).text))); + } + if (type.flags & TypeFlags.BooleanLiteral) { + return (type).intrinsicName === "true" ? createTrue() : createFalse(); + } + if (type.flags & TypeFlags.EnumLiteral) { + const name = symbolToName(type.symbol, enclosingDeclaration, /*mustBeIdentifier*/ false, flags); + return createTypeReferenceNode(name, /*typeArguments*/ undefined); + } + if (type.flags & TypeFlags.Void) { + return createKeywordTypeNode(SyntaxKind.VoidKeyword); + } + if (type.flags & TypeFlags.Undefined) { + return createKeywordTypeNode(SyntaxKind.UndefinedKeyword); + } + if (type.flags & TypeFlags.Null) { + return createKeywordTypeNode(SyntaxKind.NullKeyword); + } + if (type.flags & TypeFlags.Never) { + return createKeywordTypeNode(SyntaxKind.NeverKeyword); + } + if (type.flags & TypeFlags.ESSymbol) { + throw new Error("ESSymbol not implemented"); + } + if (type.flags & TypeFlags.NonPrimitive) { + throw new Error("Non primitive not implemented"); + } + if (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType) { + if (inObjectTypeLiteral) { + encounteredError = encounteredError || !(flags & NodeBuilderFlags.allowThisInObjectLiteral); + } + return createThis(); + } + + const objectFlags = getObjectFlags(type); + + if (objectFlags & ObjectFlags.Reference) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + return typeReferenceToTypeReferenceNode(type); + } + if (objectFlags & ObjectFlags.ClassOrInterface) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + const name = symbolToName(type.symbol, enclosingDeclaration, /*mustBeIdentifier*/ false, flags); + // TODO(aozgaa): handle type arguments. + return createTypeReferenceNode(name, /*typeArguments*/ undefined); + } + if (type.flags & TypeFlags.TypeParameter) { + const name = symbolToName(type.symbol, enclosingDeclaration, /*mustBeIdentifier*/ false, flags); + // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. + return createTypeReferenceNode(name, /*typeArguments*/ undefined); + } + + if (checkAlias && type.aliasSymbol) { + const name = symbolToName(type.aliasSymbol, enclosingDeclaration, /*mustBeIdentifier*/ false, flags); + const typeArgumentNodes = mapToTypeNodeArray(type.aliasTypeArguments); + return createTypeReferenceNode(name, typeArgumentNodes); + } + checkAlias = false; + + if (type.flags & TypeFlags.Union) { + return createUnionOrIntersectionTypeNode(SyntaxKind.UnionType, mapToTypeNodeArray(formatUnionTypes((type).types))); + } + + if (type.flags & TypeFlags.Intersection) { + return createUnionOrIntersectionTypeNode(SyntaxKind.IntersectionType, mapToTypeNodeArray((type as UnionType).types)); + } + + if (objectFlags & (ObjectFlags.Anonymous | ObjectFlags.Mapped)) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + // The type is an object literal type. + return createAnonymousTypeNode(type); + } + + if (type.flags & TypeFlags.Index) { + const indexedType = (type).type; + const indexTypeNode = typeToTypeNodeWorker(indexedType, flags); + return createTypeOperatorNode(indexTypeNode); + } + if (type.flags & TypeFlags.IndexedAccess) { + const objectTypeNode = typeToTypeNodeWorker((type).objectType, flags); + const indexTypeNode = typeToTypeNodeWorker((type).indexType, flags); + return createIndexedAccessTypeNode(objectTypeNode, indexTypeNode); + } + + Debug.fail("Should be unreachable."); + + function mapToTypeNodeArray(types: Type[]): NodeArray { + return types && asNodeArray(types.map(typeToTypeNodeWorker) as TypeNode[]); + } + + function createMappedTypeNodeFromType(type: MappedType) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + const typeParameter = getTypeParameterFromMappedType(type); + const typeParameterNode = typeParameterToDeclaration(typeParameter, enclosingDeclaration, flags); + + const templateTypeNode = typeToTypeNodeWorker(getTemplateTypeFromMappedType(type), flags | NodeBuilderFlags.allowUndefinedNode); + const readonlyToken = (type).declaration && (type).declaration.readonlyToken ? createToken(SyntaxKind.ReadonlyKeyword) : undefined; + const questionToken = (type).declaration && (type).declaration.questionToken ? createToken(SyntaxKind.QuestionToken) : undefined; + + return createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode); + } + + function createAnonymousTypeNode(type: ObjectType): TypeNode { + const symbol = type.symbol; + if (symbol) { + // Always use 'typeof T' for type of class, enum, and module objects + if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) || + symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule) || + shouldWriteTypeOfFunctionSymbol()) { + return createTypeQueryNodeFromType(type); + } + else if (contains(symbolStack, symbol)) { + // If type is an anonymous type literal in a type alias declaration, use type alias name + const typeAlias = getTypeAliasForTypeLiteral(type); + if (typeAlias) { + // The specified symbol flags need to be reinterpreted as type flags + const entityName = symbolToName(typeAlias, enclosingDeclaration, /*mustBeIdentifier*/ false, flags); + return createTypeReferenceNode(entityName, /*typeArguments*/ undefined); + } + else { + return createKeywordTypeNode(SyntaxKind.AnyKeyword); + } + } + else { + // Since instantiations of the same anonymous type have the same symbol, tracking symbols instead + // of types allows us to catch circular references to instantiations of the same anonymous type + if (!symbolStack) { + symbolStack = []; + } + symbolStack.push(symbol); + let result = createTypeNodeFromObjectType(type); + symbolStack.pop(); + return result; + } + } + else { + // Anonymous types without a symbol are never circular. + return createTypeNodeFromObjectType(type); + } + + function shouldWriteTypeOfFunctionSymbol() { + const isStaticMethodSymbol = !!(symbol.flags & SymbolFlags.Method && // typeof static method + forEach(symbol.declarations, declaration => getModifierFlags(declaration) & ModifierFlags.Static)); + const isNonLocalFunctionSymbol = !!(symbol.flags & SymbolFlags.Function) && + (symbol.parent || // is exported function symbol + forEach(symbol.declarations, declaration => + declaration.parent.kind === SyntaxKind.SourceFile || declaration.parent.kind === SyntaxKind.ModuleBlock)); + if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { + // typeof is allowed only for static/non local functions + return contains(symbolStack, symbol); // it is type of the symbol uses itself recursively + } + } + } + + function createTypeNodeFromObjectType(type: ObjectType): TypeNode { + if (type.objectFlags & ObjectFlags.Mapped) { + if (getConstraintTypeFromMappedType(type).flags & (TypeFlags.TypeParameter | TypeFlags.Index)) { + return createMappedTypeNodeFromType(type); + } + } + + const resolved = resolveStructuredTypeMembers(type); + if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { + if (!resolved.callSignatures.length && !resolved.constructSignatures.length) { + return createTypeLiteralNode(/*members*/ undefined); + } + + if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) { + const signature = resolved.callSignatures[0]; + return signatureToSignatureDeclarationHelper(signature, SyntaxKind.FunctionType, enclosingDeclaration, flags); + } + if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) { + const signature = resolved.constructSignatures[0]; + return signatureToSignatureDeclarationHelper(signature, SyntaxKind.ConstructorType, enclosingDeclaration, flags); + } + } + + const saveInObjectTypeLiteral = inObjectTypeLiteral; + inObjectTypeLiteral = true; + const members = createTypeNodesFromResolvedType(resolved); + inObjectTypeLiteral = saveInObjectTypeLiteral; + return createTypeLiteralNode(members); + } + + function createTypeQueryNodeFromType(type: Type) { + const symbol = type.symbol; + if (symbol) { + const entityName = symbolToName(symbol, enclosingDeclaration, /*mustBeIdentifier*/ false, flags); + return createTypeQueryNode(entityName); + } + } + + function typeReferenceToTypeReferenceNode(type: TypeReference) { + const typeArguments: Type[] = type.typeArguments || emptyArray; + if (type.target === globalArrayType) { + const elementType = typeToTypeNodeWorker(typeArguments[0], flags); + return createArrayTypeNode(elementType); + } + else if (type.target.objectFlags & ObjectFlags.Tuple) { + return createTupleTypeNode(typeArguments.length > 0 ? mapToTypeNodeArray(typeArguments.slice(0, getTypeReferenceArity(type))) : undefined); + } + else { + const outerTypeParameters = type.target.outerTypeParameters; + let i = 0; + let qualifiedName: QualifiedName | undefined = undefined; + if (outerTypeParameters) { + const length = outerTypeParameters.length; + while (i < length) { + // Find group of type arguments for type parameters with the same declaring container. + const start = i; + const parent = getParentSymbolOfTypeParameter(outerTypeParameters[i]); + do { + i++; + } while (i < length && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent); + // When type parameters are their own type arguments for the whole group (i.e. we have + // the default outer type arguments), we don't show the group. + if (!rangeEquals(outerTypeParameters, typeArguments, start, i)) { + const qualifiedNamePart = symbolToName(parent, enclosingDeclaration, /*mustBeIdentifier*/ true, flags); + if (!qualifiedName) { + qualifiedName = createQualifiedName(qualifiedNamePart, /*right*/ undefined); + } + else { + Debug.assert(!qualifiedName.right); + qualifiedName.right = qualifiedNamePart; + qualifiedName = createQualifiedName(qualifiedName, /*right*/ undefined); + } + } + } + } + let entityName: EntityName = undefined; + const nameIdentifier = symbolToName(type.symbol, enclosingDeclaration, /*mustBeIdentifier*/ true, flags); + if (qualifiedName) { + Debug.assert(!qualifiedName.right); + qualifiedName.right = nameIdentifier; + entityName = qualifiedName; + } + else { + entityName = nameIdentifier; + } + const typeParameterCount = (type.target.typeParameters || emptyArray).length; + const typeArgumentNodes = mapToTypeNodeArray(typeArguments.length > 0 ? typeArguments.slice(i, typeParameterCount - i) : undefined); + return createTypeReferenceNode(entityName, typeArgumentNodes); + } + } + + function createTypeNodesFromResolvedType(resolvedType: ResolvedType): TypeElement[] { + const typeElements: TypeElement[] = []; + for (const signature of resolvedType.callSignatures) { + typeElements.push(signatureToSignatureDeclarationHelper(signature, SyntaxKind.CallSignature, enclosingDeclaration, flags)); + } + for (const signature of resolvedType.constructSignatures) { + typeElements.push(signatureToSignatureDeclarationHelper(signature, SyntaxKind.ConstructSignature, enclosingDeclaration, flags)); + } + if (resolvedType.stringIndexInfo) { + typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.stringIndexInfo, IndexKind.String, enclosingDeclaration, flags)); + } + if (resolvedType.numberIndexInfo) { + typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.numberIndexInfo, IndexKind.Number, enclosingDeclaration, flags)); + } + + const properties = resolvedType.properties; + if (!properties) { + return typeElements; + } + + for (const propertySymbol of properties) { + const propertyType = getTypeOfSymbol(propertySymbol); + const oldDeclaration = propertySymbol.declarations && propertySymbol.declarations[0] as TypeElement; + if (!oldDeclaration) { + return; + } + const propertyName = oldDeclaration.name; + const optionalToken = propertySymbol.flags & SymbolFlags.Optional ? createToken(SyntaxKind.QuestionToken) : undefined;; + if (propertySymbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length) { + const signatures = getSignaturesOfType(propertyType, SignatureKind.Call); + for (const signature of signatures) { + const methodDeclaration = signatureToSignatureDeclarationHelper(signature, SyntaxKind.MethodSignature, enclosingDeclaration, flags); + methodDeclaration.name = propertyName; + methodDeclaration.questionToken = optionalToken; + typeElements.push(methodDeclaration); + } + } + else { + typeElements.push(createPropertySignature( + propertyName, + optionalToken, + typeToTypeNodeWorker(propertyType, flags), + /*initializer*/undefined)); + } + } + return typeElements.length ? typeElements : undefined; + } + } + } + + function indexInfoToIndexSignatureDeclarationHelper(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node, flags: NodeBuilderFlags): IndexSignatureDeclaration { + const indexerTypeNode = createKeywordTypeNode(kind === IndexKind.String ? SyntaxKind.StringKeyword : SyntaxKind.NumberKeyword); + + const name = getNameFromIndexInfo(indexInfo); + const indexingParameter = createParameter( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, + name, + /*questionToken*/ undefined, + indexerTypeNode, + /*initializer*/ undefined); + const typeNode = typeToTypeNodeHelper(indexInfo.type, enclosingDeclaration, flags); + return createIndexSignatureDeclaration( + [indexingParameter], + typeNode, + /*decorators*/ undefined, + indexInfo.isReadonly ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined); + } + + function signatureToSignatureDeclarationHelper(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node, flags: NodeBuilderFlags): SignatureDeclaration { + + const typeParameters = signature.typeParameters && signature.typeParameters.map(parameter => typeParameterToDeclaration(parameter, enclosingDeclaration, flags)); + const parameters = signature.parameters.map(parameter => symbolToParameterDeclaration(parameter, enclosingDeclaration, flags)); + const type = typeToTypeNodeExceptAny(getReturnTypeOfSignature(signature)); + + return createSignatureDeclaration(kind, typeParameters, parameters, type); + + function typeToTypeNodeExceptAny(type: Type): TypeNode | undefined { + // Note, this call will *not* mark encounteredError. + const typeNode = typeToTypeNode(type, enclosingDeclaration); + return typeNode && typeNode.kind !== SyntaxKind.AnyKeyword ? typeNode : undefined; + } + } + + function typeParameterToDeclaration(type: TypeParameter, enclosingDeclaration: Node, flags: NodeBuilderFlags): TypeParameterDeclaration { + if (!(type && type.symbol && type.flags & TypeFlags.TypeParameter)) { return undefined; } - if (type.flags & TypeFlags.Any) { - return createKeywordTypeNode(SyntaxKind.AnyKeyword); + const constraint = typeToTypeNodeHelper(getConstraintFromTypeParameter(type), enclosingDeclaration, flags | NodeBuilderFlags.allowUndefinedNode); + const defaultParameter = typeToTypeNodeHelper(getDefaultFromTypeParameter(type), enclosingDeclaration, flags | NodeBuilderFlags.allowUndefinedNode); +; + const name = symbolToName(type.symbol, enclosingDeclaration, /*mustBeIdentifier*/ true, flags); + return createTypeParameterDeclaration(name, constraint, defaultParameter); + } + + function symbolToParameterDeclaration(parameterSymbol: Symbol, enclosingDeclaration: Node, flags: NodeBuilderFlags): ParameterDeclaration { + const parameterDeclaration = parameterSymbol.declarations[0] as ParameterDeclaration; + const parameterType = getTypeOfSymbol(parameterSymbol); + const parameterTypeNode = typeToTypeNodeHelper(parameterType, enclosingDeclaration, flags); + // TODO(aozgaa): check initializer accessibility correctly. + const parameterNode = createParameter( + parameterDeclaration.decorators, + parameterDeclaration.modifiers, + parameterDeclaration.dotDotDotToken && createToken(SyntaxKind.DotDotDotToken), + // Clone name to remove trivia. + getSynthesizedClone(parameterDeclaration.name), + parameterDeclaration.questionToken && createToken(SyntaxKind.QuestionToken), + parameterTypeNode, + parameterDeclaration.initializer); + return parameterNode; + } + + function symbolToName(symbol: Symbol, enclosingDeclaration: Node | undefined, mustBeIdentifier: true, flags: NodeBuilderFlags): Identifier; + function symbolToName(symbol: Symbol, enclosingDeclaration: Node, mustBeIdentifier: false, flags: NodeBuilderFlags): EntityName; + function symbolToName(symbol: Symbol, enclosingDeclaration: Node | undefined, mustBeIdentifier: boolean, flags: NodeBuilderFlags): EntityName { + let parentSymbol: Symbol; + let meaning: SymbolFlags; + + // Get qualified name if the symbol is not a type parameter + // and there is an enclosing declaration. + let chain: Symbol[]; + const isTypeParameter = symbol.flags & SymbolFlags.TypeParameter; + if (!isTypeParameter && enclosingDeclaration) { + chain = getSymbolChain(symbol, meaning, /*endOfChain*/ true); + // TODO: check whether type pointed to by symbol requires type arguments to be printed. + Debug.assert(chain && chain.length > 0); } - if (type.flags & TypeFlags.String) { - return createKeywordTypeNode(SyntaxKind.StringKeyword); - } - if (type.flags & TypeFlags.Number) { - return createKeywordTypeNode(SyntaxKind.NumberKeyword); - } - if(type.flags & TypeFlags.Boolean) { - return createKeywordTypeNode(SyntaxKind.BooleanKeyword); - } - if (type.flags & TypeFlags.Enum) { - const name = createNameFromSymbol(type.symbol); - return createTypeReferenceNode(name, /*typeArguments*/ undefined); - } - if (type.flags & (TypeFlags.StringLiteral)) { - return createLiteralTypeNode((createLiteral((type).text))); - } - if (type.flags & (TypeFlags.NumberLiteral)) { - return createLiteralTypeNode((createNumericLiteral((type).text))); - } - if(type.flags & TypeFlags.BooleanLiteral) { - return (type).intrinsicName === "true" ? createTrue() : createFalse(); - } - if (type.flags & TypeFlags.EnumLiteral) { - const name = createNameFromSymbol(type.symbol); - return createTypeReferenceNode(name, /*typeArguments*/ undefined); - } - if (type.flags & TypeFlags.Void) { - return createKeywordTypeNode(SyntaxKind.VoidKeyword); - } - if (type.flags & TypeFlags.Undefined) { - return createKeywordTypeNode(SyntaxKind.UndefinedKeyword); - } - if (type.flags & TypeFlags.Null) { - return createKeywordTypeNode(SyntaxKind.NullKeyword); - } - if (type.flags & TypeFlags.Never) { - return createKeywordTypeNode(SyntaxKind.NeverKeyword); - } - if (type.flags & TypeFlags.ESSymbol) { - throw new Error("ESSymbol not implemented"); - } - if (type.flags & TypeFlags.NonPrimitive) { - throw new Error("Non primitive not implemented"); - } - if (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType) { - if (inObjectTypeLiteral) { - encounteredError = true; - } - return createThis(); + else { + chain = [symbol]; } - const objectFlags = getObjectFlags(type); - - if (objectFlags & ObjectFlags.Reference) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - return typeReferenceToTypeReferenceNode(type); - } - if (objectFlags & ObjectFlags.ClassOrInterface) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - const name = createNameFromSymbol(type.symbol); - // TODO: handle type arguments. - return createTypeReferenceNode(name, /*typeArguments*/ undefined); - } - if (type.flags & TypeFlags.TypeParameter) { - const name = createNameFromSymbol(type.symbol); - // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. - return createTypeReferenceNode(name, /*typeArguments*/ undefined); + parentSymbol = undefined; + if (mustBeIdentifier && chain.length !== 1) { + encounteredError = encounteredError || !(flags & NodeBuilderFlags.allowQualifedNameInPlaceOfIdentifier); + // TODO: failing to get an identifier when we expect one generates an unprintable node. + // Should error handling be more severe? } + return createEntityNameFromSymbolChain(chain, chain.length - 1); - if (checkAlias && type.aliasSymbol) { - const name = createNameFromSymbol(type.aliasSymbol); - const typeArgumentNodes = mapToTypeNodeArray(type.aliasTypeArguments); - return createTypeReferenceNode(name, typeArgumentNodes); - } - checkAlias = false; - - if (type.flags & TypeFlags.Union) { - return createUnionOrIntersectionTypeNode(SyntaxKind.UnionType, mapToTypeNodeArray(formatUnionTypes((type).types))); - } - - if (type.flags & TypeFlags.Intersection) { - return createUnionOrIntersectionTypeNode(SyntaxKind.IntersectionType, mapToTypeNodeArray((type as UnionType).types)); - } - - if (objectFlags & (ObjectFlags.Anonymous | ObjectFlags.Mapped)) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - // The type is an object literal type. - return createAnonymousTypeNode(type); - } - - // TODO (aozgaa): implement string and number literals here once there is a testable case. - - if (type.flags & TypeFlags.Index) { - const indexedType = (type).type; - const indexTypeNode = typeToTypeNodeWorker(indexedType); - return createTypeOperatorNode(indexTypeNode); - } - if (type.flags & TypeFlags.IndexedAccess) { - const objectTypeNode = typeToTypeNodeWorker((type).objectType); - const indexTypeNode = typeToTypeNodeWorker((type).indexType); - return createIndexedAccessTypeNode(objectTypeNode, indexTypeNode); - } - - Debug.fail("Should be unreachable."); - - function mapToTypeNodeArray(types: Type[]): NodeArray { - return types && asNodeArray(types.map(typeToTypeNodeWorker) as TypeNode[]); - } - - function createMappedTypeNodeFromType(type: MappedType) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - const typeParameter = getTypeParameterFromMappedType(type); - const typeParameterNode = typeParameterToDeclaration(typeParameter, enclosingDeclaration); - - const templateTypeNode = typeToTypeNode(getTemplateTypeFromMappedType(type), enclosingDeclaration); - const readonlyToken = (type).declaration && (type).declaration.readonlyToken ? createToken(SyntaxKind.ReadonlyKeyword) : undefined; - const questionToken = (type).declaration && (type).declaration.questionToken ? createToken(SyntaxKind.QuestionToken) : undefined; - - return createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode); - } - - function createAnonymousTypeNode(type: ObjectType): TypeNode { - const symbol = type.symbol; - if (symbol) { - // Always use 'typeof T' for type of class, enum, and module objects - if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) || - symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule) || - shouldWriteTypeOfFunctionSymbol()) { - return createTypeQueryNodeFromType(type); - } - else if (contains(symbolStack, symbol)) { - // If type is an anonymous type literal in a type alias declaration, use type alias name - const typeAlias = getTypeAliasForTypeLiteral(type); - if (typeAlias) { - // The specified symbol flags need to be reinterpreted as type flags - const entityName = createNameFromSymbol(typeAlias); - return createTypeReferenceNode(entityName, /*typeArguments*/ undefined); - } - else { - return createKeywordTypeNode(SyntaxKind.AnyKeyword); - } + function createEntityNameFromSymbolChain(chain: Symbol[], index: number): EntityName { + Debug.assert(chain && 0 <= index && index < chain.length); + // const parentIndex = index - 1; + const symbol = chain[index]; + let typeParameterString = ""; + if (index > 0) { + // TODO: is the parentSymbol wrong? + const parentSymbol = chain[index - 1]; + let typeParameters: TypeParameter[]; + if (getCheckFlags(symbol) & CheckFlags.Instantiated) { + typeParameters = getTypeParametersOfClassOrInterface(parentSymbol); } else { - // Since instantiations of the same anonymous type have the same symbol, tracking symbols instead - // of types allows us to catch circular references to instantiations of the same anonymous type - if (!symbolStack) { - symbolStack = []; + const targetSymbol = getTargetSymbol(parentSymbol); + if (targetSymbol.flags & (SymbolFlags.Class | SymbolFlags.Interface | SymbolFlags.TypeAlias)) { + typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); } - symbolStack.push(symbol); - let result = createTypeNodeFromObjectType(type); - symbolStack.pop(); - return result; } - } - else { - // Anonymous types without a symbol are never circular. - return createTypeNodeFromObjectType(type); - } + if (typeParameters && typeParameters.length > 0) { + encounteredError = encounteredError || !(flags & NodeBuilderFlags.allowTypeParameterInQualifiedName);; + const writer = getSingleLineStringWriter(); + const displayBuilder = getSymbolDisplayBuilder(); + displayBuilder.buildDisplayForTypeParametersAndDelimiters(typeParameters, writer, enclosingDeclaration, 0); + typeParameterString = writer.string(); + releaseStringWriter(writer); - function shouldWriteTypeOfFunctionSymbol() { - const isStaticMethodSymbol = !!(symbol.flags & SymbolFlags.Method && // typeof static method - forEach(symbol.declarations, declaration => getModifierFlags(declaration) & ModifierFlags.Static)); - const isNonLocalFunctionSymbol = !!(symbol.flags & SymbolFlags.Function) && - (symbol.parent || // is exported function symbol - forEach(symbol.declarations, declaration => - declaration.parent.kind === SyntaxKind.SourceFile || declaration.parent.kind === SyntaxKind.ModuleBlock)); - if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { - // typeof is allowed only for static/non local functions - return contains(symbolStack, symbol); // it is type of the symbol uses itself recursively } } + const symbolName = getNameOfSymbol(symbol); + const symbolNameWithTypeParameters = typeParameterString.length > 0 ? `${symbolName}<${typeParameterString}>` : symbolName; + let identifier = createIdentifier(symbolNameWithTypeParameters); + + return index > 0 ? createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier; } - function createTypeNodeFromObjectType(type: ObjectType): TypeNode { - if (type.objectFlags & ObjectFlags.Mapped) { - if (getConstraintTypeFromMappedType(type).flags & (TypeFlags.TypeParameter | TypeFlags.Index)) { - return createMappedTypeNodeFromType(type); - } - } + /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */ + function getSymbolChain(symbol: Symbol, meaning: SymbolFlags, endOfChain: boolean): Symbol[] | undefined { + let accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, /*useOnlyExternalAliasing*/false); - const resolved = resolveStructuredTypeMembers(type); - if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { - if (!resolved.callSignatures.length && !resolved.constructSignatures.length) { - return createTypeLiteralNode(/*members*/ undefined); - } + if (!accessibleSymbolChain || + needsQualification(accessibleSymbolChain[0], enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) { - if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) { - const signature = resolved.callSignatures[0]; - return signatureToSignatureDeclaration(signature, SyntaxKind.FunctionType, enclosingDeclaration); - } - if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) { - const signature = resolved.constructSignatures[0]; - return signatureToSignatureDeclaration(signature, SyntaxKind.ConstructorType, enclosingDeclaration); - } - } - - const saveInObjectTypeLiteral = inObjectTypeLiteral; - inObjectTypeLiteral = true; - const members = createTypeNodesFromResolvedType(resolved); - inObjectTypeLiteral = saveInObjectTypeLiteral; - return createTypeLiteralNode(members); - } - - function createTypeQueryNodeFromType(type: Type) { - const symbol = type.symbol; - if (symbol) { - const entityName = createNameFromSymbol(symbol); - return createTypeQueryNode(entityName); - } - } - - function typeReferenceToTypeReferenceNode(type: TypeReference) { - const typeArguments: Type[] = type.typeArguments || emptyArray; - if (type.target === globalArrayType) { - const elementType = typeToTypeNodeWorker(typeArguments[0]); - return createArrayTypeNode(elementType); - } - else if (type.target.objectFlags & ObjectFlags.Tuple) { - return createTupleTypeNode(typeArguments.length > 0 ? mapToTypeNodeArray(typeArguments.slice(0, getTypeReferenceArity(type))) : undefined); - } - else { - const outerTypeParameters = type.target.outerTypeParameters; - let i = 0; - let qualifiedName: QualifiedName | undefined = undefined; - if (outerTypeParameters) { - const length = outerTypeParameters.length; - while (i < length) { - // Find group of type arguments for type parameters with the same declaring container. - const start = i; - const parent = getParentSymbolOfTypeParameter(outerTypeParameters[i]); - do { - i++; - } while (i < length && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent); - // When type parameters are their own type arguments for the whole group (i.e. we have - // the default outer type arguments), we don't show the group. - if (!rangeEquals(outerTypeParameters, typeArguments, start, i)) { - const qualifiedNamePart = createNameFromSymbol(parent, /*mustBeIdentifier*/ true); - if (!qualifiedName) { - qualifiedName = createQualifiedName(qualifiedNamePart, /*right*/ undefined); - } - else { - Debug.assert(!qualifiedName.right); - qualifiedName.right = qualifiedNamePart; - qualifiedName = createQualifiedName(qualifiedName, /*right*/ undefined); - } - } + // Go up and add our parent. + const parent = getParentOfSymbol(accessibleSymbolChain ? accessibleSymbolChain[0] : symbol); + if (parent) { + const parentChain = getSymbolChain(parent, getQualifiedLeftMeaning(meaning), /*endOfChain*/ false); + if (parentChain) { + accessibleSymbolChain = parentChain.concat(accessibleSymbolChain || [symbol]); } } - let entityName: EntityName = undefined; - const nameIdentifier = createNameFromSymbol(type.symbol, /*mustBeIdentifier*/ true); - if (qualifiedName) { - Debug.assert(!qualifiedName.right); - qualifiedName.right = nameIdentifier; - entityName = qualifiedName; - } - else { - entityName = nameIdentifier; - } - const typeParameterCount = (type.target.typeParameters || emptyArray).length; - const typeArgumentNodes = mapToTypeNodeArray(typeArguments.length > 0 ? typeArguments.slice(i, typeParameterCount - i) : undefined); - return createTypeReferenceNode(entityName, typeArgumentNodes); - } - } - - function createTypeNodesFromResolvedType(resolvedType: ResolvedType): TypeElement[] { - const typeElements: TypeElement[] = []; - for (const signature of resolvedType.callSignatures) { - typeElements.push(signatureToSignatureDeclaration(signature, SyntaxKind.CallSignature, enclosingDeclaration)); - } - for (const signature of resolvedType.constructSignatures) { - typeElements.push(signatureToSignatureDeclaration(signature, SyntaxKind.ConstructSignature, enclosingDeclaration)); - } - if (resolvedType.stringIndexInfo) { - typeElements.push(indexInfoToIndexSignatureDeclaration(resolvedType.stringIndexInfo, IndexKind.String, enclosingDeclaration)); - } - if (resolvedType.numberIndexInfo) { - typeElements.push(indexInfoToIndexSignatureDeclaration(resolvedType.numberIndexInfo, IndexKind.Number, enclosingDeclaration)); } - const properties = resolvedType.properties; - if (!properties) { - return typeElements; + if (accessibleSymbolChain) { + return accessibleSymbolChain; } - for (const propertySymbol of properties) { - const propertyType = getTypeOfSymbol(propertySymbol); - const oldDeclaration = propertySymbol.declarations && propertySymbol.declarations[0] as TypeElement; - if (!oldDeclaration) { - return; - } - const propertyName = oldDeclaration.name; - const optionalToken = propertySymbol.flags & SymbolFlags.Optional ? createToken(SyntaxKind.QuestionToken) : undefined;; - if (propertySymbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length) { - const signatures = getSignaturesOfType(propertyType, SignatureKind.Call); - for (const signature of signatures) { - const methodDeclaration = signatureToSignatureDeclaration(signature, SyntaxKind.MethodSignature, enclosingDeclaration); - methodDeclaration.name = propertyName; - methodDeclaration.questionToken = optionalToken; - typeElements.push(methodDeclaration); - } - } - else { - typeElements.push(createPropertySignature( - propertyName, - optionalToken, - typeToTypeNodeWorker(propertyType), - /*initializer*/undefined)); - } - } - return typeElements.length ? typeElements : undefined; - } + else if ( + // If this is the last part of outputting the symbol, always output. The cases apply only to parent symbols. + endOfChain || + // If a parent symbol is an external module, don't write it. (We prefer just `x` vs `"foo/bar".x`.) + !(!parentSymbol && ts.forEach(symbol.declarations, hasExternalModuleSymbol)) && + // If a parent symbol is an anonymous type, don't write it. + !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral))) { - function createNameFromSymbol(symbol: Symbol, mustBeIdentifier: true): Identifier; - function createNameFromSymbol(symbol: Symbol, mustBeIdentifier?: false): EntityName; - function createNameFromSymbol(symbol: Symbol, mustBeIdentifier: boolean | undefined): EntityName { - let parentSymbol: Symbol; - let meaning: SymbolFlags; - - // Get qualified name if the symbol is not a type parameter - // and there is an enclosing declaration. - let chain: Symbol[]; - const isTypeParameter = symbol.flags & SymbolFlags.TypeParameter; - if (!isTypeParameter && enclosingDeclaration) { - chain = getSymbolChain(symbol, meaning, /*endOfChain*/ true); - // TODO: check whether type pointed to by symbol requires type arguments to be printed. - Debug.assert(chain && chain.length > 0); - } - else { - chain = [symbol]; - } - - parentSymbol = undefined; - if(mustBeIdentifier && chain.length !== 1) { - encounteredError = true; - // TODO: failing to get an identifier when we expect one generates an unprintable node. - // Should error handling be more severe? - } - return createEntityNameFromSymbolChain(chain, chain.length - 1); - - function createEntityNameFromSymbolChain(chain: Symbol[], index: number): EntityName { - Debug.assert(chain && 0 <= index && index < chain.length); - // const parentIndex = index - 1; - const symbol = chain[index]; - let typeParameterString = ""; - if(index > 0) { - // TODO: is the parentSymbol wrong? - const parentSymbol = chain[index - 1]; - let typeParameters: TypeParameter[]; - if(getCheckFlags(symbol) & CheckFlags.Instantiated) { - typeParameters = getTypeParametersOfClassOrInterface(parentSymbol); - } - else { - const targetSymbol = getTargetSymbol(parentSymbol); - if(targetSymbol.flags & (SymbolFlags.Class | SymbolFlags.Interface | SymbolFlags.TypeAlias)) { - typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); - } - } - if(typeParameters && typeParameters.length > 0) { - encounteredError = true; - const writer = getSingleLineStringWriter(); - const displayBuilder = getSymbolDisplayBuilder(); - displayBuilder.buildDisplayForTypeParametersAndDelimiters(typeParameters, writer, enclosingDeclaration, 0); - typeParameterString = writer.string(); - releaseStringWriter(writer); - - } - } - const symbolName = getNameOfSymbol(symbol); - const symbolNameWithTypeParameters = typeParameterString.length > 0 ? `${symbolName}<${typeParameterString}>` : symbolName; - let identifier = createIdentifier(symbolNameWithTypeParameters); - - return index > 0 ? createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier; - } - - /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */ - function getSymbolChain(symbol: Symbol, meaning: SymbolFlags, endOfChain: boolean): Symbol[] | undefined { - let accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, /*useOnlyExternalAliasing*/false); - - if (!accessibleSymbolChain || - needsQualification(accessibleSymbolChain[0], enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) { - - // Go up and add our parent. - const parent = getParentOfSymbol(accessibleSymbolChain ? accessibleSymbolChain[0] : symbol); - if (parent) { - const parentChain = getSymbolChain(parent, getQualifiedLeftMeaning(meaning), /*endOfChain*/ false); - if (parentChain) { - accessibleSymbolChain = parentChain.concat(accessibleSymbolChain || [symbol]); - } - } - } - - if (accessibleSymbolChain) { - return accessibleSymbolChain; - } - - else if ( - // If this is the last part of outputting the symbol, always output. The cases apply only to parent symbols. - endOfChain || - // If a parent symbol is an external module, don't write it. (We prefer just `x` vs `"foo/bar".x`.) - !(!parentSymbol && ts.forEach(symbol.declarations, hasExternalModuleSymbol)) && - // If a parent symbol is an anonymous type, don't write it. - !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral))) { - - return [symbol]; - } + return [symbol]; } } @@ -2673,7 +2727,7 @@ namespace ts { if (declaration.parent && declaration.parent.kind === SyntaxKind.VariableDeclaration) { return declarationNameToString((declaration.parent).name); } - encounteredError = true; + encounteredError = encounteredError || !(flags & NodeBuilderFlags.allowAnonymousIdentifier); switch (declaration.kind) { case SyntaxKind.ClassExpression: return "(Anonymous class)"; @@ -2687,26 +2741,6 @@ namespace ts { } } - function indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node): IndexSignatureDeclaration { - const indexerTypeNode = createKeywordTypeNode(kind === IndexKind.String ? SyntaxKind.StringKeyword : SyntaxKind.NumberKeyword); - - const name = getNameFromIndexInfo(indexInfo); - const indexingParameter = createParameter( - /*decorators*/ undefined, - /*modifiers*/ undefined, - /*dotDotDotToken*/ undefined, - name, - /*questionToken*/ undefined, - indexerTypeNode, - /*initializer*/ undefined); - const typeNode = typeToTypeNode(indexInfo.type, enclosingDeclaration); - return createIndexSignatureDeclaration( - [indexingParameter], - typeNode, - /*decorators*/ undefined, - indexInfo.isReadonly ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined); - } - function typePredicateToString(typePredicate: TypePredicate, enclosingDeclaration?: Declaration, flags?: TypeFormatFlags): string { const writer = getSingleLineStringWriter(); getSymbolDisplayBuilder().buildTypePredicateDisplay(typePredicate, writer, enclosingDeclaration, flags); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 5ccdd79f19..d6faf8cc64 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2473,11 +2473,11 @@ namespace ts { getNonNullableType(type: Type): Type; /** Note that the resulting nodes cannot be checked. */ - typeToTypeNode(type: Type, enclosingDeclaration: Node): TypeNode; + typeToTypeNode(type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeNode; /** Note that the resulting nodes cannot be checked. */ - indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node): IndexSignatureDeclaration; + signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): SignatureDeclaration; /** Note that the resulting nodes cannot be checked. */ - signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node): SignatureDeclaration; + indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration; getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; getSymbolAtLocation(node: Node): Symbol; @@ -2530,6 +2530,23 @@ namespace ts { /* @internal */ getTypeCount(): number; } + /** Note that any resulting nodes cannot be checked. */ + /* @internal */ + export interface NodeBuilder { + typeToTypeNode(type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeNode; + signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): SignatureDeclaration; + indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration; + } + + export enum NodeBuilderFlags { + None = 0, + allowUndefinedNode = 1 << 0, + allowThisInObjectLiteral = 1 << 1, + allowQualifedNameInPlaceOfIdentifier = 1 << 2, + allowTypeParameterInQualifiedName = 1 << 3, + allowAnonymousIdentifier = 1 << 4 + } + export interface SymbolDisplayBuilder { buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void; From dfb4df92c8f7e5d80af3213f27e70187dd9287a9 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Thu, 23 Mar 2017 11:17:25 -0700 Subject: [PATCH 127/164] move undefined handling to caller --- src/compiler/checker.ts | 44 ++++++++++++++++++++++------------------- src/compiler/types.ts | 9 ++++----- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c981d0673b..f996f738f1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2235,14 +2235,14 @@ namespace ts { let checkAlias = true; let symbolStack: Symbol[] = undefined; - return typeToTypeNodeWorker(type, flags); + return typeToTypeNodeWorker(type); - function typeToTypeNodeWorker(type: Type, flags: NodeBuilderFlags): TypeNode { + function typeToTypeNodeWorker(type: Type): TypeNode { if (!type) { - encounteredError = encounteredError || !(flags & NodeBuilderFlags.allowUndefinedNode); + encounteredError = true; + // TODO(aozgaa): should we return implict any (undefined) or explicit any (keywordtypenode)? return undefined; } - flags = flags & ~NodeBuilderFlags.allowUndefinedNode; if (type.flags & TypeFlags.Any) { return createKeywordTypeNode(SyntaxKind.AnyKeyword); @@ -2302,7 +2302,7 @@ namespace ts { if (objectFlags & ObjectFlags.Reference) { Debug.assert(!!(type.flags & TypeFlags.Object)); - return typeReferenceToTypeReferenceNode(type); + return typeReferenceToTypeNode (type); } if (objectFlags & ObjectFlags.ClassOrInterface) { Debug.assert(!!(type.flags & TypeFlags.Object)); @@ -2339,19 +2339,19 @@ namespace ts { if (type.flags & TypeFlags.Index) { const indexedType = (type).type; - const indexTypeNode = typeToTypeNodeWorker(indexedType, flags); + const indexTypeNode = typeToTypeNodeWorker(indexedType); return createTypeOperatorNode(indexTypeNode); } if (type.flags & TypeFlags.IndexedAccess) { - const objectTypeNode = typeToTypeNodeWorker((type).objectType, flags); - const indexTypeNode = typeToTypeNodeWorker((type).indexType, flags); + const objectTypeNode = typeToTypeNodeWorker((type).objectType); + const indexTypeNode = typeToTypeNodeWorker((type).indexType); return createIndexedAccessTypeNode(objectTypeNode, indexTypeNode); } Debug.fail("Should be unreachable."); function mapToTypeNodeArray(types: Type[]): NodeArray { - return types && asNodeArray(types.map(typeToTypeNodeWorker) as TypeNode[]); + return types && asNodeArray(types.map(typeToTypeNodeWorker).filter(node => !!node)); } function createMappedTypeNodeFromType(type: MappedType) { @@ -2359,7 +2359,8 @@ namespace ts { const typeParameter = getTypeParameterFromMappedType(type); const typeParameterNode = typeParameterToDeclaration(typeParameter, enclosingDeclaration, flags); - const templateTypeNode = typeToTypeNodeWorker(getTemplateTypeFromMappedType(type), flags | NodeBuilderFlags.allowUndefinedNode); + const templateType = getTemplateTypeFromMappedType(type) + const templateTypeNode = templateType && typeToTypeNodeWorker(templateType); const readonlyToken = (type).declaration && (type).declaration.readonlyToken ? createToken(SyntaxKind.ReadonlyKeyword) : undefined; const questionToken = (type).declaration && (type).declaration.questionToken ? createToken(SyntaxKind.QuestionToken) : undefined; @@ -2456,10 +2457,10 @@ namespace ts { } } - function typeReferenceToTypeReferenceNode(type: TypeReference) { + function typeReferenceToTypeNode(type: TypeReference) { const typeArguments: Type[] = type.typeArguments || emptyArray; if (type.target === globalArrayType) { - const elementType = typeToTypeNodeWorker(typeArguments[0], flags); + const elementType = typeToTypeNodeWorker(typeArguments[0]); return createArrayTypeNode(elementType); } else if (type.target.objectFlags & ObjectFlags.Tuple) { @@ -2547,10 +2548,12 @@ namespace ts { } } else { + // TODO(aozgaa): should we create a node with explicit or implict any? + const propertyTypeNode = propertyType ? typeToTypeNodeWorker(propertyType) : createKeywordTypeNode(SyntaxKind.AnyKeyword); typeElements.push(createPropertySignature( propertyName, optionalToken, - typeToTypeNodeWorker(propertyType, flags), + propertyTypeNode, /*initializer*/undefined)); } } @@ -2599,11 +2602,12 @@ namespace ts { return undefined; } - const constraint = typeToTypeNodeHelper(getConstraintFromTypeParameter(type), enclosingDeclaration, flags | NodeBuilderFlags.allowUndefinedNode); - const defaultParameter = typeToTypeNodeHelper(getDefaultFromTypeParameter(type), enclosingDeclaration, flags | NodeBuilderFlags.allowUndefinedNode); -; + const constraint = getConstraintFromTypeParameter(type); + const constraintNode = constraint && typeToTypeNodeHelper(constraint, enclosingDeclaration, flags); + const defaultParameter = getDefaultFromTypeParameter(type); + const defaultParameterNode = defaultParameter && typeToTypeNodeHelper(defaultParameter, enclosingDeclaration, flags); const name = symbolToName(type.symbol, enclosingDeclaration, /*mustBeIdentifier*/ true, flags); - return createTypeParameterDeclaration(name, constraint, defaultParameter); + return createTypeParameterDeclaration(name, constraintNode, defaultParameterNode); } function symbolToParameterDeclaration(parameterSymbol: Symbol, enclosingDeclaration: Node, flags: NodeBuilderFlags): ParameterDeclaration { @@ -2635,7 +2639,7 @@ namespace ts { const isTypeParameter = symbol.flags & SymbolFlags.TypeParameter; if (!isTypeParameter && enclosingDeclaration) { chain = getSymbolChain(symbol, meaning, /*endOfChain*/ true); - // TODO: check whether type pointed to by symbol requires type arguments to be printed. + // TODO(aozgaa): check whether type pointed to by symbol requires type arguments to be printed. Debug.assert(chain && chain.length > 0); } else { @@ -2645,7 +2649,7 @@ namespace ts { parentSymbol = undefined; if (mustBeIdentifier && chain.length !== 1) { encounteredError = encounteredError || !(flags & NodeBuilderFlags.allowQualifedNameInPlaceOfIdentifier); - // TODO: failing to get an identifier when we expect one generates an unprintable node. + // TODO(aozgaa): failing to get an identifier when we expect one generates an unprintable node. // Should error handling be more severe? } return createEntityNameFromSymbolChain(chain, chain.length - 1); @@ -2656,7 +2660,7 @@ namespace ts { const symbol = chain[index]; let typeParameterString = ""; if (index > 0) { - // TODO: is the parentSymbol wrong? + // TODO(aozgaa): is the parentSymbol wrong? const parentSymbol = chain[index - 1]; let typeParameters: TypeParameter[]; if (getCheckFlags(symbol) & CheckFlags.Instantiated) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d6faf8cc64..03569788d2 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2540,11 +2540,10 @@ namespace ts { export enum NodeBuilderFlags { None = 0, - allowUndefinedNode = 1 << 0, - allowThisInObjectLiteral = 1 << 1, - allowQualifedNameInPlaceOfIdentifier = 1 << 2, - allowTypeParameterInQualifiedName = 1 << 3, - allowAnonymousIdentifier = 1 << 4 + allowThisInObjectLiteral = 1 << 0, + allowQualifedNameInPlaceOfIdentifier = 1 << 1, + allowTypeParameterInQualifiedName = 1 << 2, + allowAnonymousIdentifier = 1 << 3 } export interface SymbolDisplayBuilder { From f4fc9ed61f2352e429ff7db24fd39d1c71c0f3c6 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 23 Mar 2017 11:23:13 -0700 Subject: [PATCH 128/164] Fix deeply nested type check --- src/compiler/checker.ts | 36 +++++++++++++++++++----------------- src/compiler/types.ts | 1 - 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 24ca7da87c..3ab09aff04 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8277,8 +8277,8 @@ namespace ts { maybeStack[depth].set(id, RelationComparisonResult.Succeeded); depth++; const saveExpandingFlags = expandingFlags; - if (!(expandingFlags & 1) && isDeeplyNestedGeneric(source, sourceStack, depth)) expandingFlags |= 1; - if (!(expandingFlags & 2) && isDeeplyNestedGeneric(target, targetStack, depth)) expandingFlags |= 2; + if (!(expandingFlags & 1) && isDeeplyNestedType(source, sourceStack, depth)) expandingFlags |= 1; + if (!(expandingFlags & 2) && isDeeplyNestedType(target, targetStack, depth)) expandingFlags |= 2; let result: Ternary; if (expandingFlags === 3) { result = Ternary.Maybe; @@ -8698,21 +8698,23 @@ namespace ts { return false; } - // Return true if the given type is part of a deeply nested chain of generic instantiations. We consider this to be the case - // when structural type comparisons have been started for 10 or more instantiations of the same generic type. It is possible, - // though highly unlikely, for this test to be true in a situation where a chain of instantiations is not infinitely expanding. - // Effectively, we will generate a false positive when two types are structurally equal to at least 10 levels, but unequal at - // some level beyond that. - function isDeeplyNestedGeneric(type: Type, stack: Type[], depth: number): boolean { - // We track type references (created by createTypeReference) and instantiated types (created by instantiateType) - if (getObjectFlags(type) & (ObjectFlags.Reference | ObjectFlags.Instantiated) && depth >= 5) { + // Return true if the given type is deeply nested. We consider this to be the case when structural type comparisons + // for 5 or more occurrences or instantiations of the type have been recorded on the given stack. It is possible, + // though highly unlikely, for this test to be true in a situation where a chain of instantiations is not infinitely + // expanding. Effectively, we will generate a false positive when two types are structurally equal to at least 5 + // levels, but unequal at some level beyond that. + function isDeeplyNestedType(type: Type, stack: Type[], depth: number): boolean { + // We track all object types that have an associated symbol (representing the origin of the type) + if (depth >= 5 && type.flags & TypeFlags.Object) { const symbol = type.symbol; - let count = 0; - for (let i = 0; i < depth; i++) { - const t = stack[i]; - if (getObjectFlags(t) & (ObjectFlags.Reference | ObjectFlags.Instantiated) && t.symbol === symbol) { - count++; - if (count >= 5) return true; + if (symbol) { + let count = 0; + for (let i = 0; i < depth; i++) { + const t = stack[i]; + if (t.flags & TypeFlags.Object && t.symbol === symbol) { + count++; + if (count >= 5) return true; + } } } } @@ -9455,7 +9457,7 @@ namespace ts { if (isInProcess(source, target)) { return; } - if (isDeeplyNestedGeneric(source, sourceStack, depth) && isDeeplyNestedGeneric(target, targetStack, depth)) { + if (isDeeplyNestedType(source, sourceStack, depth) && isDeeplyNestedType(target, targetStack, depth)) { return; } const key = source.id + "," + target.id; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 2377cd81f1..ceeb2922d4 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3014,7 +3014,6 @@ namespace ts { ObjectLiteral = 1 << 7, // Originates in an object literal EvolvingArray = 1 << 8, // Evolving array type ObjectLiteralPatternWithComputedProperties = 1 << 9, // Object literal pattern with computed properties - NonPrimitive = 1 << 10, // NonPrimitive object type ClassOrInterface = Class | Interface } From 5ea146334a14abf2f58232a261cea5a83a4652f7 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 23 Mar 2017 11:23:26 -0700 Subject: [PATCH 129/164] Add regression test --- tests/cases/compiler/deeplyNestedCheck.ts | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 tests/cases/compiler/deeplyNestedCheck.ts diff --git a/tests/cases/compiler/deeplyNestedCheck.ts b/tests/cases/compiler/deeplyNestedCheck.ts new file mode 100644 index 0000000000..e95233af98 --- /dev/null +++ b/tests/cases/compiler/deeplyNestedCheck.ts @@ -0,0 +1,9 @@ +// Repro from #14794 + +interface DataSnapshot { + child(path: string): DataSnapshot; +} + +interface Snapshot extends DataSnapshot { + child(path: U): Snapshot; +} From f139a6c58a6ea8df8f3561d8f342f625f1d4415e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 23 Mar 2017 11:24:01 -0700 Subject: [PATCH 130/164] Accept new baselines --- .../baselines/reference/deeplyNestedCheck.js | 14 +++++++++ .../reference/deeplyNestedCheck.symbols | 29 +++++++++++++++++++ .../reference/deeplyNestedCheck.types | 29 +++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 tests/baselines/reference/deeplyNestedCheck.js create mode 100644 tests/baselines/reference/deeplyNestedCheck.symbols create mode 100644 tests/baselines/reference/deeplyNestedCheck.types diff --git a/tests/baselines/reference/deeplyNestedCheck.js b/tests/baselines/reference/deeplyNestedCheck.js new file mode 100644 index 0000000000..466ae94f12 --- /dev/null +++ b/tests/baselines/reference/deeplyNestedCheck.js @@ -0,0 +1,14 @@ +//// [deeplyNestedCheck.ts] +// Repro from #14794 + +interface DataSnapshot { + child(path: string): DataSnapshot; +} + +interface Snapshot extends DataSnapshot { + child(path: U): Snapshot; +} + + +//// [deeplyNestedCheck.js] +// Repro from #14794 diff --git a/tests/baselines/reference/deeplyNestedCheck.symbols b/tests/baselines/reference/deeplyNestedCheck.symbols new file mode 100644 index 0000000000..a8b5af6088 --- /dev/null +++ b/tests/baselines/reference/deeplyNestedCheck.symbols @@ -0,0 +1,29 @@ +=== tests/cases/compiler/deeplyNestedCheck.ts === +// Repro from #14794 + +interface DataSnapshot { +>DataSnapshot : Symbol(DataSnapshot, Decl(deeplyNestedCheck.ts, 0, 0)) +>X : Symbol(X, Decl(deeplyNestedCheck.ts, 2, 23)) + + child(path: string): DataSnapshot; +>child : Symbol(DataSnapshot.child, Decl(deeplyNestedCheck.ts, 2, 32)) +>path : Symbol(path, Decl(deeplyNestedCheck.ts, 3, 8)) +>DataSnapshot : Symbol(DataSnapshot, Decl(deeplyNestedCheck.ts, 0, 0)) +} + +interface Snapshot extends DataSnapshot { +>Snapshot : Symbol(Snapshot, Decl(deeplyNestedCheck.ts, 4, 1)) +>T : Symbol(T, Decl(deeplyNestedCheck.ts, 6, 19)) +>DataSnapshot : Symbol(DataSnapshot, Decl(deeplyNestedCheck.ts, 0, 0)) + + child(path: U): Snapshot; +>child : Symbol(Snapshot.child, Decl(deeplyNestedCheck.ts, 6, 44)) +>U : Symbol(U, Decl(deeplyNestedCheck.ts, 7, 8)) +>T : Symbol(T, Decl(deeplyNestedCheck.ts, 6, 19)) +>path : Symbol(path, Decl(deeplyNestedCheck.ts, 7, 27)) +>U : Symbol(U, Decl(deeplyNestedCheck.ts, 7, 8)) +>Snapshot : Symbol(Snapshot, Decl(deeplyNestedCheck.ts, 4, 1)) +>T : Symbol(T, Decl(deeplyNestedCheck.ts, 6, 19)) +>U : Symbol(U, Decl(deeplyNestedCheck.ts, 7, 8)) +} + diff --git a/tests/baselines/reference/deeplyNestedCheck.types b/tests/baselines/reference/deeplyNestedCheck.types new file mode 100644 index 0000000000..e500fc75ed --- /dev/null +++ b/tests/baselines/reference/deeplyNestedCheck.types @@ -0,0 +1,29 @@ +=== tests/cases/compiler/deeplyNestedCheck.ts === +// Repro from #14794 + +interface DataSnapshot { +>DataSnapshot : DataSnapshot +>X : X + + child(path: string): DataSnapshot; +>child : (path: string) => DataSnapshot<{}> +>path : string +>DataSnapshot : DataSnapshot +} + +interface Snapshot extends DataSnapshot { +>Snapshot : Snapshot +>T : T +>DataSnapshot : DataSnapshot + + child(path: U): Snapshot; +>child : (path: U) => Snapshot +>U : U +>T : T +>path : U +>U : U +>Snapshot : Snapshot +>T : T +>U : U +} + From 8915cb9a0f5f12c03ddb054ab20f4a5eb00bbc7a Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Thu, 23 Mar 2017 13:36:38 -0700 Subject: [PATCH 131/164] Split signature factory methods --- src/compiler/factory.ts | 63 ++++++++++++++++++++++++------- src/compiler/visitor.ts | 35 ++++++++++++----- src/services/codefixes/helpers.ts | 8 ++-- 3 files changed, 79 insertions(+), 27 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 0ae4245970..0d2dee8cfd 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -378,28 +378,65 @@ namespace ts { } // TODO: Split according to AST nodes. - export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined): T; - export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined): T; - export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, name?: string | PropertyName, questionToken?: QuestionToken): T { - const signatureDeclaration = createSynthesizedNode(kind) as T; + export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) { + const signatureDeclaration = createSynthesizedNode(kind) as SignatureDeclaration; signatureDeclaration.typeParameters = asNodeArray(typeParameters); signatureDeclaration.parameters = asNodeArray(parameters); signatureDeclaration.type = type; - signatureDeclaration.name = asName(name); - signatureDeclaration.questionToken = questionToken; return signatureDeclaration; } - // TODO: figure out right type annotation for this function. - export function updateSignatureDeclaration(node: T, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): T; - export function updateSignatureDeclaration(node: T, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined, name: PropertyName, questionToken: QuestionToken | undefined): T; - export function updateSignatureDeclaration(node: T, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined, name?: PropertyName, questionToken?: QuestionToken): T { + export function updateSignatureDeclaration(node: SignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) { + return node.typeParameters !== typeParameters + || node.parameters !== parameters + || node.type !== type + ? updateNode(createSignatureDeclaration(node.kind, typeParameters, parameters, type), node) + : node; + } + + export function createFunctionTypeNode(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined): FunctionTypeNode { + return createSignatureDeclaration(SyntaxKind.FunctionType, typeParameters, parameters, type) as FunctionTypeNode; + } + + export function updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): FunctionTypeNode { + return updateSignatureDeclaration(node, typeParameters, parameters, type); + } + + export function createConstructorTypeNode(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined): ConstructorTypeNode { + return createSignatureDeclaration(SyntaxKind.ConstructorType, typeParameters, parameters, type) as ConstructorTypeNode; + } + export function updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): ConstructorTypeNode { + return updateSignatureDeclaration(node, typeParameters, parameters, type); + } + + export function createCallSignatureDeclaration(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined): CallSignatureDeclaration { + return createSignatureDeclaration(SyntaxKind.CallSignature, typeParameters, parameters, type) as CallSignatureDeclaration; + } + export function updateCallSignatureDeclaration(node: CallSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): CallSignatureDeclaration { + return updateSignatureDeclaration(node, typeParameters, parameters, type); + } + + export function createConstructSignatureDeclaration(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined): ConstructSignatureDeclaration { + return createSignatureDeclaration(SyntaxKind.ConstructSignature, typeParameters, parameters, type) as ConstructSignatureDeclaration; + } + export function updateConstructSignatureDeclaration(node: ConstructSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): ConstructSignatureDeclaration { + return updateSignatureDeclaration(node, typeParameters, parameters, type); + } + + export function createMethodSignature(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined): MethodSignature{ + const methodSignature = createSignatureDeclaration(SyntaxKind.MethodSignature, typeParameters, parameters, type) as MethodSignature; + methodSignature.name = asName(name); + methodSignature.questionToken = questionToken; + return methodSignature; + } + + export function updateMethodSignature(node: MethodSignature, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined, name?: PropertyName, questionToken?: QuestionToken): MethodSignature { return node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.name !== name || node.questionToken !== questionToken - ? updateNode(createSignatureDeclaration(node.kind, typeParameters, parameters, type, name, questionToken), node) + ? updateNode(createMethodSignature(typeParameters, parameters, type, name, questionToken), node) : node; } @@ -502,7 +539,7 @@ namespace ts { : node; } - export function createMethod(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) { + export function createMethodDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) { const node = createSynthesizedNode(SyntaxKind.MethodDeclaration); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); @@ -525,7 +562,7 @@ namespace ts { || node.parameters !== parameters || node.type !== type || node.body !== body - ? updateNode(createMethod(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body), node) + ? updateNode(createMethodDeclaration(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body), node) : node; } diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 57de104b0c..e6df9c211e 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -260,21 +260,36 @@ namespace ts { // Signatures and Signature Elements case SyntaxKind.FunctionType: + return updateFunctionTypeNode(node, + nodesVisitor((node).typeParameters, visitor, isTypeParameter), + visitParameterList((node).parameters, visitor, context, nodesVisitor), + visitNode((node).type, visitor, isTypeNode)); + case SyntaxKind.ConstructorType: + return updateConstructorTypeNode(node, + nodesVisitor((node).typeParameters, visitor, isTypeParameter), + visitParameterList((node).parameters, visitor, context, nodesVisitor), + visitNode((node).type, visitor, isTypeNode)); + case SyntaxKind.CallSignature: + return updateCallSignatureDeclaration(node, + nodesVisitor((node).typeParameters, visitor, isTypeParameter), + visitParameterList((node).parameters, visitor, context, nodesVisitor), + visitNode((node).type, visitor, isTypeNode)); + case SyntaxKind.ConstructSignature: - return updateSignatureDeclaration(node, - nodesVisitor((node).typeParameters, visitor, isTypeParameter), - visitParameterList((node).parameters, visitor, context, nodesVisitor), - visitNode((node).type, visitor, isTypeNode)); + return updateConstructSignatureDeclaration(node, + nodesVisitor((node).typeParameters, visitor, isTypeParameter), + visitParameterList((node).parameters, visitor, context, nodesVisitor), + visitNode((node).type, visitor, isTypeNode)); case SyntaxKind.MethodSignature: - return updateSignatureDeclaration(node, - nodesVisitor((node).typeParameters, visitor, isTypeParameter), - visitParameterList((node).parameters, visitor, context, nodesVisitor), - visitNode((node).type, visitor, isTypeNode), - visitNode((node).name, visitor, isPropertyName), - visitNode((node).questionToken, tokenVisitor, isToken)); + return updateMethodSignature(node, + nodesVisitor((node).typeParameters, visitor, isTypeParameter), + visitParameterList((node).parameters, visitor, context, nodesVisitor), + visitNode((node).type, visitor, isTypeNode), + visitNode((node).name, visitor, isPropertyName), + visitNode((node).questionToken, tokenVisitor, isToken)); case SyntaxKind.IndexSignature: return updateIndexSignatureDeclaration(node, diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index da72921508..0000bd97c5 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -100,7 +100,7 @@ namespace ts.codefix { if (declarations.length === 1) { Debug.assert(signatures.length === 1); const signature = signatures[0]; - const signatureDeclaration = checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration) as MethodDeclaration; + const signatureDeclaration = checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration); signatureDeclaration.modifiers = modifiers; signatureDeclaration.name = name; signatureDeclaration.questionToken = optional ? createToken(SyntaxKind.QuestionToken) : undefined; @@ -111,7 +111,7 @@ namespace ts.codefix { let signatureDeclarations = []; for (let i = 0; i < signatures.length; i++) { const signature = signatures[i]; - const signatureDeclaration = checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration) as MethodDeclaration; + const signatureDeclaration = checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration); signatureDeclaration.modifiers = modifiers; signatureDeclaration.name = name; signatureDeclaration.questionToken = optional ? createToken(SyntaxKind.QuestionToken) : undefined; @@ -120,7 +120,7 @@ namespace ts.codefix { if (declarations.length > signatures.length) { let signature = checker.getSignatureFromDeclaration(declarations[declarations.length - 1] as SignatureDeclaration); - const signatureDeclaration = checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration) as MethodDeclaration; + const signatureDeclaration = checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration); signatureDeclaration.modifiers = modifiers; signatureDeclaration.name = name; signatureDeclaration.questionToken = optional ? createToken(SyntaxKind.QuestionToken) : undefined; @@ -197,7 +197,7 @@ namespace ts.codefix { } export function createStubbedMethod(modifiers: Modifier[], name: PropertyName, optional: boolean, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], returnType: TypeNode | undefined) { - return createMethod( + return createMethodDeclaration( /*decorators*/ undefined, modifiers, /*asteriskToken*/ undefined, From ee7e9fc502ec45f93812ab0f4844a9765d7149a7 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Thu, 23 Mar 2017 14:00:49 -0700 Subject: [PATCH 132/164] handle todo's --- src/compiler/checker.ts | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f996f738f1..e98ac3be4d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2257,7 +2257,7 @@ namespace ts { return createKeywordTypeNode(SyntaxKind.BooleanKeyword); } if (type.flags & TypeFlags.Enum) { - const name = symbolToName(type.symbol, enclosingDeclaration, /*mustBeIdentifier*/ false, flags); + const name = symbolToName(type.symbol, enclosingDeclaration, /*expectsIdentifier*/ false, flags); return createTypeReferenceNode(name, /*typeArguments*/ undefined); } if (type.flags & (TypeFlags.StringLiteral)) { @@ -2270,7 +2270,7 @@ namespace ts { return (type).intrinsicName === "true" ? createTrue() : createFalse(); } if (type.flags & TypeFlags.EnumLiteral) { - const name = symbolToName(type.symbol, enclosingDeclaration, /*mustBeIdentifier*/ false, flags); + const name = symbolToName(type.symbol, enclosingDeclaration, /*expectsIdentifier*/ false, flags); return createTypeReferenceNode(name, /*typeArguments*/ undefined); } if (type.flags & TypeFlags.Void) { @@ -2306,18 +2306,18 @@ namespace ts { } if (objectFlags & ObjectFlags.ClassOrInterface) { Debug.assert(!!(type.flags & TypeFlags.Object)); - const name = symbolToName(type.symbol, enclosingDeclaration, /*mustBeIdentifier*/ false, flags); + const name = symbolToName(type.symbol, enclosingDeclaration, /*expectsIdentifier*/ false, flags); // TODO(aozgaa): handle type arguments. return createTypeReferenceNode(name, /*typeArguments*/ undefined); } if (type.flags & TypeFlags.TypeParameter) { - const name = symbolToName(type.symbol, enclosingDeclaration, /*mustBeIdentifier*/ false, flags); + const name = symbolToName(type.symbol, enclosingDeclaration, /*expectsIdentifier*/ false, flags); // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. return createTypeReferenceNode(name, /*typeArguments*/ undefined); } if (checkAlias && type.aliasSymbol) { - const name = symbolToName(type.aliasSymbol, enclosingDeclaration, /*mustBeIdentifier*/ false, flags); + const name = symbolToName(type.aliasSymbol, enclosingDeclaration, /*expectsIdentifier*/ false, flags); const typeArgumentNodes = mapToTypeNodeArray(type.aliasTypeArguments); return createTypeReferenceNode(name, typeArgumentNodes); } @@ -2381,7 +2381,7 @@ namespace ts { const typeAlias = getTypeAliasForTypeLiteral(type); if (typeAlias) { // The specified symbol flags need to be reinterpreted as type flags - const entityName = symbolToName(typeAlias, enclosingDeclaration, /*mustBeIdentifier*/ false, flags); + const entityName = symbolToName(typeAlias, enclosingDeclaration, /*expectsIdentifier*/ false, flags); return createTypeReferenceNode(entityName, /*typeArguments*/ undefined); } else { @@ -2452,7 +2452,7 @@ namespace ts { function createTypeQueryNodeFromType(type: Type) { const symbol = type.symbol; if (symbol) { - const entityName = symbolToName(symbol, enclosingDeclaration, /*mustBeIdentifier*/ false, flags); + const entityName = symbolToName(symbol, enclosingDeclaration, /*expectsIdentifier*/ false, flags); return createTypeQueryNode(entityName); } } @@ -2482,7 +2482,7 @@ namespace ts { // When type parameters are their own type arguments for the whole group (i.e. we have // the default outer type arguments), we don't show the group. if (!rangeEquals(outerTypeParameters, typeArguments, start, i)) { - const qualifiedNamePart = symbolToName(parent, enclosingDeclaration, /*mustBeIdentifier*/ true, flags); + const qualifiedNamePart = symbolToName(parent, enclosingDeclaration, /*expectsIdentifier*/ true, flags); if (!qualifiedName) { qualifiedName = createQualifiedName(qualifiedNamePart, /*right*/ undefined); } @@ -2495,7 +2495,7 @@ namespace ts { } } let entityName: EntityName = undefined; - const nameIdentifier = symbolToName(type.symbol, enclosingDeclaration, /*mustBeIdentifier*/ true, flags); + const nameIdentifier = symbolToName(type.symbol, enclosingDeclaration, /*expectsIdentifier*/ true, flags); if (qualifiedName) { Debug.assert(!qualifiedName.right); qualifiedName.right = nameIdentifier; @@ -2606,7 +2606,7 @@ namespace ts { const constraintNode = constraint && typeToTypeNodeHelper(constraint, enclosingDeclaration, flags); const defaultParameter = getDefaultFromTypeParameter(type); const defaultParameterNode = defaultParameter && typeToTypeNodeHelper(defaultParameter, enclosingDeclaration, flags); - const name = symbolToName(type.symbol, enclosingDeclaration, /*mustBeIdentifier*/ true, flags); + const name = symbolToName(type.symbol, enclosingDeclaration, /*expectsIdentifier*/ true, flags); return createTypeParameterDeclaration(name, constraintNode, defaultParameterNode); } @@ -2627,19 +2627,17 @@ namespace ts { return parameterNode; } - function symbolToName(symbol: Symbol, enclosingDeclaration: Node | undefined, mustBeIdentifier: true, flags: NodeBuilderFlags): Identifier; - function symbolToName(symbol: Symbol, enclosingDeclaration: Node, mustBeIdentifier: false, flags: NodeBuilderFlags): EntityName; - function symbolToName(symbol: Symbol, enclosingDeclaration: Node | undefined, mustBeIdentifier: boolean, flags: NodeBuilderFlags): EntityName { + function symbolToName(symbol: Symbol, enclosingDeclaration: Node | undefined, expectsIdentifier: true, flags: NodeBuilderFlags): Identifier; + function symbolToName(symbol: Symbol, enclosingDeclaration: Node | undefined, expectsIdentifier: false, flags: NodeBuilderFlags): EntityName; + function symbolToName(symbol: Symbol, enclosingDeclaration: Node | undefined, expectsIdentifier: boolean, flags: NodeBuilderFlags): EntityName { let parentSymbol: Symbol; let meaning: SymbolFlags; - // Get qualified name if the symbol is not a type parameter - // and there is an enclosing declaration. + // Try to get qualified name if the symbol is not a type parameter and there is an enclosing declaration. let chain: Symbol[]; const isTypeParameter = symbol.flags & SymbolFlags.TypeParameter; if (!isTypeParameter && enclosingDeclaration) { chain = getSymbolChain(symbol, meaning, /*endOfChain*/ true); - // TODO(aozgaa): check whether type pointed to by symbol requires type arguments to be printed. Debug.assert(chain && chain.length > 0); } else { @@ -2647,10 +2645,8 @@ namespace ts { } parentSymbol = undefined; - if (mustBeIdentifier && chain.length !== 1) { + if (expectsIdentifier && chain.length !== 1) { encounteredError = encounteredError || !(flags & NodeBuilderFlags.allowQualifedNameInPlaceOfIdentifier); - // TODO(aozgaa): failing to get an identifier when we expect one generates an unprintable node. - // Should error handling be more severe? } return createEntityNameFromSymbolChain(chain, chain.length - 1); @@ -2660,7 +2656,6 @@ namespace ts { const symbol = chain[index]; let typeParameterString = ""; if (index > 0) { - // TODO(aozgaa): is the parentSymbol wrong? const parentSymbol = chain[index - 1]; let typeParameters: TypeParameter[]; if (getCheckFlags(symbol) & CheckFlags.Instantiated) { From 5421812f1e1f3f926e01fd3bcd3a36aef75accad Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Thu, 23 Mar 2017 16:54:13 -0700 Subject: [PATCH 133/164] build builder --- src/compiler/checker.ts | 72 ++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 40 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b02b33e56b..9dd1fda7f5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -61,7 +61,7 @@ namespace ts { const noImplicitThis = compilerOptions.noImplicitThis === undefined ? compilerOptions.strict : compilerOptions.noImplicitThis; const emitResolver = createResolver(); - let nodeBuilderCache: NodeBuilder | undefined; + const nodeBuilder = getNodeBuilder(); const undefinedSymbol = createSymbol(SymbolFlags.Property, "undefined"); undefinedSymbol.declarations = []; @@ -107,9 +107,9 @@ namespace ts { getParameterType: getTypeAtPosition, getReturnTypeOfSignature, getNonNullableType, - typeToTypeNode: getNodeBuilder().typeToTypeNode, - indexInfoToIndexSignatureDeclaration: getNodeBuilder().indexInfoToIndexSignatureDeclaration, - signatureToSignatureDeclaration: getNodeBuilder().signatureToSignatureDeclaration, + typeToTypeNode: nodeBuilder.typeToTypeNode, + indexInfoToIndexSignatureDeclaration: nodeBuilder.indexInfoToIndexSignatureDeclaration, + signatureToSignatureDeclaration: nodeBuilder.signatureToSignatureDeclaration, getSymbolsInScope: (location, meaning) => { location = getParseTreeNode(location); return location ? getSymbolsInScope(location, meaning) : []; @@ -2203,43 +2203,36 @@ namespace ts { } function getNodeBuilder(): NodeBuilder { - if (nodeBuilderCache) { - return nodeBuilderCache; - } let encounteredError = false; - nodeBuilderCache = { - typeToTypeNode, - indexInfoToIndexSignatureDeclaration, - signatureToSignatureDeclaration + return { + typeToTypeNode: (type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags) => { + Debug.assert(encounteredError === false, "Nested call into nodeBuilder are forbidden."); + encounteredError = false; + const resultingNode = typeToTypeNodeHelper(type, enclosingDeclaration, flags); + const result = encounteredError ? undefined : resultingNode; + encounteredError = false; + return result; + }, + indexInfoToIndexSignatureDeclaration: (indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags) => { + Debug.assert(encounteredError === false, "Nested call into nodeBuilder are forbidden."); + encounteredError = false; + const resultingNode = indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, enclosingDeclaration, flags) + const result = encounteredError ? undefined : resultingNode; + encounteredError = false; + return result; + }, + signatureToSignatureDeclaration: (signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags) => { + Debug.assert(encounteredError === false, "Nested call into nodeBuilder are forbidden."); + encounteredError = false; + const resultingNode = signatureToSignatureDeclarationHelper(signature, kind, enclosingDeclaration, flags); + const result = encounteredError ? undefined : resultingNode; + encounteredError = false; + return result; + } }; - return nodeBuilderCache; - - function typeToTypeNode(type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeNode { - const helper = () => typeToTypeNodeHelper(type, enclosingDeclaration, flags); - return callHelperWithErrorHandling(helper); - } - - function indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration { - const helper = () => indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, enclosingDeclaration, flags); - return callHelperWithErrorHandling(helper); - } - - function signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): SignatureDeclaration { - const helper = () => signatureToSignatureDeclarationHelper(signature, kind, enclosingDeclaration, flags); - return callHelperWithErrorHandling(helper); - } - - function callHelperWithErrorHandling(nodeBuilderHelper: () => T): T | undefined { - const encounteredErrorCache = encounteredError; - const resultingNode = nodeBuilderHelper(); - const result = encounteredError ? undefined : resultingNode; - encounteredError = encounteredErrorCache; - return result; - } - function typeToTypeNodeHelper(type: Type, enclosingDeclaration: Node, flags: NodeBuilderFlags): TypeNode { let inObjectTypeLiteral = false; let checkAlias = true; @@ -2597,13 +2590,12 @@ namespace ts { const typeParameters = signature.typeParameters && signature.typeParameters.map(parameter => typeParameterToDeclaration(parameter, enclosingDeclaration, flags)); const parameters = signature.parameters.map(parameter => symbolToParameterDeclaration(parameter, enclosingDeclaration, flags)); - const type = typeToTypeNodeExceptAny(getReturnTypeOfSignature(signature)); + const returnTypeNode = typeToTypeNodeExceptAny(getReturnTypeOfSignature(signature)); - return createSignatureDeclaration(kind, typeParameters, parameters, type); + return createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNode); function typeToTypeNodeExceptAny(type: Type): TypeNode | undefined { - // Note, this call will *not* mark encounteredError. - const typeNode = typeToTypeNode(type, enclosingDeclaration); + const typeNode = type && typeToTypeNodeHelper(type, enclosingDeclaration, flags); return typeNode && typeNode.kind !== SyntaxKind.AnyKeyword ? typeNode : undefined; } } From ed1d5f45ca0ca1fce9a0829d4aac46fee4cdce65 Mon Sep 17 00:00:00 2001 From: rbuckton Date: Thu, 23 Mar 2017 19:16:00 -0700 Subject: [PATCH 134/164] Type parameter default is 'any' in js files --- src/compiler/checker.ts | 35 +-- .../reference/genericDefaultsJs.symbols | 226 ++++++++++++++++ .../reference/genericDefaultsJs.types | 254 ++++++++++++++++++ tests/cases/compiler/genericDefaultsJs.ts | 80 ++++++ 4 files changed, 579 insertions(+), 16 deletions(-) create mode 100644 tests/baselines/reference/genericDefaultsJs.symbols create mode 100644 tests/baselines/reference/genericDefaultsJs.types create mode 100644 tests/cases/compiler/genericDefaultsJs.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 24ca7da87c..86193a5807 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3993,14 +3993,15 @@ namespace ts { return getClassExtendsHeritageClauseElement(type.symbol.valueDeclaration); } - function getConstructorsForTypeArguments(type: Type, typeArgumentNodes: TypeNode[]): Signature[] { + function getConstructorsForTypeArguments(type: Type, typeArgumentNodes: TypeNode[], location: Node): Signature[] { const typeArgCount = length(typeArgumentNodes); + const isJavaScript = isInJavaScriptFile(location); return filter(getSignaturesOfType(type, SignatureKind.Construct), - sig => typeArgCount >= getMinTypeArgumentCount(sig.typeParameters) && typeArgCount <= length(sig.typeParameters)); + sig => (isJavaScript || typeArgCount >= getMinTypeArgumentCount(sig.typeParameters)) && typeArgCount <= length(sig.typeParameters)); } - function getInstantiatedConstructorsForTypeArguments(type: Type, typeArgumentNodes: TypeNode[]): Signature[] { - let signatures = getConstructorsForTypeArguments(type, typeArgumentNodes); + function getInstantiatedConstructorsForTypeArguments(type: Type, typeArgumentNodes: TypeNode[], location: Node): Signature[] { + let signatures = getConstructorsForTypeArguments(type, typeArgumentNodes, location); if (typeArgumentNodes) { const typeArguments = map(typeArgumentNodes, getTypeFromTypeNode); signatures = map(signatures, sig => getSignatureInstantiation(sig, typeArguments)); @@ -4083,7 +4084,7 @@ namespace ts { // The class derives from a "class-like" constructor function, check that we have at least one construct signature // with a matching number of type parameters and use the return type of the first instantiated signature. Elsewhere // we check that all instantiated signatures return the same type. - const constructors = getInstantiatedConstructorsForTypeArguments(baseConstructorType, baseTypeNode.typeArguments); + const constructors = getInstantiatedConstructorsForTypeArguments(baseConstructorType, baseTypeNode.typeArguments, baseTypeNode); if (!constructors.length) { error(baseTypeNode.expression, Diagnostics.No_base_constructor_has_the_specified_number_of_type_arguments); return; @@ -4593,14 +4594,15 @@ namespace ts { return [createSignature(undefined, classType.localTypeParameters, undefined, emptyArray, classType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false)]; } const baseTypeNode = getBaseTypeNodeOfClass(classType); + const isJavaScript = isInJavaScriptFile(baseTypeNode); const typeArguments = map(baseTypeNode.typeArguments, getTypeFromTypeNode); const typeArgCount = length(typeArguments); const result: Signature[] = []; for (const baseSig of baseSignatures) { const minTypeArgumentCount = getMinTypeArgumentCount(baseSig.typeParameters); const typeParamCount = length(baseSig.typeParameters); - if (typeArgCount >= minTypeArgumentCount && typeArgCount <= typeParamCount) { - const sig = typeParamCount ? createSignatureInstantiation(baseSig, fillMissingTypeArguments(typeArguments, baseSig.typeParameters, minTypeArgumentCount)) : cloneSignature(baseSig); + if ((isJavaScript || typeArgCount >= minTypeArgumentCount) && typeArgCount <= typeParamCount) { + const sig = typeParamCount ? createSignatureInstantiation(baseSig, fillMissingTypeArguments(typeArguments, baseSig.typeParameters, minTypeArgumentCount, baseTypeNode)) : cloneSignature(baseSig); sig.typeParameters = classType.localTypeParameters; sig.resolvedReturnType = classType; result.push(sig); @@ -5433,11 +5435,12 @@ namespace ts { * @param typeParameters The requested type parameters. * @param minTypeArgumentCount The minimum number of required type arguments. */ - function fillMissingTypeArguments(typeArguments: Type[] | undefined, typeParameters: TypeParameter[] | undefined, minTypeArgumentCount: number) { + function fillMissingTypeArguments(typeArguments: Type[] | undefined, typeParameters: TypeParameter[] | undefined, minTypeArgumentCount: number, location?: Node) { const numTypeParameters = length(typeParameters); if (numTypeParameters) { const numTypeArguments = length(typeArguments); - if (numTypeArguments >= minTypeArgumentCount && numTypeArguments <= numTypeParameters) { + const isJavaScript = isInJavaScriptFile(location); + if ((isJavaScript || numTypeArguments >= minTypeArgumentCount) && numTypeArguments <= numTypeParameters) { if (!typeArguments) { typeArguments = []; } @@ -5446,12 +5449,12 @@ namespace ts { // If a type parameter does not have a default type, or if the default type // is a forward reference, the empty object type is used. for (let i = numTypeArguments; i < numTypeParameters; i++) { - typeArguments[i] = emptyObjectType; + typeArguments[i] = isJavaScript ? anyType : emptyObjectType; } for (let i = numTypeArguments; i < numTypeParameters; i++) { const mapper = createTypeMapper(typeParameters, typeArguments); const defaultType = getDefaultFromTypeParameter(typeParameters[i]); - typeArguments[i] = defaultType ? instantiateType(defaultType, mapper) : emptyObjectType; + typeArguments[i] = defaultType ? instantiateType(defaultType, mapper) : isJavaScript ? anyType : emptyObjectType; } } } @@ -5825,7 +5828,7 @@ namespace ts { if (typeParameters) { const numTypeArguments = length(node.typeArguments); const minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); - if (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length) { + if (!isInJavaScriptFile(node) && (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length)) { error(node, minTypeArgumentCount === typeParameters.length ? Diagnostics.Generic_type_0_requires_1_type_argument_s @@ -5838,7 +5841,7 @@ namespace ts { // In a type reference, the outer type parameters of the referenced class or interface are automatically // supplied as type arguments and the type reference only specifies arguments for the local type parameters // of the class or interface. - const typeArguments = concatenate(type.outerTypeParameters, fillMissingTypeArguments(map(node.typeArguments, getTypeFromTypeNode), typeParameters, minTypeArgumentCount)); + const typeArguments = concatenate(type.outerTypeParameters, fillMissingTypeArguments(map(node.typeArguments, getTypeFromTypeNode), typeParameters, minTypeArgumentCount, node)); return createTypeReference(type, typeArguments); } if (node.typeArguments) { @@ -14481,7 +14484,7 @@ namespace ts { // with the type arguments specified in the extends clause. const baseTypeNode = getClassExtendsHeritageClauseElement(getContainingClass(node)); if (baseTypeNode) { - const baseConstructors = getInstantiatedConstructorsForTypeArguments(superType, baseTypeNode.typeArguments); + const baseConstructors = getInstantiatedConstructorsForTypeArguments(superType, baseTypeNode.typeArguments, baseTypeNode); return resolveCall(node, baseConstructors, candidatesOutArray); } } @@ -19595,7 +19598,7 @@ namespace ts { checkSourceElement(baseTypeNode.expression); if (baseTypeNode.typeArguments) { forEach(baseTypeNode.typeArguments, checkSourceElement); - for (const constructor of getConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments)) { + for (const constructor of getConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments, baseTypeNode)) { if (!checkTypeArgumentConstraints(constructor.typeParameters, baseTypeNode.typeArguments)) { break; } @@ -19613,7 +19616,7 @@ namespace ts { // that all instantiated base constructor signatures return the same type. We can simply compare the type // references (as opposed to checking the structure of the types) because elsewhere we have already checked // that the base type is a class or interface type (and not, for example, an anonymous object type). - const constructors = getInstantiatedConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments); + const constructors = getInstantiatedConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments, baseTypeNode); if (forEach(constructors, sig => getReturnTypeOfSignature(sig) !== baseType)) { error(baseTypeNode.expression, Diagnostics.Base_constructors_must_all_have_the_same_return_type); } diff --git a/tests/baselines/reference/genericDefaultsJs.symbols b/tests/baselines/reference/genericDefaultsJs.symbols new file mode 100644 index 0000000000..633e4cc8fe --- /dev/null +++ b/tests/baselines/reference/genericDefaultsJs.symbols @@ -0,0 +1,226 @@ +=== tests/cases/compiler/decls.d.ts === +declare function f0(x?: T): T; +>f0 : Symbol(f0, Decl(decls.d.ts, 0, 0)) +>T : Symbol(T, Decl(decls.d.ts, 0, 20)) +>x : Symbol(x, Decl(decls.d.ts, 0, 23)) +>T : Symbol(T, Decl(decls.d.ts, 0, 20)) +>T : Symbol(T, Decl(decls.d.ts, 0, 20)) + +declare function f1(x?: T): [T, U]; +>f1 : Symbol(f1, Decl(decls.d.ts, 0, 33)) +>T : Symbol(T, Decl(decls.d.ts, 1, 20)) +>U : Symbol(U, Decl(decls.d.ts, 1, 22)) +>x : Symbol(x, Decl(decls.d.ts, 1, 35)) +>T : Symbol(T, Decl(decls.d.ts, 1, 20)) +>T : Symbol(T, Decl(decls.d.ts, 1, 20)) +>U : Symbol(U, Decl(decls.d.ts, 1, 22)) + +declare class C0 { +>C0 : Symbol(C0, Decl(decls.d.ts, 1, 50)) +>T : Symbol(T, Decl(decls.d.ts, 2, 17)) + + y: T; +>y : Symbol(C0.y, Decl(decls.d.ts, 2, 21)) +>T : Symbol(T, Decl(decls.d.ts, 2, 17)) + + constructor(x?: T); +>x : Symbol(x, Decl(decls.d.ts, 4, 16)) +>T : Symbol(T, Decl(decls.d.ts, 2, 17)) +} +declare class C1 { +>C1 : Symbol(C1, Decl(decls.d.ts, 5, 1)) +>T : Symbol(T, Decl(decls.d.ts, 6, 17)) +>U : Symbol(U, Decl(decls.d.ts, 6, 19)) + + y: [T, U]; +>y : Symbol(C1.y, Decl(decls.d.ts, 6, 33)) +>T : Symbol(T, Decl(decls.d.ts, 6, 17)) +>U : Symbol(U, Decl(decls.d.ts, 6, 19)) + + constructor(x?: T); +>x : Symbol(x, Decl(decls.d.ts, 8, 16)) +>T : Symbol(T, Decl(decls.d.ts, 6, 17)) +} +=== tests/cases/compiler/main.js === +const f0_v0 = f0(); +>f0_v0 : Symbol(f0_v0, Decl(main.js, 0, 5)) +>f0 : Symbol(f0, Decl(decls.d.ts, 0, 0)) + +const f0_v1 = f0(1); +>f0_v1 : Symbol(f0_v1, Decl(main.js, 1, 5)) +>f0 : Symbol(f0, Decl(decls.d.ts, 0, 0)) + +const f1_c0 = f1(); +>f1_c0 : Symbol(f1_c0, Decl(main.js, 3, 5)) +>f1 : Symbol(f1, Decl(decls.d.ts, 0, 33)) + +const f1_c1 = f1(1); +>f1_c1 : Symbol(f1_c1, Decl(main.js, 4, 5)) +>f1 : Symbol(f1, Decl(decls.d.ts, 0, 33)) + +const C0_v0 = new C0(); +>C0_v0 : Symbol(C0_v0, Decl(main.js, 6, 5)) +>C0 : Symbol(C0, Decl(decls.d.ts, 1, 50)) + +const C0_v0_y = C0_v0.y; +>C0_v0_y : Symbol(C0_v0_y, Decl(main.js, 7, 5)) +>C0_v0.y : Symbol(C0.y, Decl(decls.d.ts, 2, 21)) +>C0_v0 : Symbol(C0_v0, Decl(main.js, 6, 5)) +>y : Symbol(C0.y, Decl(decls.d.ts, 2, 21)) + +const C0_v1 = new C0(1); +>C0_v1 : Symbol(C0_v1, Decl(main.js, 9, 5)) +>C0 : Symbol(C0, Decl(decls.d.ts, 1, 50)) + +const C0_v1_y = C0_v1.y; +>C0_v1_y : Symbol(C0_v1_y, Decl(main.js, 10, 5)) +>C0_v1.y : Symbol(C0.y, Decl(decls.d.ts, 2, 21)) +>C0_v1 : Symbol(C0_v1, Decl(main.js, 9, 5)) +>y : Symbol(C0.y, Decl(decls.d.ts, 2, 21)) + +const C1_v0 = new C1(); +>C1_v0 : Symbol(C1_v0, Decl(main.js, 12, 5)) +>C1 : Symbol(C1, Decl(decls.d.ts, 5, 1)) + +const C1_v0_y = C1_v0.y; +>C1_v0_y : Symbol(C1_v0_y, Decl(main.js, 13, 5)) +>C1_v0.y : Symbol(C1.y, Decl(decls.d.ts, 6, 33)) +>C1_v0 : Symbol(C1_v0, Decl(main.js, 12, 5)) +>y : Symbol(C1.y, Decl(decls.d.ts, 6, 33)) + +const C1_v1 = new C1(1); +>C1_v1 : Symbol(C1_v1, Decl(main.js, 15, 5)) +>C1 : Symbol(C1, Decl(decls.d.ts, 5, 1)) + +const C1_v1_y = C1_v1.y; +>C1_v1_y : Symbol(C1_v1_y, Decl(main.js, 16, 5)) +>C1_v1.y : Symbol(C1.y, Decl(decls.d.ts, 6, 33)) +>C1_v1 : Symbol(C1_v1, Decl(main.js, 15, 5)) +>y : Symbol(C1.y, Decl(decls.d.ts, 6, 33)) + +class C0_B0 extends C0 {} +>C0_B0 : Symbol(C0_B0, Decl(main.js, 16, 24)) +>C0 : Symbol(C0, Decl(decls.d.ts, 1, 50)) + +class C0_B1 extends C0 { +>C0_B1 : Symbol(C0_B1, Decl(main.js, 18, 25)) +>C0 : Symbol(C0, Decl(decls.d.ts, 1, 50)) + + constructor() { + super(); +>super : Symbol(C0, Decl(decls.d.ts, 1, 50)) + } +} +class C0_B2 extends C0 { +>C0_B2 : Symbol(C0_B2, Decl(main.js, 23, 1)) +>C0 : Symbol(C0, Decl(decls.d.ts, 1, 50)) + + constructor() { + super(1); +>super : Symbol(C0, Decl(decls.d.ts, 1, 50)) + } +} + +const C0_B0_v0 = new C0_B0(); +>C0_B0_v0 : Symbol(C0_B0_v0, Decl(main.js, 30, 5)) +>C0_B0 : Symbol(C0_B0, Decl(main.js, 16, 24)) + +const C0_B0_v0_y = C0_B0_v0.y; +>C0_B0_v0_y : Symbol(C0_B0_v0_y, Decl(main.js, 31, 5)) +>C0_B0_v0.y : Symbol(C0.y, Decl(decls.d.ts, 2, 21)) +>C0_B0_v0 : Symbol(C0_B0_v0, Decl(main.js, 30, 5)) +>y : Symbol(C0.y, Decl(decls.d.ts, 2, 21)) + +const C0_B0_v1 = new C0_B0(1); +>C0_B0_v1 : Symbol(C0_B0_v1, Decl(main.js, 33, 5)) +>C0_B0 : Symbol(C0_B0, Decl(main.js, 16, 24)) + +const C0_B0_v1_y = C0_B0_v1.y; +>C0_B0_v1_y : Symbol(C0_B0_v1_y, Decl(main.js, 34, 5)) +>C0_B0_v1.y : Symbol(C0.y, Decl(decls.d.ts, 2, 21)) +>C0_B0_v1 : Symbol(C0_B0_v1, Decl(main.js, 33, 5)) +>y : Symbol(C0.y, Decl(decls.d.ts, 2, 21)) + +const C0_B1_v0 = new C0_B1(); +>C0_B1_v0 : Symbol(C0_B1_v0, Decl(main.js, 36, 5)) +>C0_B1 : Symbol(C0_B1, Decl(main.js, 18, 25)) + +const C0_B1_v0_y = C0_B1_v0.y; +>C0_B1_v0_y : Symbol(C0_B1_v0_y, Decl(main.js, 37, 5)) +>C0_B1_v0.y : Symbol(C0.y, Decl(decls.d.ts, 2, 21)) +>C0_B1_v0 : Symbol(C0_B1_v0, Decl(main.js, 36, 5)) +>y : Symbol(C0.y, Decl(decls.d.ts, 2, 21)) + +const C0_B2_v0 = new C0_B2(); +>C0_B2_v0 : Symbol(C0_B2_v0, Decl(main.js, 39, 5)) +>C0_B2 : Symbol(C0_B2, Decl(main.js, 23, 1)) + +const C0_B2_v0_y = C0_B2_v0.y; +>C0_B2_v0_y : Symbol(C0_B2_v0_y, Decl(main.js, 40, 5)) +>C0_B2_v0.y : Symbol(C0.y, Decl(decls.d.ts, 2, 21)) +>C0_B2_v0 : Symbol(C0_B2_v0, Decl(main.js, 39, 5)) +>y : Symbol(C0.y, Decl(decls.d.ts, 2, 21)) + +class C1_B0 extends C1 {} +>C1_B0 : Symbol(C1_B0, Decl(main.js, 40, 30)) +>C1 : Symbol(C1, Decl(decls.d.ts, 5, 1)) + +class C1_B1 extends C1 { +>C1_B1 : Symbol(C1_B1, Decl(main.js, 42, 25)) +>C1 : Symbol(C1, Decl(decls.d.ts, 5, 1)) + + constructor() { + super(); +>super : Symbol(C1, Decl(decls.d.ts, 5, 1)) + } +} +class C1_B2 extends C1 { +>C1_B2 : Symbol(C1_B2, Decl(main.js, 47, 1)) +>C1 : Symbol(C1, Decl(decls.d.ts, 5, 1)) + + constructor() { + super(1); +>super : Symbol(C1, Decl(decls.d.ts, 5, 1)) + } +} + +const C1_B0_v0 = new C1_B0(); +>C1_B0_v0 : Symbol(C1_B0_v0, Decl(main.js, 54, 5)) +>C1_B0 : Symbol(C1_B0, Decl(main.js, 40, 30)) + +const C1_B0_v0_y = C1_B0_v0.y; +>C1_B0_v0_y : Symbol(C1_B0_v0_y, Decl(main.js, 55, 5)) +>C1_B0_v0.y : Symbol(C1.y, Decl(decls.d.ts, 6, 33)) +>C1_B0_v0 : Symbol(C1_B0_v0, Decl(main.js, 54, 5)) +>y : Symbol(C1.y, Decl(decls.d.ts, 6, 33)) + +const C1_B0_v1 = new C1_B0(1); +>C1_B0_v1 : Symbol(C1_B0_v1, Decl(main.js, 57, 5)) +>C1_B0 : Symbol(C1_B0, Decl(main.js, 40, 30)) + +const C1_B0_v1_y = C1_B0_v1.y; +>C1_B0_v1_y : Symbol(C1_B0_v1_y, Decl(main.js, 58, 5)) +>C1_B0_v1.y : Symbol(C1.y, Decl(decls.d.ts, 6, 33)) +>C1_B0_v1 : Symbol(C1_B0_v1, Decl(main.js, 57, 5)) +>y : Symbol(C1.y, Decl(decls.d.ts, 6, 33)) + +const C1_B1_v0 = new C1_B1(); +>C1_B1_v0 : Symbol(C1_B1_v0, Decl(main.js, 60, 5)) +>C1_B1 : Symbol(C1_B1, Decl(main.js, 42, 25)) + +const C1_B1_v0_y = C1_B1_v0.y; +>C1_B1_v0_y : Symbol(C1_B1_v0_y, Decl(main.js, 61, 5)) +>C1_B1_v0.y : Symbol(C1.y, Decl(decls.d.ts, 6, 33)) +>C1_B1_v0 : Symbol(C1_B1_v0, Decl(main.js, 60, 5)) +>y : Symbol(C1.y, Decl(decls.d.ts, 6, 33)) + +const C1_B2_v0 = new C1_B2(); +>C1_B2_v0 : Symbol(C1_B2_v0, Decl(main.js, 63, 5)) +>C1_B2 : Symbol(C1_B2, Decl(main.js, 47, 1)) + +const C1_B2_v0_y = C1_B2_v0.y; +>C1_B2_v0_y : Symbol(C1_B2_v0_y, Decl(main.js, 64, 5)) +>C1_B2_v0.y : Symbol(C1.y, Decl(decls.d.ts, 6, 33)) +>C1_B2_v0 : Symbol(C1_B2_v0, Decl(main.js, 63, 5)) +>y : Symbol(C1.y, Decl(decls.d.ts, 6, 33)) + diff --git a/tests/baselines/reference/genericDefaultsJs.types b/tests/baselines/reference/genericDefaultsJs.types new file mode 100644 index 0000000000..3275e757d7 --- /dev/null +++ b/tests/baselines/reference/genericDefaultsJs.types @@ -0,0 +1,254 @@ +=== tests/cases/compiler/decls.d.ts === +declare function f0(x?: T): T; +>f0 : (x?: T) => T +>T : T +>x : T +>T : T +>T : T + +declare function f1(x?: T): [T, U]; +>f1 : (x?: T) => [T, U] +>T : T +>U : U +>x : T +>T : T +>T : T +>U : U + +declare class C0 { +>C0 : C0 +>T : T + + y: T; +>y : T +>T : T + + constructor(x?: T); +>x : T +>T : T +} +declare class C1 { +>C1 : C1 +>T : T +>U : U + + y: [T, U]; +>y : [T, U] +>T : T +>U : U + + constructor(x?: T); +>x : T +>T : T +} +=== tests/cases/compiler/main.js === +const f0_v0 = f0(); +>f0_v0 : any +>f0() : any +>f0 : (x?: T) => T + +const f0_v1 = f0(1); +>f0_v1 : 1 +>f0(1) : 1 +>f0 : (x?: T) => T +>1 : 1 + +const f1_c0 = f1(); +>f1_c0 : [any, number] +>f1() : [any, number] +>f1 : (x?: T) => [T, U] + +const f1_c1 = f1(1); +>f1_c1 : [number, number] +>f1(1) : [number, number] +>f1 : (x?: T) => [T, U] +>1 : 1 + +const C0_v0 = new C0(); +>C0_v0 : C0 +>new C0() : C0 +>C0 : typeof C0 + +const C0_v0_y = C0_v0.y; +>C0_v0_y : any +>C0_v0.y : any +>C0_v0 : C0 +>y : any + +const C0_v1 = new C0(1); +>C0_v1 : C0 +>new C0(1) : C0 +>C0 : typeof C0 +>1 : 1 + +const C0_v1_y = C0_v1.y; +>C0_v1_y : number +>C0_v1.y : number +>C0_v1 : C0 +>y : number + +const C1_v0 = new C1(); +>C1_v0 : C1 +>new C1() : C1 +>C1 : typeof C1 + +const C1_v0_y = C1_v0.y; +>C1_v0_y : [any, number] +>C1_v0.y : [any, number] +>C1_v0 : C1 +>y : [any, number] + +const C1_v1 = new C1(1); +>C1_v1 : C1 +>new C1(1) : C1 +>C1 : typeof C1 +>1 : 1 + +const C1_v1_y = C1_v1.y; +>C1_v1_y : [number, number] +>C1_v1.y : [number, number] +>C1_v1 : C1 +>y : [number, number] + +class C0_B0 extends C0 {} +>C0_B0 : C0_B0 +>C0 : C0 + +class C0_B1 extends C0 { +>C0_B1 : C0_B1 +>C0 : C0 + + constructor() { + super(); +>super() : void +>super : typeof C0 + } +} +class C0_B2 extends C0 { +>C0_B2 : C0_B2 +>C0 : C0 + + constructor() { + super(1); +>super(1) : void +>super : typeof C0 +>1 : 1 + } +} + +const C0_B0_v0 = new C0_B0(); +>C0_B0_v0 : C0_B0 +>new C0_B0() : C0_B0 +>C0_B0 : typeof C0_B0 + +const C0_B0_v0_y = C0_B0_v0.y; +>C0_B0_v0_y : any +>C0_B0_v0.y : any +>C0_B0_v0 : C0_B0 +>y : any + +const C0_B0_v1 = new C0_B0(1); +>C0_B0_v1 : C0_B0 +>new C0_B0(1) : C0_B0 +>C0_B0 : typeof C0_B0 +>1 : 1 + +const C0_B0_v1_y = C0_B0_v1.y; +>C0_B0_v1_y : any +>C0_B0_v1.y : any +>C0_B0_v1 : C0_B0 +>y : any + +const C0_B1_v0 = new C0_B1(); +>C0_B1_v0 : C0_B1 +>new C0_B1() : C0_B1 +>C0_B1 : typeof C0_B1 + +const C0_B1_v0_y = C0_B1_v0.y; +>C0_B1_v0_y : any +>C0_B1_v0.y : any +>C0_B1_v0 : C0_B1 +>y : any + +const C0_B2_v0 = new C0_B2(); +>C0_B2_v0 : C0_B2 +>new C0_B2() : C0_B2 +>C0_B2 : typeof C0_B2 + +const C0_B2_v0_y = C0_B2_v0.y; +>C0_B2_v0_y : any +>C0_B2_v0.y : any +>C0_B2_v0 : C0_B2 +>y : any + +class C1_B0 extends C1 {} +>C1_B0 : C1_B0 +>C1 : C1 + +class C1_B1 extends C1 { +>C1_B1 : C1_B1 +>C1 : C1 + + constructor() { + super(); +>super() : void +>super : typeof C1 + } +} +class C1_B2 extends C1 { +>C1_B2 : C1_B2 +>C1 : C1 + + constructor() { + super(1); +>super(1) : void +>super : typeof C1 +>1 : 1 + } +} + +const C1_B0_v0 = new C1_B0(); +>C1_B0_v0 : C1_B0 +>new C1_B0() : C1_B0 +>C1_B0 : typeof C1_B0 + +const C1_B0_v0_y = C1_B0_v0.y; +>C1_B0_v0_y : [any, number] +>C1_B0_v0.y : [any, number] +>C1_B0_v0 : C1_B0 +>y : [any, number] + +const C1_B0_v1 = new C1_B0(1); +>C1_B0_v1 : C1_B0 +>new C1_B0(1) : C1_B0 +>C1_B0 : typeof C1_B0 +>1 : 1 + +const C1_B0_v1_y = C1_B0_v1.y; +>C1_B0_v1_y : [any, number] +>C1_B0_v1.y : [any, number] +>C1_B0_v1 : C1_B0 +>y : [any, number] + +const C1_B1_v0 = new C1_B1(); +>C1_B1_v0 : C1_B1 +>new C1_B1() : C1_B1 +>C1_B1 : typeof C1_B1 + +const C1_B1_v0_y = C1_B1_v0.y; +>C1_B1_v0_y : [any, number] +>C1_B1_v0.y : [any, number] +>C1_B1_v0 : C1_B1 +>y : [any, number] + +const C1_B2_v0 = new C1_B2(); +>C1_B2_v0 : C1_B2 +>new C1_B2() : C1_B2 +>C1_B2 : typeof C1_B2 + +const C1_B2_v0_y = C1_B2_v0.y; +>C1_B2_v0_y : [any, number] +>C1_B2_v0.y : [any, number] +>C1_B2_v0 : C1_B2 +>y : [any, number] + diff --git a/tests/cases/compiler/genericDefaultsJs.ts b/tests/cases/compiler/genericDefaultsJs.ts new file mode 100644 index 0000000000..6aa3640d96 --- /dev/null +++ b/tests/cases/compiler/genericDefaultsJs.ts @@ -0,0 +1,80 @@ +// @checkJs: true +// @allowJs: true +// @noEmit: true +// @filename: decls.d.ts +declare function f0(x?: T): T; +declare function f1(x?: T): [T, U]; +declare class C0 { + y: T; + constructor(x?: T); +} +declare class C1 { + y: [T, U]; + constructor(x?: T); +} +// @filename: main.js +const f0_v0 = f0(); +const f0_v1 = f0(1); + +const f1_c0 = f1(); +const f1_c1 = f1(1); + +const C0_v0 = new C0(); +const C0_v0_y = C0_v0.y; + +const C0_v1 = new C0(1); +const C0_v1_y = C0_v1.y; + +const C1_v0 = new C1(); +const C1_v0_y = C1_v0.y; + +const C1_v1 = new C1(1); +const C1_v1_y = C1_v1.y; + +class C0_B0 extends C0 {} +class C0_B1 extends C0 { + constructor() { + super(); + } +} +class C0_B2 extends C0 { + constructor() { + super(1); + } +} + +const C0_B0_v0 = new C0_B0(); +const C0_B0_v0_y = C0_B0_v0.y; + +const C0_B0_v1 = new C0_B0(1); +const C0_B0_v1_y = C0_B0_v1.y; + +const C0_B1_v0 = new C0_B1(); +const C0_B1_v0_y = C0_B1_v0.y; + +const C0_B2_v0 = new C0_B2(); +const C0_B2_v0_y = C0_B2_v0.y; + +class C1_B0 extends C1 {} +class C1_B1 extends C1 { + constructor() { + super(); + } +} +class C1_B2 extends C1 { + constructor() { + super(1); + } +} + +const C1_B0_v0 = new C1_B0(); +const C1_B0_v0_y = C1_B0_v0.y; + +const C1_B0_v1 = new C1_B0(1); +const C1_B0_v1_y = C1_B0_v1.y; + +const C1_B1_v0 = new C1_B1(); +const C1_B1_v0_y = C1_B1_v0.y; + +const C1_B2_v0 = new C1_B2(); +const C1_B2_v0_y = C1_B2_v0.y; From 6b5330f3432bc35dfb19963bfdc3cc317e495fdd Mon Sep 17 00:00:00 2001 From: Vadi Taslim Date: Fri, 24 Mar 2017 12:39:36 +0800 Subject: [PATCH 135/164] Bug fix for issue #14696, things changed are; - Empty class type will now throw an error, - Trailing comma in class type will also throw an error, - Added tests for empty class type parameter, - Updated tests for class type parameters with trailing comma This behavior is consistently following function or method like when its type parameter is either empty or has trailing comma. --- src/compiler/checker.ts | 7 ++++++- .../reference/classWithEmptyTypeParameter.errors.txt | 8 ++++++++ .../baselines/reference/classWithEmptyTypeParameter.js | 10 ++++++++++ .../typeParameterListWithTrailingComma1.errors.txt | 8 ++++++++ tests/cases/compiler/classWithEmptyTypeParameter.ts | 2 ++ 5 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/classWithEmptyTypeParameter.errors.txt create mode 100644 tests/baselines/reference/classWithEmptyTypeParameter.js create mode 100644 tests/baselines/reference/typeParameterListWithTrailingComma1.errors.txt create mode 100644 tests/cases/compiler/classWithEmptyTypeParameter.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 70cbda14f6..448a15e513 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19559,7 +19559,7 @@ namespace ts { } function checkClassLikeDeclaration(node: ClassLikeDeclaration) { - checkGrammarClassDeclarationHeritageClauses(node); + checkGrammarClassLikeDeclaration(node); checkDecorators(node); if (node.name) { checkTypeNameIsReserved(node.name, Diagnostics.Class_name_cannot_be_0); @@ -22520,6 +22520,11 @@ namespace ts { checkGrammarParameterList(node.parameters) || checkGrammarArrowFunction(node, file); } + function checkGrammarClassLikeDeclaration(node: ClassLikeDeclaration): boolean { + const file = getSourceFileOfNode(node); + return checkGrammarClassDeclarationHeritageClauses(node) || checkGrammarTypeParameterList(node.typeParameters, file); + } + function checkGrammarArrowFunction(node: FunctionLikeDeclaration, file: SourceFile): boolean { if (node.kind === SyntaxKind.ArrowFunction) { const arrowFunction = node; diff --git a/tests/baselines/reference/classWithEmptyTypeParameter.errors.txt b/tests/baselines/reference/classWithEmptyTypeParameter.errors.txt new file mode 100644 index 0000000000..8114bbd7ba --- /dev/null +++ b/tests/baselines/reference/classWithEmptyTypeParameter.errors.txt @@ -0,0 +1,8 @@ +tests/cases/compiler/classWithEmptyTypeParameter.ts(1,8): error TS1098: Type parameter list cannot be empty. + + +==== tests/cases/compiler/classWithEmptyTypeParameter.ts (1 errors) ==== + class C<> { + ~~ +!!! error TS1098: Type parameter list cannot be empty. + } \ No newline at end of file diff --git a/tests/baselines/reference/classWithEmptyTypeParameter.js b/tests/baselines/reference/classWithEmptyTypeParameter.js new file mode 100644 index 0000000000..c25ace495b --- /dev/null +++ b/tests/baselines/reference/classWithEmptyTypeParameter.js @@ -0,0 +1,10 @@ +//// [classWithEmptyTypeParameter.ts] +class C<> { +} + +//// [classWithEmptyTypeParameter.js] +var C = (function () { + function C() { + } + return C; +}()); diff --git a/tests/baselines/reference/typeParameterListWithTrailingComma1.errors.txt b/tests/baselines/reference/typeParameterListWithTrailingComma1.errors.txt new file mode 100644 index 0000000000..ac20e82696 --- /dev/null +++ b/tests/baselines/reference/typeParameterListWithTrailingComma1.errors.txt @@ -0,0 +1,8 @@ +tests/cases/compiler/typeParameterListWithTrailingComma1.ts(1,10): error TS1009: Trailing comma not allowed. + + +==== tests/cases/compiler/typeParameterListWithTrailingComma1.ts (1 errors) ==== + class C { + ~ +!!! error TS1009: Trailing comma not allowed. + } \ No newline at end of file diff --git a/tests/cases/compiler/classWithEmptyTypeParameter.ts b/tests/cases/compiler/classWithEmptyTypeParameter.ts new file mode 100644 index 0000000000..42541c8e46 --- /dev/null +++ b/tests/cases/compiler/classWithEmptyTypeParameter.ts @@ -0,0 +1,2 @@ +class C<> { +} \ No newline at end of file From 25d8367aaf5b79b5852c80d2387e9809b0e5e377 Mon Sep 17 00:00:00 2001 From: Bill Ticehurst Date: Tue, 21 Mar 2017 14:49:20 -0700 Subject: [PATCH 136/164] Suppress semantic errors in JS only configured projects (cherry picked from commit 4ee8bdb762f870351da9be51d13dae6c9328e72f) --- src/server/session.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/server/session.ts b/src/server/session.ts index 8dd0411d07..11c99dfe46 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -25,8 +25,14 @@ namespace ts.server { return ((1e9 * seconds) + nanoseconds) / 1000000.0; } - function shouldSkipSematicCheck(project: Project) { - return (project.projectKind === ProjectKind.Inferred || project.projectKind === ProjectKind.External) && project.isJsOnlyProject(); + function shouldSkipSemanticCheck(project: Project) { + if (project.projectKind === ProjectKind.Inferred || project.projectKind === ProjectKind.External) { + return project.isJsOnlyProject(); + } + else { + // For configured projects, require that skipLibCheck be set also + return project.getCompilerOptions().skipLibCheck && project.isJsOnlyProject(); + } } interface FileStart { @@ -447,7 +453,7 @@ namespace ts.server { private semanticCheck(file: NormalizedPath, project: Project) { try { let diags: Diagnostic[] = []; - if (!shouldSkipSematicCheck(project)) { + if (!shouldSkipSemanticCheck(project)) { diags = project.getLanguageService().getSemanticDiagnostics(file); } @@ -555,7 +561,7 @@ namespace ts.server { private getDiagnosticsWorker(args: protocol.FileRequestArgs, isSemantic: boolean, selector: (project: Project, file: string) => Diagnostic[], includeLinePosition: boolean) { const { project, file } = this.getFileAndProject(args); - if (isSemantic && shouldSkipSematicCheck(project)) { + if (isSemantic && shouldSkipSemanticCheck(project)) { return []; } const scriptInfo = project.getScriptInfoForNormalizedPath(file); From 71e296042aa4495308456d2797837dd543bd450f Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 17 Mar 2017 12:56:31 -0700 Subject: [PATCH 137/164] Apply the 20 MB non-TS source limit across all projects (cherry picked from commit cc8ce5975cbda492834d43ec1b743126a3334df4) (cherry picked from commit de8fb9e8335d9bf34d0bbd5e61fee4df40cb5222) --- src/server/editorServices.ts | 25 +++++++++++++++++++------ src/server/project.ts | 2 +- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 397de9ead3..3252e2114a 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -254,6 +254,7 @@ namespace ts.server { private compilerOptionsForInferredProjects: CompilerOptions; private compileOnSaveForInferredProjects: boolean; + private readonly projectToSizeMap: Map = createMap(); private readonly directoryWatchers: DirectoryWatchers; private readonly throttledOperations: ThrottledOperations; @@ -563,9 +564,11 @@ namespace ts.server { switch (project.projectKind) { case ProjectKind.External: removeItemFromSet(this.externalProjects, project); + this.projectToSizeMap.delete((project as ExternalProject).externalProjectName); break; case ProjectKind.Configured: removeItemFromSet(this.configuredProjects, project); + this.projectToSizeMap.delete((project as ConfiguredProject).canonicalConfigFilePath); break; case ProjectKind.Inferred: removeItemFromSet(this.inferredProjects, project); @@ -852,10 +855,17 @@ namespace ts.server { return { success: true, projectOptions, configFileErrors: errors }; } - private exceededTotalSizeLimitForNonTsFiles(options: CompilerOptions, fileNames: T[], propertyReader: FilePropertyReader) { + private exceededTotalSizeLimitForNonTsFiles(name: string, options: CompilerOptions, fileNames: T[], propertyReader: FilePropertyReader) { if (options && options.disableSizeLimit || !this.host.getFileSize) { return false; } + + let availableSpace = maxProgramSizeForNonTsFiles; + this.projectToSizeMap.set(name, 0); + this.projectToSizeMap.forEach(size => { + availableSpace -= size; + }); + let totalNonTsFileSize = 0; for (const f of fileNames) { const fileName = propertyReader.getFileName(f); @@ -863,10 +873,13 @@ namespace ts.server { continue; } totalNonTsFileSize += this.host.getFileSize(fileName); - if (totalNonTsFileSize > maxProgramSizeForNonTsFiles) { + if (totalNonTsFileSize > availableSpace) { + this.projectToSizeMap.set(name, totalNonTsFileSize); return true; } } + + this.projectToSizeMap.set(name, totalNonTsFileSize); return false; } @@ -877,7 +890,7 @@ namespace ts.server { this, this.documentRegistry, compilerOptions, - /*languageServiceEnabled*/ !this.exceededTotalSizeLimitForNonTsFiles(compilerOptions, files, externalFilePropertyReader), + /*languageServiceEnabled*/ !this.exceededTotalSizeLimitForNonTsFiles(projectFileName, compilerOptions, files, externalFilePropertyReader), options.compileOnSave === undefined ? true : options.compileOnSave); this.addFilesToProjectAndUpdateGraph(project, files, externalFilePropertyReader, /*clientFileName*/ undefined, typeAcquisition, /*configFileErrors*/ undefined); @@ -897,7 +910,7 @@ namespace ts.server { } private createAndAddConfiguredProject(configFileName: NormalizedPath, projectOptions: ProjectOptions, configFileErrors: Diagnostic[], clientFileName?: string) { - const sizeLimitExceeded = this.exceededTotalSizeLimitForNonTsFiles(projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader); + const sizeLimitExceeded = this.exceededTotalSizeLimitForNonTsFiles(configFileName, projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader); const project = new ConfiguredProject( configFileName, this, @@ -1050,7 +1063,7 @@ namespace ts.server { return configFileErrors; } - if (this.exceededTotalSizeLimitForNonTsFiles(projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader)) { + if (this.exceededTotalSizeLimitForNonTsFiles(project.canonicalConfigFilePath, projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader)) { project.setCompilerOptions(projectOptions.compilerOptions); if (!project.languageServiceEnabled) { // language service is already disabled @@ -1414,7 +1427,7 @@ namespace ts.server { if (externalProject) { if (!tsConfigFiles) { const compilerOptions = convertCompilerOptions(proj.options); - if (this.exceededTotalSizeLimitForNonTsFiles(compilerOptions, proj.rootFiles, externalFilePropertyReader)) { + if (this.exceededTotalSizeLimitForNonTsFiles(proj.projectFileName, compilerOptions, proj.rootFiles, externalFilePropertyReader)) { externalProject.disableLanguageService(); } else { diff --git a/src/server/project.ts b/src/server/project.ts index 385816b102..e57e605d65 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1031,7 +1031,7 @@ namespace ts.server { export class ExternalProject extends Project { private typeAcquisition: TypeAcquisition; - constructor(externalProjectName: string, + constructor(public externalProjectName: string, projectService: ProjectService, documentRegistry: ts.DocumentRegistry, compilerOptions: CompilerOptions, From afbe63ae990577a4d3ce603b4ab78f7095636a29 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 17 Mar 2017 15:36:15 -0700 Subject: [PATCH 138/164] Make compatible with 2.1 maps # Conflicts: # src/server/editorServices.ts # src/server/project.ts (cherry picked from commit 456614f7e0d8ac0f5d420a6caf42f57cf5dda313) (cherry picked from commit be30adc77f450a4871045c48d7d614c196fe37a5) --- src/server/editorServices.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 3252e2114a..196df1a2cb 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -564,11 +564,11 @@ namespace ts.server { switch (project.projectKind) { case ProjectKind.External: removeItemFromSet(this.externalProjects, project); - this.projectToSizeMap.delete((project as ExternalProject).externalProjectName); + delete this.projectToSizeMap[(project as ExternalProject).externalProjectName]; break; case ProjectKind.Configured: removeItemFromSet(this.configuredProjects, project); - this.projectToSizeMap.delete((project as ConfiguredProject).canonicalConfigFilePath); + delete this.projectToSizeMap[(project as ConfiguredProject).canonicalConfigFilePath]; break; case ProjectKind.Inferred: removeItemFromSet(this.inferredProjects, project); @@ -861,10 +861,10 @@ namespace ts.server { } let availableSpace = maxProgramSizeForNonTsFiles; - this.projectToSizeMap.set(name, 0); - this.projectToSizeMap.forEach(size => { - availableSpace -= size; - }); + this.projectToSizeMap[name] = 0; + for (const key in this.projectToSizeMap) { + availableSpace -= (this.projectToSizeMap[key] || 0); + } let totalNonTsFileSize = 0; for (const f of fileNames) { @@ -874,12 +874,12 @@ namespace ts.server { } totalNonTsFileSize += this.host.getFileSize(fileName); if (totalNonTsFileSize > availableSpace) { - this.projectToSizeMap.set(name, totalNonTsFileSize); + this.projectToSizeMap[name] = totalNonTsFileSize; return true; } } - this.projectToSizeMap.set(name, totalNonTsFileSize); + this.projectToSizeMap[name] = totalNonTsFileSize; return false; } From d69a18d9d971872fe14341755e1259e988a49117 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 21 Mar 2017 11:37:22 -0700 Subject: [PATCH 139/164] Store the size of the project properly (cherry picked from commit 16c7bcfebbeb8490a86dd994167283414d9d43a0) (cherry picked from commit 8b3c54dbfb04c084061c287a342e7e6ffa0f0612) --- src/server/editorServices.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 196df1a2cb..5c7dfcae64 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -873,14 +873,14 @@ namespace ts.server { continue; } totalNonTsFileSize += this.host.getFileSize(fileName); - if (totalNonTsFileSize > availableSpace) { + if (totalNonTsFileSize > maxProgramSizeForNonTsFiles) { this.projectToSizeMap[name] = totalNonTsFileSize; return true; } } this.projectToSizeMap[name] = totalNonTsFileSize; - return false; + return totalNonTsFileSize < availableSpace; } private createAndAddExternalProject(projectFileName: string, files: protocol.ExternalFile[], options: protocol.ExternalProjectCompilerOptions, typeAcquisition: TypeAcquisition) { From 5b7a099aa6ad568a57347f1cd4c3b0f37979a74a Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 21 Mar 2017 11:41:58 -0700 Subject: [PATCH 140/164] Math (cherry picked from commit 7b17f6affecd6fb5e478607bf43e4cc29edf3f45) (cherry picked from commit 63aeacb83f2c00eef903bb6d2f39d3aa6b72254d) --- src/server/editorServices.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 5c7dfcae64..1bdf68fe08 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -880,7 +880,7 @@ namespace ts.server { } this.projectToSizeMap[name] = totalNonTsFileSize; - return totalNonTsFileSize < availableSpace; + return totalNonTsFileSize > availableSpace; } private createAndAddExternalProject(projectFileName: string, files: protocol.ExternalFile[], options: protocol.ExternalProjectCompilerOptions, typeAcquisition: TypeAcquisition) { From 390e63200a85dd52649f7fad509555e3e7117d2d Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 21 Mar 2017 12:08:51 -0700 Subject: [PATCH 141/164] Add unit test (cherry picked from commit ff0947996c03c07a7d2c1d8fdaf25e60dce6039c) (cherry picked from commit c66a5359e2bdc45b0a37941f614dda40661ae2cd) --- .../unittests/tsserverProjectSystem.ts | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 5ea0df91ca..356a7a8962 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -1007,6 +1007,41 @@ namespace ts.projectSystem { checkProjectRootFiles(projectService.configuredProjects[0], [commonFile1.path, commonFile2.path]); }); + it("should disable features when the files are too large", () => { + const file1 = { + path: "/a/b/f1.js", + content: "let x =1;", + fileSize: 10 * 1024 * 1024 + }; + const file2 = { + path: "/a/b/f2.js", + content: "let y =1;", + fileSize: 6 * 1024 * 1024 + }; + const file3 = { + path: "/a/b/f3.js", + content: "let y =1;", + fileSize: 6 * 1024 * 1024 + }; + + const proj1name = "proj1", proj2name = "proj2", proj3name = "proj3"; + + const host = createServerHost([file1, file2, file3]); + const projectService = createProjectService(host); + + projectService.openExternalProject({ rootFiles: toExternalFiles([file1.path]), options: {}, projectFileName: proj1name }); + const proj1 = projectService.findProject(proj1name); + assert.isTrue(proj1.languageServiceEnabled); + + projectService.openExternalProject({ rootFiles: toExternalFiles([file2.path]), options: {}, projectFileName: proj2name }); + const proj2 = projectService.findProject(proj2name); + assert.isTrue(proj2.languageServiceEnabled); + + projectService.openExternalProject({ rootFiles: toExternalFiles([file3.path]), options: {}, projectFileName: proj3name }); + const proj3 = projectService.findProject(proj3name); + assert.isFalse(proj3.languageServiceEnabled); + }); + it("should use only one inferred project if 'useOneInferredProject' is set", () => { const file1 = { path: "/a/b/main.ts", From e5313bda21180a6bad7023e258d7b27b64d9197d Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 21 Mar 2017 13:01:06 -0700 Subject: [PATCH 142/164] Don't add in size of disabled projects (cherry picked from commit 2721a8c8b4fcacc551e68594964ea581b713f83c) (cherry picked from commit 1696df6c9eca388b72b73a1e1897ab9b85080a7e) --- src/server/editorServices.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 1bdf68fe08..c4c299a067 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -874,7 +874,7 @@ namespace ts.server { } totalNonTsFileSize += this.host.getFileSize(fileName); if (totalNonTsFileSize > maxProgramSizeForNonTsFiles) { - this.projectToSizeMap[name] = totalNonTsFileSize; + // Keep the size as zero since it's disabled return true; } } From eef0505f55b37999d8d37f22dfd4a142b5372950 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 21 Mar 2017 16:02:54 -0700 Subject: [PATCH 143/164] Store diabled projects as 0 (cherry picked from commit e9e7271fc3ab50654cb234c813e46fc90d70a736) (cherry picked from commit 35e77171e98d134c64ae1000d94b1be317879a05) --- src/server/editorServices.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index c4c299a067..291fa83d60 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -879,8 +879,12 @@ namespace ts.server { } } + if (totalNonTsFileSize > availableSpace) { + return true; + } + this.projectToSizeMap[name] = totalNonTsFileSize; - return totalNonTsFileSize > availableSpace; + return false; } private createAndAddExternalProject(projectFileName: string, files: protocol.ExternalFile[], options: protocol.ExternalProjectCompilerOptions, typeAcquisition: TypeAcquisition) { From 21c954717c6cdafa2d689f88d63aff572ad5d38d Mon Sep 17 00:00:00 2001 From: Bill Ticehurst Date: Wed, 22 Mar 2017 19:48:20 -0700 Subject: [PATCH 144/164] Changes for Map implementation (cherry picked from commit 8a67b6ddd43bdb33c89c1877d2755b738cb4c4c1) --- src/server/editorServices.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 291fa83d60..8af6fe5d34 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -564,11 +564,11 @@ namespace ts.server { switch (project.projectKind) { case ProjectKind.External: removeItemFromSet(this.externalProjects, project); - delete this.projectToSizeMap[(project as ExternalProject).externalProjectName]; + this.projectToSizeMap.delete((project as ExternalProject).externalProjectName); break; case ProjectKind.Configured: removeItemFromSet(this.configuredProjects, project); - delete this.projectToSizeMap[(project as ConfiguredProject).canonicalConfigFilePath]; + this.projectToSizeMap.delete((project as ConfiguredProject).canonicalConfigFilePath); break; case ProjectKind.Inferred: removeItemFromSet(this.inferredProjects, project); @@ -861,10 +861,8 @@ namespace ts.server { } let availableSpace = maxProgramSizeForNonTsFiles; - this.projectToSizeMap[name] = 0; - for (const key in this.projectToSizeMap) { - availableSpace -= (this.projectToSizeMap[key] || 0); - } + this.projectToSizeMap.set(name, 0); + this.projectToSizeMap.forEach(val => (availableSpace -= (val || 0))); let totalNonTsFileSize = 0; for (const f of fileNames) { @@ -883,7 +881,7 @@ namespace ts.server { return true; } - this.projectToSizeMap[name] = totalNonTsFileSize; + this.projectToSizeMap.set(name, totalNonTsFileSize); return false; } From a7c166c4a5ecea91565c7512aa0ea0b7f0c70efb Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Fri, 24 Mar 2017 12:56:54 -0700 Subject: [PATCH 145/164] optional signature --- src/compiler/checker.ts | 4 +- src/services/codefixes/helpers.ts | 41 ++++++++++--------- ...ClassImplementClassMemberAnonymousClass.ts | 9 +--- 3 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9dd1fda7f5..7c5e8153a6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2218,7 +2218,7 @@ namespace ts { indexInfoToIndexSignatureDeclaration: (indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags) => { Debug.assert(encounteredError === false, "Nested call into nodeBuilder are forbidden."); encounteredError = false; - const resultingNode = indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, enclosingDeclaration, flags) + const resultingNode = indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, enclosingDeclaration, flags); const result = encounteredError ? undefined : resultingNode; encounteredError = false; return result; @@ -2568,8 +2568,8 @@ namespace ts { function indexInfoToIndexSignatureDeclarationHelper(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node, flags: NodeBuilderFlags): IndexSignatureDeclaration { const indexerTypeNode = createKeywordTypeNode(kind === IndexKind.String ? SyntaxKind.StringKeyword : SyntaxKind.NumberKeyword); - const name = getNameFromIndexInfo(indexInfo); + const indexingParameter = createParameter( /*decorators*/ undefined, /*modifiers*/ undefined, diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index d26edbac17..49f95243c9 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -67,6 +67,7 @@ namespace ts.codefix { const visibilityModifier = createVisibilityModifier(getModifierFlags(declaration)); const modifiers = visibilityModifier ? createNodeArray([visibilityModifier]) : undefined; const type = checker.getWidenedType(checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration)); + const optional = !!(symbol.flags & SymbolFlags.Optional); switch (declaration.kind) { case SyntaxKind.GetAccessor: @@ -78,7 +79,7 @@ namespace ts.codefix { /*decorators*/undefined, modifiers, name, - /*questionToken*/ undefined, + optional ? createToken(SyntaxKind.QuestionToken) : undefined, typeNode, /*initializer*/ undefined); return property; @@ -96,36 +97,27 @@ namespace ts.codefix { return undefined; } - const optional = !!(symbol.flags & SymbolFlags.Optional); if (declarations.length === 1) { Debug.assert(signatures.length === 1); const signature = signatures[0]; - const signatureDeclaration = checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration); - signatureDeclaration.modifiers = modifiers; - signatureDeclaration.name = name; - signatureDeclaration.questionToken = optional ? createToken(SyntaxKind.QuestionToken) : undefined; - signatureDeclaration.body = createStubbedMethodBody(); - return signatureDeclaration; + return signatureToMethodDeclaration(signature, enclosingDeclaration, createStubbedMethodBody()); } const signatureDeclarations = []; for (let i = 0; i < signatures.length; i++) { const signature = signatures[i]; - const signatureDeclaration = checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration); - signatureDeclaration.modifiers = modifiers; - signatureDeclaration.name = name; - signatureDeclaration.questionToken = optional ? createToken(SyntaxKind.QuestionToken) : undefined; - signatureDeclarations.push(signatureDeclaration); + const methodDeclaration = signatureToMethodDeclaration(signature, enclosingDeclaration); + if (methodDeclaration) { + signatureDeclarations.push(methodDeclaration); + } } if (declarations.length > signatures.length) { const signature = checker.getSignatureFromDeclaration(declarations[declarations.length - 1] as SignatureDeclaration); - const signatureDeclaration = checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration); - signatureDeclaration.modifiers = modifiers; - signatureDeclaration.name = name; - signatureDeclaration.questionToken = optional ? createToken(SyntaxKind.QuestionToken) : undefined; - signatureDeclaration.body = createStubbedMethodBody(); - signatureDeclarations.push(signatureDeclaration); + const methodDeclaration = signatureToMethodDeclaration(signature, enclosingDeclaration, createStubbedMethodBody()); + if (methodDeclaration) { + signatureDeclarations.push(methodDeclaration); + } } else { Debug.assert(declarations.length === signatures.length); @@ -136,6 +128,17 @@ namespace ts.codefix { default: return undefined; } + + function signatureToMethodDeclaration(signature: Signature, enclosingDeclaration: Node, body?: Block) { + const signatureDeclaration = checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration); + if (signatureDeclaration) { + signatureDeclaration.modifiers = modifiers; + signatureDeclaration.name = name; + signatureDeclaration.questionToken = optional ? createToken(SyntaxKind.QuestionToken) : undefined; + signatureDeclaration.body = body; + } + return signatureDeclaration; + } } function createMethodImplementingSignatures(signatures: Signature[], name: PropertyName, optional: boolean, modifiers: Modifier[] | undefined): MethodDeclaration { diff --git a/tests/cases/fourslash/codeFixClassImplementClassMemberAnonymousClass.ts b/tests/cases/fourslash/codeFixClassImplementClassMemberAnonymousClass.ts index a8a024d194..ee8b8cafff 100644 --- a/tests/cases/fourslash/codeFixClassImplementClassMemberAnonymousClass.ts +++ b/tests/cases/fourslash/codeFixClassImplementClassMemberAnonymousClass.ts @@ -10,11 +10,4 @@ //// } //// class C implements A {[| |]} -verify.rangeAfterCodeFix(` - foo() { - throw new Error("Method not implemented."); - } - bar() { - throw new Error("Method not implemented."); - } -`); +verify.not.codeFixAvailable(); From 797f6dac028fb3f4f8a16b60053a8610f2ee6aca Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Fri, 24 Mar 2017 13:01:27 -0700 Subject: [PATCH 146/164] rename helper --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7c5e8153a6..694763f6c0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -61,7 +61,7 @@ namespace ts { const noImplicitThis = compilerOptions.noImplicitThis === undefined ? compilerOptions.strict : compilerOptions.noImplicitThis; const emitResolver = createResolver(); - const nodeBuilder = getNodeBuilder(); + const nodeBuilder = createNodeBuilder(); const undefinedSymbol = createSymbol(SymbolFlags.Property, "undefined"); undefinedSymbol.declarations = []; @@ -2202,7 +2202,7 @@ namespace ts { return result; } - function getNodeBuilder(): NodeBuilder { + function createNodeBuilder(): NodeBuilder { let encounteredError = false; From 85986ddaee1d9df121bdcfb30b31c4b33ac7e475 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Fri, 24 Mar 2017 13:12:07 -0700 Subject: [PATCH 147/164] dont check isPartOfTypeNode --- src/compiler/utilities.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 57c00ed8fb..f4f288d0cb 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3735,7 +3735,7 @@ namespace ts { * of a TypeNode. */ export function isTypeNode(node: Node): node is TypeNode { - return node && isTypeNodeKind(node.kind) && (!node.parent || isPartOfTypeNode(node)); + return node && isTypeNodeKind(node.kind); } // Binding patterns From f1339ecb8ee84d0f73191bdf83bfdba90579de3a Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 24 Mar 2017 16:07:23 -0700 Subject: [PATCH 148/164] Remove trailing WS --- src/server/server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/server.ts b/src/server/server.ts index e80b6f6b7b..e38f82f35f 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -733,7 +733,7 @@ namespace ts.server { if (localeStr) { validateLocaleAndSetLanguage(localeStr, sys); } - + const typingSafeListLocation = findArgument("--typingSafeListLocation"); const useSingleInferredProject = hasArgument("--useSingleInferredProject"); From a065331d694a9864c074833316d9eef2ea098f0f Mon Sep 17 00:00:00 2001 From: IgorNovozhilov Date: Sat, 25 Mar 2017 17:26:18 +0300 Subject: [PATCH 149/164] [object Generator] 25.3 Generator Objects http://www.ecma-international.org/ecma-262/6.0/#sec-generator-objects ``` C:\Users> node > GF = function* (){} [Function: GF] > GF.constructor.name 'GeneratorFunction' > G = GF() {} > G + '' '[object Generator]' ``` --- src/lib/es2015.generator.d.ts | 11 ++++++++++- src/lib/es2015.symbol.wellknown.d.ts | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/lib/es2015.generator.d.ts b/src/lib/es2015.generator.d.ts index 2f522ad877..d7a3ff1606 100644 --- a/src/lib/es2015.generator.d.ts +++ b/src/lib/es2015.generator.d.ts @@ -1,4 +1,13 @@ -interface GeneratorFunction extends Function { } +interface Generator extends Iterator { } + +interface GeneratorFunction { + /** + * Creates a new Generator object. + * @param args A list of arguments the function accepts. + */ + new (...args: any[]): Generator; + (...args: any[]): Generator; +} interface GeneratorFunctionConstructor { /** diff --git a/src/lib/es2015.symbol.wellknown.d.ts b/src/lib/es2015.symbol.wellknown.d.ts index 71e4cb7c89..5334dae9e0 100644 --- a/src/lib/es2015.symbol.wellknown.d.ts +++ b/src/lib/es2015.symbol.wellknown.d.ts @@ -137,7 +137,7 @@ interface Function { [Symbol.hasInstance](value: any): boolean; } -interface GeneratorFunction extends Function { +interface GeneratorFunction { readonly [Symbol.toStringTag]: "GeneratorFunction"; } From a94f874b06e687b6856c9a9e315a28af2598642b Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Sat, 25 Mar 2017 14:14:36 -0700 Subject: [PATCH 150/164] use NodeBuilderContext --- src/compiler/checker.ts | 697 +++++++++++++++++++++------------------- src/compiler/factory.ts | 4 +- src/compiler/types.ts | 4 +- 3 files changed, 373 insertions(+), 332 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 694763f6c0..a45f3424ef 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2204,369 +2204,403 @@ namespace ts { function createNodeBuilder(): NodeBuilder { - let encounteredError = false; + interface NodeBuilderContext { + readonly enclosingDeclaration: Node | undefined; + readonly flags: NodeBuilderFlags | undefined; + encounteredError: boolean; + inObjectTypeLiteral: boolean; + checkAlias: boolean; + symbolStack: Symbol[] | undefined; + } + + function createNodeBuilderContext(enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): NodeBuilderContext { + return { + enclosingDeclaration, + flags, + encounteredError: false, + inObjectTypeLiteral: false, + checkAlias: true, + symbolStack: undefined + }; + } + + let context: NodeBuilderContext; return { typeToTypeNode: (type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags) => { - Debug.assert(encounteredError === false, "Nested call into nodeBuilder are forbidden."); - encounteredError = false; - const resultingNode = typeToTypeNodeHelper(type, enclosingDeclaration, flags); - const result = encounteredError ? undefined : resultingNode; - encounteredError = false; + context = createNodeBuilderContext(enclosingDeclaration, flags); + const resultingNode = typeToTypeNodeHelper(type); + const result = context.encounteredError ? undefined : resultingNode; return result; }, indexInfoToIndexSignatureDeclaration: (indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags) => { - Debug.assert(encounteredError === false, "Nested call into nodeBuilder are forbidden."); - encounteredError = false; - const resultingNode = indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, enclosingDeclaration, flags); - const result = encounteredError ? undefined : resultingNode; - encounteredError = false; + context = createNodeBuilderContext(enclosingDeclaration, flags); + const resultingNode = indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind); + const result = context.encounteredError ? undefined : resultingNode; return result; }, signatureToSignatureDeclaration: (signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags) => { - Debug.assert(encounteredError === false, "Nested call into nodeBuilder are forbidden."); - encounteredError = false; - const resultingNode = signatureToSignatureDeclarationHelper(signature, kind, enclosingDeclaration, flags); - const result = encounteredError ? undefined : resultingNode; - encounteredError = false; + context = createNodeBuilderContext(enclosingDeclaration, flags); + const resultingNode = signatureToSignatureDeclarationHelper(signature, kind); + const result = context.encounteredError ? undefined : resultingNode; return result; } }; - function typeToTypeNodeHelper(type: Type, enclosingDeclaration: Node, flags: NodeBuilderFlags): TypeNode { - let inObjectTypeLiteral = false; - let checkAlias = true; - let symbolStack: Symbol[] = undefined; + function typeToTypeNodeHelper(type: Type): TypeNode { + if (!type) { + context.encounteredError = true; + // TODO(aozgaa): should we return implict any (undefined) or explicit any (keywordtypenode)? + return undefined; + } - return typeToTypeNodeWorker(type); + if (type.flags & TypeFlags.Any) { + return createKeywordTypeNode(SyntaxKind.AnyKeyword); + } + if (type.flags & TypeFlags.String) { + return createKeywordTypeNode(SyntaxKind.StringKeyword); + } + if (type.flags & TypeFlags.Number) { + return createKeywordTypeNode(SyntaxKind.NumberKeyword); + } + if (type.flags & TypeFlags.Boolean) { + return createKeywordTypeNode(SyntaxKind.BooleanKeyword); + } + if (type.flags & TypeFlags.Enum) { + const name = symbolToName(type.symbol, /*expectsIdentifier*/ false); + return createTypeReferenceNode(name, /*typeArguments*/ undefined); + } + if (type.flags & (TypeFlags.StringLiteral)) { + return createLiteralTypeNode((createLiteral((type).text))); + } + if (type.flags & (TypeFlags.NumberLiteral)) { + return createLiteralTypeNode((createNumericLiteral((type).text))); + } + if (type.flags & TypeFlags.BooleanLiteral) { + return (type).intrinsicName === "true" ? createTrue() : createFalse(); + } + if (type.flags & TypeFlags.EnumLiteral) { + const name = symbolToName(type.symbol, /*expectsIdentifier*/ false); + return createTypeReferenceNode(name, /*typeArguments*/ undefined); + } + if (type.flags & TypeFlags.Void) { + return createKeywordTypeNode(SyntaxKind.VoidKeyword); + } + if (type.flags & TypeFlags.Undefined) { + return createKeywordTypeNode(SyntaxKind.UndefinedKeyword); + } + if (type.flags & TypeFlags.Null) { + return createKeywordTypeNode(SyntaxKind.NullKeyword); + } + if (type.flags & TypeFlags.Never) { + return createKeywordTypeNode(SyntaxKind.NeverKeyword); + } + if (type.flags & TypeFlags.ESSymbol) { + throw new Error("ESSymbol not implemented"); + } + if (type.flags & TypeFlags.NonPrimitive) { + throw new Error("Non primitive not implemented"); + } + if (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType) { + if (context.inObjectTypeLiteral) { + if (!context.encounteredError && !(context.flags & NodeBuilderFlags.allowThisInObjectLiteral)) { + context.encounteredError = true; + } + } + return createThis(); + } - function typeToTypeNodeWorker(type: Type): TypeNode { - if (!type) { - encounteredError = true; - // TODO(aozgaa): should we return implict any (undefined) or explicit any (keywordtypenode)? + const objectFlags = getObjectFlags(type); + + if (objectFlags & ObjectFlags.Reference) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + return typeReferenceToTypeNode(type); + } + if (objectFlags & ObjectFlags.ClassOrInterface) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + const name = symbolToName(type.symbol, /*expectsIdentifier*/ false); + // TODO(aozgaa): handle type arguments. + return createTypeReferenceNode(name, /*typeArguments*/ undefined); + } + if (type.flags & TypeFlags.TypeParameter) { + const name = symbolToName(type.symbol, /*expectsIdentifier*/ false); + // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. + return createTypeReferenceNode(name, /*typeArguments*/ undefined); + } + + if (context.checkAlias && type.aliasSymbol) { + const name = symbolToName(type.aliasSymbol, /*expectsIdentifier*/ false); + const typeArgumentNodes = type.aliasTypeArguments && mapToTypeNodeArray(type.aliasTypeArguments); + return createTypeReferenceNode(name, typeArgumentNodes); + } + context.checkAlias = false; + + if (type.flags & TypeFlags.Union) { + const formattedUnionTypes = formatUnionTypes((type).types); + const unionTypeNodes = formattedUnionTypes && mapToTypeNodeArray(formattedUnionTypes); + if (unionTypeNodes && unionTypeNodes.length > 0) { + return createUnionOrIntersectionTypeNode(SyntaxKind.UnionType, unionTypeNodes); + } + else { + if (!context.encounteredError && !(context.flags & NodeBuilderFlags.allowEmptyUnionOrIntersection)) { + context.encounteredError = true; + } return undefined; } + } - if (type.flags & TypeFlags.Any) { - return createKeywordTypeNode(SyntaxKind.AnyKeyword); - } - if (type.flags & TypeFlags.String) { - return createKeywordTypeNode(SyntaxKind.StringKeyword); - } - if (type.flags & TypeFlags.Number) { - return createKeywordTypeNode(SyntaxKind.NumberKeyword); - } - if (type.flags & TypeFlags.Boolean) { - return createKeywordTypeNode(SyntaxKind.BooleanKeyword); - } - if (type.flags & TypeFlags.Enum) { - const name = symbolToName(type.symbol, enclosingDeclaration, /*expectsIdentifier*/ false, flags); - return createTypeReferenceNode(name, /*typeArguments*/ undefined); - } - if (type.flags & (TypeFlags.StringLiteral)) { - return createLiteralTypeNode((createLiteral((type).text))); - } - if (type.flags & (TypeFlags.NumberLiteral)) { - return createLiteralTypeNode((createNumericLiteral((type).text))); - } - if (type.flags & TypeFlags.BooleanLiteral) { - return (type).intrinsicName === "true" ? createTrue() : createFalse(); - } - if (type.flags & TypeFlags.EnumLiteral) { - const name = symbolToName(type.symbol, enclosingDeclaration, /*expectsIdentifier*/ false, flags); - return createTypeReferenceNode(name, /*typeArguments*/ undefined); - } - if (type.flags & TypeFlags.Void) { - return createKeywordTypeNode(SyntaxKind.VoidKeyword); - } - if (type.flags & TypeFlags.Undefined) { - return createKeywordTypeNode(SyntaxKind.UndefinedKeyword); - } - if (type.flags & TypeFlags.Null) { - return createKeywordTypeNode(SyntaxKind.NullKeyword); - } - if (type.flags & TypeFlags.Never) { - return createKeywordTypeNode(SyntaxKind.NeverKeyword); - } - if (type.flags & TypeFlags.ESSymbol) { - throw new Error("ESSymbol not implemented"); - } - if (type.flags & TypeFlags.NonPrimitive) { - throw new Error("Non primitive not implemented"); - } - if (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType) { - if (inObjectTypeLiteral) { - encounteredError = encounteredError || !(flags & NodeBuilderFlags.allowThisInObjectLiteral); + if (type.flags & TypeFlags.Intersection) { + return createUnionOrIntersectionTypeNode(SyntaxKind.IntersectionType, mapToTypeNodeArray((type as UnionType).types)); + } + + if (objectFlags & (ObjectFlags.Anonymous | ObjectFlags.Mapped)) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + // The type is an object literal type. + return createAnonymousTypeNode(type); + } + + if (type.flags & TypeFlags.Index) { + const indexedType = (type).type; + const indexTypeNode = typeToTypeNodeHelper(indexedType); + return createTypeOperatorNode(indexTypeNode); + } + if (type.flags & TypeFlags.IndexedAccess) { + const objectTypeNode = typeToTypeNodeHelper((type).objectType); + const indexTypeNode = typeToTypeNodeHelper((type).indexType); + return createIndexedAccessTypeNode(objectTypeNode, indexTypeNode); + } + + Debug.fail("Should be unreachable."); + + function mapToTypeNodeArray(types: Type[]): TypeNode[] { + const result = []; + for (const type of types) { + const typeNode = typeToTypeNodeHelper(type); + if (typeNode) { + result.push(typeNode); } - return createThis(); } + return result; + } - const objectFlags = getObjectFlags(type); + function createMappedTypeNodeFromType(type: MappedType) { + Debug.assert(!!(type.flags & TypeFlags.Object)); + const typeParameter = getTypeParameterFromMappedType(type); + const typeParameterNode = typeParameterToDeclaration(typeParameter); - if (objectFlags & ObjectFlags.Reference) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - return typeReferenceToTypeNode (type); - } - if (objectFlags & ObjectFlags.ClassOrInterface) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - const name = symbolToName(type.symbol, enclosingDeclaration, /*expectsIdentifier*/ false, flags); - // TODO(aozgaa): handle type arguments. - return createTypeReferenceNode(name, /*typeArguments*/ undefined); - } - if (type.flags & TypeFlags.TypeParameter) { - const name = symbolToName(type.symbol, enclosingDeclaration, /*expectsIdentifier*/ false, flags); - // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. - return createTypeReferenceNode(name, /*typeArguments*/ undefined); - } + const templateType = getTemplateTypeFromMappedType(type); + const templateTypeNode = templateType && typeToTypeNodeHelper(templateType); + const readonlyToken = (type).declaration && (type).declaration.readonlyToken ? createToken(SyntaxKind.ReadonlyKeyword) : undefined; + const questionToken = (type).declaration && (type).declaration.questionToken ? createToken(SyntaxKind.QuestionToken) : undefined; - if (checkAlias && type.aliasSymbol) { - const name = symbolToName(type.aliasSymbol, enclosingDeclaration, /*expectsIdentifier*/ false, flags); - const typeArgumentNodes = mapToTypeNodeArray(type.aliasTypeArguments); - return createTypeReferenceNode(name, typeArgumentNodes); - } - checkAlias = false; + return createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode); + } - if (type.flags & TypeFlags.Union) { - return createUnionOrIntersectionTypeNode(SyntaxKind.UnionType, mapToTypeNodeArray(formatUnionTypes((type).types))); - } - - if (type.flags & TypeFlags.Intersection) { - return createUnionOrIntersectionTypeNode(SyntaxKind.IntersectionType, mapToTypeNodeArray((type as UnionType).types)); - } - - if (objectFlags & (ObjectFlags.Anonymous | ObjectFlags.Mapped)) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - // The type is an object literal type. - return createAnonymousTypeNode(type); - } - - if (type.flags & TypeFlags.Index) { - const indexedType = (type).type; - const indexTypeNode = typeToTypeNodeWorker(indexedType); - return createTypeOperatorNode(indexTypeNode); - } - if (type.flags & TypeFlags.IndexedAccess) { - const objectTypeNode = typeToTypeNodeWorker((type).objectType); - const indexTypeNode = typeToTypeNodeWorker((type).indexType); - return createIndexedAccessTypeNode(objectTypeNode, indexTypeNode); - } - - Debug.fail("Should be unreachable."); - - function mapToTypeNodeArray(types: Type[]): NodeArray { - return types && asNodeArray(types.map(typeToTypeNodeWorker).filter(node => !!node)); - } - - function createMappedTypeNodeFromType(type: MappedType) { - Debug.assert(!!(type.flags & TypeFlags.Object)); - const typeParameter = getTypeParameterFromMappedType(type); - const typeParameterNode = typeParameterToDeclaration(typeParameter, enclosingDeclaration, flags); - - const templateType = getTemplateTypeFromMappedType(type); - const templateTypeNode = templateType && typeToTypeNodeWorker(templateType); - const readonlyToken = (type).declaration && (type).declaration.readonlyToken ? createToken(SyntaxKind.ReadonlyKeyword) : undefined; - const questionToken = (type).declaration && (type).declaration.questionToken ? createToken(SyntaxKind.QuestionToken) : undefined; - - return createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode); - } - - function createAnonymousTypeNode(type: ObjectType): TypeNode { - const symbol = type.symbol; - if (symbol) { - // Always use 'typeof T' for type of class, enum, and module objects - if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) || - symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule) || - shouldWriteTypeOfFunctionSymbol()) { - return createTypeQueryNodeFromType(type); - } - else if (contains(symbolStack, symbol)) { - // If type is an anonymous type literal in a type alias declaration, use type alias name - const typeAlias = getTypeAliasForTypeLiteral(type); - if (typeAlias) { - // The specified symbol flags need to be reinterpreted as type flags - const entityName = symbolToName(typeAlias, enclosingDeclaration, /*expectsIdentifier*/ false, flags); - return createTypeReferenceNode(entityName, /*typeArguments*/ undefined); - } - else { - return createKeywordTypeNode(SyntaxKind.AnyKeyword); - } + function createAnonymousTypeNode(type: ObjectType): TypeNode { + const symbol = type.symbol; + if (symbol) { + // Always use 'typeof T' for type of class, enum, and module objects + if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) || + symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule) || + shouldWriteTypeOfFunctionSymbol()) { + return createTypeQueryNodeFromType(type); + } + else if (contains(context.symbolStack, symbol)) { + // If type is an anonymous type literal in a type alias declaration, use type alias name + const typeAlias = getTypeAliasForTypeLiteral(type); + if (typeAlias) { + // The specified symbol flags need to be reinterpreted as type flags + const entityName = symbolToName(typeAlias, /*expectsIdentifier*/ false); + return createTypeReferenceNode(entityName, /*typeArguments*/ undefined); } else { - // Since instantiations of the same anonymous type have the same symbol, tracking symbols instead - // of types allows us to catch circular references to instantiations of the same anonymous type - if (!symbolStack) { - symbolStack = []; - } - symbolStack.push(symbol); - const result = createTypeNodeFromObjectType(type); - symbolStack.pop(); - return result; + return createKeywordTypeNode(SyntaxKind.AnyKeyword); } } else { - // Anonymous types without a symbol are never circular. - return createTypeNodeFromObjectType(type); - } - - function shouldWriteTypeOfFunctionSymbol() { - const isStaticMethodSymbol = !!(symbol.flags & SymbolFlags.Method && // typeof static method - forEach(symbol.declarations, declaration => getModifierFlags(declaration) & ModifierFlags.Static)); - const isNonLocalFunctionSymbol = !!(symbol.flags & SymbolFlags.Function) && - (symbol.parent || // is exported function symbol - forEach(symbol.declarations, declaration => - declaration.parent.kind === SyntaxKind.SourceFile || declaration.parent.kind === SyntaxKind.ModuleBlock)); - if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { - // typeof is allowed only for static/non local functions - return contains(symbolStack, symbol); // it is type of the symbol uses itself recursively + // Since instantiations of the same anonymous type have the same symbol, tracking symbols instead + // of types allows us to catch circular references to instantiations of the same anonymous type + if (!context.symbolStack) { + context.symbolStack = []; } + context.symbolStack.push(symbol); + const result = createTypeNodeFromObjectType(type); + context.symbolStack.pop(); + return result; + } + } + else { + // Anonymous types without a symbol are never circular. + return createTypeNodeFromObjectType(type); + } + + function shouldWriteTypeOfFunctionSymbol() { + const isStaticMethodSymbol = !!(symbol.flags & SymbolFlags.Method && // typeof static method + forEach(symbol.declarations, declaration => getModifierFlags(declaration) & ModifierFlags.Static)); + const isNonLocalFunctionSymbol = !!(symbol.flags & SymbolFlags.Function) && + (symbol.parent || // is exported function symbol + forEach(symbol.declarations, declaration => + declaration.parent.kind === SyntaxKind.SourceFile || declaration.parent.kind === SyntaxKind.ModuleBlock)); + if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { + // typeof is allowed only for static/non local functions + return contains(context.symbolStack, symbol); // it is type of the symbol uses itself recursively + } + } + } + + function createTypeNodeFromObjectType(type: ObjectType): TypeNode { + if (type.objectFlags & ObjectFlags.Mapped) { + if (getConstraintTypeFromMappedType(type).flags & (TypeFlags.TypeParameter | TypeFlags.Index)) { + return createMappedTypeNodeFromType(type); } } - function createTypeNodeFromObjectType(type: ObjectType): TypeNode { - if (type.objectFlags & ObjectFlags.Mapped) { - if (getConstraintTypeFromMappedType(type).flags & (TypeFlags.TypeParameter | TypeFlags.Index)) { - return createMappedTypeNodeFromType(type); - } + const resolved = resolveStructuredTypeMembers(type); + if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { + if (!resolved.callSignatures.length && !resolved.constructSignatures.length) { + return createTypeLiteralNode(/*members*/ undefined); } - const resolved = resolveStructuredTypeMembers(type); - if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { - if (!resolved.callSignatures.length && !resolved.constructSignatures.length) { - return createTypeLiteralNode(/*members*/ undefined); - } - - if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) { - const signature = resolved.callSignatures[0]; - return signatureToSignatureDeclarationHelper(signature, SyntaxKind.FunctionType, enclosingDeclaration, flags); - } - if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) { - const signature = resolved.constructSignatures[0]; - return signatureToSignatureDeclarationHelper(signature, SyntaxKind.ConstructorType, enclosingDeclaration, flags); - } + if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) { + const signature = resolved.callSignatures[0]; + return signatureToSignatureDeclarationHelper(signature, SyntaxKind.FunctionType); } - - const saveInObjectTypeLiteral = inObjectTypeLiteral; - inObjectTypeLiteral = true; - const members = createTypeNodesFromResolvedType(resolved); - inObjectTypeLiteral = saveInObjectTypeLiteral; - return createTypeLiteralNode(members); - } - - function createTypeQueryNodeFromType(type: Type) { - const symbol = type.symbol; - if (symbol) { - const entityName = symbolToName(symbol, enclosingDeclaration, /*expectsIdentifier*/ false, flags); - return createTypeQueryNode(entityName); + if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) { + const signature = resolved.constructSignatures[0]; + return signatureToSignatureDeclarationHelper(signature, SyntaxKind.ConstructorType); } } - function typeReferenceToTypeNode(type: TypeReference) { - const typeArguments: Type[] = type.typeArguments || emptyArray; - if (type.target === globalArrayType) { - const elementType = typeToTypeNodeWorker(typeArguments[0]); - return createArrayTypeNode(elementType); + const saveInObjectTypeLiteral = context.inObjectTypeLiteral; + context.inObjectTypeLiteral = true; + const members = createTypeNodesFromResolvedType(resolved); + context.inObjectTypeLiteral = saveInObjectTypeLiteral; + return createTypeLiteralNode(members); + } + + function createTypeQueryNodeFromType(type: Type) { + const symbol = type.symbol; + if (symbol) { + const entityName = symbolToName(symbol, /*expectsIdentifier*/ false); + return createTypeQueryNode(entityName); + } + } + + function typeReferenceToTypeNode(type: TypeReference) { + const typeArguments: Type[] = type.typeArguments || emptyArray; + if (type.target === globalArrayType) { + const elementType = typeToTypeNodeHelper(typeArguments[0]); + return createArrayTypeNode(elementType); + } + else if (type.target.objectFlags & ObjectFlags.Tuple) { + if (typeArguments.length > 0) { + const tupleConstituentNodes = mapToTypeNodeArray(typeArguments.slice(0, getTypeReferenceArity(type))); + if (tupleConstituentNodes && tupleConstituentNodes.length > 0) { + return createTupleTypeNode(tupleConstituentNodes); + } } - else if (type.target.objectFlags & ObjectFlags.Tuple) { - return createTupleTypeNode(typeArguments.length > 0 ? mapToTypeNodeArray(typeArguments.slice(0, getTypeReferenceArity(type))) : undefined); + if (!context.encounteredError && !(context.flags & NodeBuilderFlags.allowEmptyTuple)) { + context.encounteredError = true; } - else { - const outerTypeParameters = type.target.outerTypeParameters; - let i = 0; - let qualifiedName: QualifiedName | undefined = undefined; - if (outerTypeParameters) { - const length = outerTypeParameters.length; - while (i < length) { - // Find group of type arguments for type parameters with the same declaring container. - const start = i; - const parent = getParentSymbolOfTypeParameter(outerTypeParameters[i]); - do { - i++; - } while (i < length && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent); - // When type parameters are their own type arguments for the whole group (i.e. we have - // the default outer type arguments), we don't show the group. - if (!rangeEquals(outerTypeParameters, typeArguments, start, i)) { - const qualifiedNamePart = symbolToName(parent, enclosingDeclaration, /*expectsIdentifier*/ true, flags); - if (!qualifiedName) { - qualifiedName = createQualifiedName(qualifiedNamePart, /*right*/ undefined); - } - else { - Debug.assert(!qualifiedName.right); - qualifiedName.right = qualifiedNamePart; - qualifiedName = createQualifiedName(qualifiedName, /*right*/ undefined); - } + return undefined; + } + else { + const outerTypeParameters = type.target.outerTypeParameters; + let i = 0; + let qualifiedName: QualifiedName | undefined = undefined; + if (outerTypeParameters) { + const length = outerTypeParameters.length; + while (i < length) { + // Find group of type arguments for type parameters with the same declaring container. + const start = i; + const parent = getParentSymbolOfTypeParameter(outerTypeParameters[i]); + do { + i++; + } while (i < length && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent); + // When type parameters are their own type arguments for the whole group (i.e. we have + // the default outer type arguments), we don't show the group. + if (!rangeEquals(outerTypeParameters, typeArguments, start, i)) { + const qualifiedNamePart = symbolToName(parent, /*expectsIdentifier*/ true); + if (!qualifiedName) { + qualifiedName = createQualifiedName(qualifiedNamePart, /*right*/ undefined); + } + else { + Debug.assert(!qualifiedName.right); + qualifiedName.right = qualifiedNamePart; + qualifiedName = createQualifiedName(qualifiedName, /*right*/ undefined); } } } - let entityName: EntityName = undefined; - const nameIdentifier = symbolToName(type.symbol, enclosingDeclaration, /*expectsIdentifier*/ true, flags); - if (qualifiedName) { - Debug.assert(!qualifiedName.right); - qualifiedName.right = nameIdentifier; - entityName = qualifiedName; - } - else { - entityName = nameIdentifier; - } - const typeParameterCount = (type.target.typeParameters || emptyArray).length; - const typeArgumentNodes = mapToTypeNodeArray(typeArguments.length > 0 ? typeArguments.slice(i, typeParameterCount - i) : undefined); - return createTypeReferenceNode(entityName, typeArgumentNodes); } + let entityName: EntityName = undefined; + const nameIdentifier = symbolToName(type.symbol, /*expectsIdentifier*/ true); + if (qualifiedName) { + Debug.assert(!qualifiedName.right); + qualifiedName.right = nameIdentifier; + entityName = qualifiedName; + } + else { + entityName = nameIdentifier; + } + const typeParameterCount = (type.target.typeParameters || emptyArray).length; + const typeArgumentNodes = typeArguments.length > 0 ? mapToTypeNodeArray(typeArguments.slice(i, typeParameterCount - i)) : undefined; + return createTypeReferenceNode(entityName, typeArgumentNodes); + } + } + + function createTypeNodesFromResolvedType(resolvedType: ResolvedType): TypeElement[] { + const typeElements: TypeElement[] = []; + for (const signature of resolvedType.callSignatures) { + typeElements.push(signatureToSignatureDeclarationHelper(signature, SyntaxKind.CallSignature)); + } + for (const signature of resolvedType.constructSignatures) { + typeElements.push(signatureToSignatureDeclarationHelper(signature, SyntaxKind.ConstructSignature)); + } + if (resolvedType.stringIndexInfo) { + typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.stringIndexInfo, IndexKind.String)); + } + if (resolvedType.numberIndexInfo) { + typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.numberIndexInfo, IndexKind.Number)); } - function createTypeNodesFromResolvedType(resolvedType: ResolvedType): TypeElement[] { - const typeElements: TypeElement[] = []; - for (const signature of resolvedType.callSignatures) { - typeElements.push(signatureToSignatureDeclarationHelper(signature, SyntaxKind.CallSignature, enclosingDeclaration, flags)); - } - for (const signature of resolvedType.constructSignatures) { - typeElements.push(signatureToSignatureDeclarationHelper(signature, SyntaxKind.ConstructSignature, enclosingDeclaration, flags)); - } - if (resolvedType.stringIndexInfo) { - typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.stringIndexInfo, IndexKind.String, enclosingDeclaration, flags)); - } - if (resolvedType.numberIndexInfo) { - typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.numberIndexInfo, IndexKind.Number, enclosingDeclaration, flags)); - } + const properties = resolvedType.properties; + if (!properties) { + return typeElements; + } - const properties = resolvedType.properties; - if (!properties) { - return typeElements; + for (const propertySymbol of properties) { + const propertyType = getTypeOfSymbol(propertySymbol); + const oldDeclaration = propertySymbol.declarations && propertySymbol.declarations[0] as TypeElement; + if (!oldDeclaration) { + return; } - - for (const propertySymbol of properties) { - const propertyType = getTypeOfSymbol(propertySymbol); - const oldDeclaration = propertySymbol.declarations && propertySymbol.declarations[0] as TypeElement; - if (!oldDeclaration) { - return; + const propertyName = oldDeclaration.name; + const optionalToken = propertySymbol.flags & SymbolFlags.Optional ? createToken(SyntaxKind.QuestionToken) : undefined; + if (propertySymbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length) { + const signatures = getSignaturesOfType(propertyType, SignatureKind.Call); + for (const signature of signatures) { + const methodDeclaration = signatureToSignatureDeclarationHelper(signature, SyntaxKind.MethodSignature); + methodDeclaration.name = propertyName; + methodDeclaration.questionToken = optionalToken; + typeElements.push(methodDeclaration); } - const propertyName = oldDeclaration.name; - const optionalToken = propertySymbol.flags & SymbolFlags.Optional ? createToken(SyntaxKind.QuestionToken) : undefined; - if (propertySymbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length) { - const signatures = getSignaturesOfType(propertyType, SignatureKind.Call); - for (const signature of signatures) { - const methodDeclaration = signatureToSignatureDeclarationHelper(signature, SyntaxKind.MethodSignature, enclosingDeclaration, flags); - methodDeclaration.name = propertyName; - methodDeclaration.questionToken = optionalToken; - typeElements.push(methodDeclaration); - } - } - else { + } + else { - // TODO(aozgaa): should we create a node with explicit or implict any? - const propertyTypeNode = propertyType ? typeToTypeNodeWorker(propertyType) : createKeywordTypeNode(SyntaxKind.AnyKeyword); - typeElements.push(createPropertySignature( - propertyName, - optionalToken, - propertyTypeNode, + // TODO(aozgaa): should we create a node with explicit or implict any? + const propertyTypeNode = propertyType ? typeToTypeNodeHelper(propertyType) : createKeywordTypeNode(SyntaxKind.AnyKeyword); + typeElements.push(createPropertySignature( + propertyName, + optionalToken, + propertyTypeNode, /*initializer*/undefined)); - } } - return typeElements.length ? typeElements : undefined; } + return typeElements.length ? typeElements : undefined; } } - function indexInfoToIndexSignatureDeclarationHelper(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node, flags: NodeBuilderFlags): IndexSignatureDeclaration { + function indexInfoToIndexSignatureDeclarationHelper(indexInfo: IndexInfo, kind: IndexKind): IndexSignatureDeclaration { const indexerTypeNode = createKeywordTypeNode(kind === IndexKind.String ? SyntaxKind.StringKeyword : SyntaxKind.NumberKeyword); const name = getNameFromIndexInfo(indexInfo); @@ -2578,7 +2612,7 @@ namespace ts { /*questionToken*/ undefined, indexerTypeNode, /*initializer*/ undefined); - const typeNode = typeToTypeNodeHelper(indexInfo.type, enclosingDeclaration, flags); + const typeNode = typeToTypeNodeHelper(indexInfo.type); return createIndexSignatureDeclaration( [indexingParameter], typeNode, @@ -2586,37 +2620,37 @@ namespace ts { indexInfo.isReadonly ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined); } - function signatureToSignatureDeclarationHelper(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node, flags: NodeBuilderFlags): SignatureDeclaration { + function signatureToSignatureDeclarationHelper(signature: Signature, kind: SyntaxKind): SignatureDeclaration { - const typeParameters = signature.typeParameters && signature.typeParameters.map(parameter => typeParameterToDeclaration(parameter, enclosingDeclaration, flags)); - const parameters = signature.parameters.map(parameter => symbolToParameterDeclaration(parameter, enclosingDeclaration, flags)); + const typeParameters = signature.typeParameters && signature.typeParameters.map(parameter => typeParameterToDeclaration(parameter)); + const parameters = signature.parameters.map(parameter => symbolToParameterDeclaration(parameter)); const returnTypeNode = typeToTypeNodeExceptAny(getReturnTypeOfSignature(signature)); return createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNode); function typeToTypeNodeExceptAny(type: Type): TypeNode | undefined { - const typeNode = type && typeToTypeNodeHelper(type, enclosingDeclaration, flags); + const typeNode = type && typeToTypeNodeHelper(type); return typeNode && typeNode.kind !== SyntaxKind.AnyKeyword ? typeNode : undefined; } } - function typeParameterToDeclaration(type: TypeParameter, enclosingDeclaration: Node, flags: NodeBuilderFlags): TypeParameterDeclaration { + function typeParameterToDeclaration(type: TypeParameter): TypeParameterDeclaration { if (!(type && type.symbol && type.flags & TypeFlags.TypeParameter)) { return undefined; } const constraint = getConstraintFromTypeParameter(type); - const constraintNode = constraint && typeToTypeNodeHelper(constraint, enclosingDeclaration, flags); + const constraintNode = constraint && typeToTypeNodeHelper(constraint); const defaultParameter = getDefaultFromTypeParameter(type); - const defaultParameterNode = defaultParameter && typeToTypeNodeHelper(defaultParameter, enclosingDeclaration, flags); - const name = symbolToName(type.symbol, enclosingDeclaration, /*expectsIdentifier*/ true, flags); + const defaultParameterNode = defaultParameter && typeToTypeNodeHelper(defaultParameter); + const name = symbolToName(type.symbol, /*expectsIdentifier*/ true); return createTypeParameterDeclaration(name, constraintNode, defaultParameterNode); } - function symbolToParameterDeclaration(parameterSymbol: Symbol, enclosingDeclaration: Node, flags: NodeBuilderFlags): ParameterDeclaration { + function symbolToParameterDeclaration(parameterSymbol: Symbol): ParameterDeclaration { const parameterDeclaration = parameterSymbol.declarations[0] as ParameterDeclaration; const parameterType = getTypeOfSymbol(parameterSymbol); - const parameterTypeNode = typeToTypeNodeHelper(parameterType, enclosingDeclaration, flags); + const parameterTypeNode = typeToTypeNodeHelper(parameterType); // TODO(aozgaa): check initializer accessibility correctly. const parameterNode = createParameter( parameterDeclaration.decorators, @@ -2630,15 +2664,15 @@ namespace ts { return parameterNode; } - function symbolToName(symbol: Symbol, enclosingDeclaration: Node | undefined, expectsIdentifier: true, flags: NodeBuilderFlags): Identifier; - function symbolToName(symbol: Symbol, enclosingDeclaration: Node | undefined, expectsIdentifier: false, flags: NodeBuilderFlags): EntityName; - function symbolToName(symbol: Symbol, enclosingDeclaration: Node | undefined, expectsIdentifier: boolean, flags: NodeBuilderFlags): EntityName { + function symbolToName(symbol: Symbol, expectsIdentifier: true): Identifier; + function symbolToName(symbol: Symbol, expectsIdentifier: false): EntityName; + function symbolToName(symbol: Symbol, expectsIdentifier: boolean): EntityName { let parentSymbol: Symbol; // Try to get qualified name if the symbol is not a type parameter and there is an enclosing declaration. let chain: Symbol[]; const isTypeParameter = symbol.flags & SymbolFlags.TypeParameter; - if (!isTypeParameter && enclosingDeclaration) { + if (!isTypeParameter && context.enclosingDeclaration) { chain = getSymbolChain(symbol, SymbolFlags.None, /*endOfChain*/ true); Debug.assert(chain && chain.length > 0); } @@ -2648,8 +2682,10 @@ namespace ts { parentSymbol = undefined; - if (expectsIdentifier && chain.length !== 1) { - encounteredError = encounteredError || !(flags & NodeBuilderFlags.allowQualifedNameInPlaceOfIdentifier); + if (expectsIdentifier && chain.length !== 1 + && !context.encounteredError + && !(context.flags & NodeBuilderFlags.allowQualifedNameInPlaceOfIdentifier)) { + context.encounteredError = true; } return createEntityNameFromSymbolChain(chain, chain.length - 1); @@ -2672,11 +2708,12 @@ namespace ts { } } if (typeParameters && typeParameters.length > 0) { - encounteredError = encounteredError || !(flags & NodeBuilderFlags.allowTypeParameterInQualifiedName); - + if (!context.encounteredError && !(context.flags & NodeBuilderFlags.allowTypeParameterInQualifiedName)) { + context.encounteredError = true; + } const writer = getSingleLineStringWriter(); const displayBuilder = getSymbolDisplayBuilder(); - displayBuilder.buildDisplayForTypeParametersAndDelimiters(typeParameters, writer, enclosingDeclaration, 0); + displayBuilder.buildDisplayForTypeParametersAndDelimiters(typeParameters, writer, context.enclosingDeclaration, 0); typeParameterString = writer.string(); releaseStringWriter(writer); @@ -2691,10 +2728,10 @@ namespace ts { /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */ function getSymbolChain(symbol: Symbol, meaning: SymbolFlags, endOfChain: boolean): Symbol[] | undefined { - let accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, /*useOnlyExternalAliasing*/false); + let accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, /*useOnlyExternalAliasing*/false); if (!accessibleSymbolChain || - needsQualification(accessibleSymbolChain[0], enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) { + needsQualification(accessibleSymbolChain[0], context.enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) { // Go up and add our parent. const parent = getParentOfSymbol(accessibleSymbolChain ? accessibleSymbolChain[0] : symbol); @@ -2731,7 +2768,9 @@ namespace ts { if (declaration.parent && declaration.parent.kind === SyntaxKind.VariableDeclaration) { return declarationNameToString((declaration.parent).name); } - encounteredError = encounteredError || !(flags & NodeBuilderFlags.allowAnonymousIdentifier); + if (!context.encounteredError && !(context.flags & NodeBuilderFlags.allowAnonymousIdentifier)) { + context.encounteredError = true; + } switch (declaration.kind) { case SyntaxKind.ClassExpression: return "(Anonymous class)"; diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 08dc91c6b2..e1e4e2c4ae 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -238,10 +238,10 @@ namespace ts { : node; } - export function createTypeReferenceNode(typeName: string | EntityName, typeArguments: NodeArray | undefined) { + export function createTypeReferenceNode(typeName: string | EntityName, typeArguments: TypeNode[] | undefined) { const typeReference = createSynthesizedNode(SyntaxKind.TypeReference) as TypeReferenceNode; typeReference.typeName = asName(typeName); - typeReference.typeArguments = typeArguments; + typeReference.typeArguments = asNodeArray(typeArguments); return typeReference; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 461e33426e..178e6fe779 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2548,7 +2548,9 @@ namespace ts { allowThisInObjectLiteral = 1 << 0, allowQualifedNameInPlaceOfIdentifier = 1 << 1, allowTypeParameterInQualifiedName = 1 << 2, - allowAnonymousIdentifier = 1 << 3 + allowAnonymousIdentifier = 1 << 3, + allowEmptyUnionOrIntersection = 1 << 4, + allowEmptyTuple = 1 << 5 } export interface SymbolDisplayBuilder { From ee2a909f54cae61621d5a4cf52ff217d8e817d86 Mon Sep 17 00:00:00 2001 From: IgorNovozhilov Date: Sun, 26 Mar 2017 17:08:27 +0300 Subject: [PATCH 151/164] ["Two small changes"] --- src/lib/es2015.generator.d.ts | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/lib/es2015.generator.d.ts b/src/lib/es2015.generator.d.ts index d7a3ff1606..5637ef816d 100644 --- a/src/lib/es2015.generator.d.ts +++ b/src/lib/es2015.generator.d.ts @@ -6,7 +6,23 @@ interface GeneratorFunction { * @param args A list of arguments the function accepts. */ new (...args: any[]): Generator; + /** + * Creates a new Generator object. + * @param args A list of arguments the function accepts. + */ (...args: any[]): Generator; + /** + * The length of the arguments. + */ + readonly length: number; + /** + * Returns the name of the function. + */ + readonly name: string; + /** + * A reference to the prototype. + */ + readonly prototype: Generator; } interface GeneratorFunctionConstructor { @@ -15,7 +31,22 @@ interface GeneratorFunctionConstructor { * @param args A list of arguments the function accepts. */ new (...args: string[]): GeneratorFunction; + /** + * Creates a new Generator function. + * @param args A list of arguments the function accepts. + */ (...args: string[]): GeneratorFunction; + /** + * The length of the arguments. + */ + readonly length: number; + /** + * Returns the name of the function. + */ + readonly name: string; + /** + * A reference to the prototype. + */ readonly prototype: GeneratorFunction; } declare var GeneratorFunction: GeneratorFunctionConstructor; From 6366719de89676c34c3849459752cb35fa9ca29d Mon Sep 17 00:00:00 2001 From: ncoley Date: Sat, 25 Mar 2017 19:27:15 -0400 Subject: [PATCH 152/164] Add missing methods for FormData type --- src/lib/dom.iterable.d.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/lib/dom.iterable.d.ts b/src/lib/dom.iterable.d.ts index 9a04b723ac..ea0d43d364 100644 --- a/src/lib/dom.iterable.d.ts +++ b/src/lib/dom.iterable.d.ts @@ -4,6 +4,23 @@ interface DOMTokenList { [Symbol.iterator](): IterableIterator; } +interface FormData { + /** + * Returns an array of key, value pairs for every entry in the list + */ + entries(): IterableIterator<[string, any]>; + /** + * Returns a list of keys in the list + */ + keys(): IterableIterator; + /** + * Returns a list of values in the list + */ + values(): IterableIterator; + + [Symbol.iterator](): IterableIterator; +} + interface NodeList { /** * Returns an array of key, value pairs for every entry in the list From e2b3c9c66374365381d3704c642bb3f4f59424bf Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Sun, 26 Mar 2017 22:29:17 -0700 Subject: [PATCH 153/164] remove NodeBuilder --- src/compiler/checker.ts | 43 ++++++++++++++++++++--------------------- src/compiler/types.ts | 8 -------- 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a45f3424ef..3c2eb8c513 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2202,28 +2202,7 @@ namespace ts { return result; } - function createNodeBuilder(): NodeBuilder { - - interface NodeBuilderContext { - readonly enclosingDeclaration: Node | undefined; - readonly flags: NodeBuilderFlags | undefined; - encounteredError: boolean; - inObjectTypeLiteral: boolean; - checkAlias: boolean; - symbolStack: Symbol[] | undefined; - } - - function createNodeBuilderContext(enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): NodeBuilderContext { - return { - enclosingDeclaration, - flags, - encounteredError: false, - inObjectTypeLiteral: false, - checkAlias: true, - symbolStack: undefined - }; - } - + function createNodeBuilder() { let context: NodeBuilderContext; return { @@ -2247,6 +2226,26 @@ namespace ts { } }; + interface NodeBuilderContext { + readonly enclosingDeclaration: Node | undefined; + readonly flags: NodeBuilderFlags | undefined; + encounteredError: boolean; + inObjectTypeLiteral: boolean; + checkAlias: boolean; + symbolStack: Symbol[] | undefined; + } + + function createNodeBuilderContext(enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): NodeBuilderContext { + return { + enclosingDeclaration, + flags, + encounteredError: false, + inObjectTypeLiteral: false, + checkAlias: true, + symbolStack: undefined + }; + } + function typeToTypeNodeHelper(type: Type): TypeNode { if (!type) { context.encounteredError = true; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 178e6fe779..a93e8bddef 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2535,14 +2535,6 @@ namespace ts { /* @internal */ getTypeCount(): number; } - /** Note that any resulting nodes cannot be checked. */ - /* @internal */ - export interface NodeBuilder { - typeToTypeNode(type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeNode; - signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): SignatureDeclaration; - indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration; - } - export enum NodeBuilderFlags { None = 0, allowThisInObjectLiteral = 1 << 0, From fb4e3d87bd93a3299735271e659ca3e410ee1c2b Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Sun, 26 Mar 2017 22:45:13 -0700 Subject: [PATCH 154/164] essymbol and object --- src/compiler/checker.ts | 4 ++-- ...ts => codeFixClassImplementInterfaceProperty.ts} | 10 ++++++++-- ...FixClassImplementInterfacePropertyEnumLiteral.ts | 13 ------------- 3 files changed, 10 insertions(+), 17 deletions(-) rename tests/cases/fourslash/{codeFixClassImplementInterfacePropertyEnum.ts => codeFixClassImplementInterfaceProperty.ts} (57%) delete mode 100644 tests/cases/fourslash/codeFixClassImplementInterfacePropertyEnumLiteral.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3c2eb8c513..7a7ce2536f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2295,10 +2295,10 @@ namespace ts { return createKeywordTypeNode(SyntaxKind.NeverKeyword); } if (type.flags & TypeFlags.ESSymbol) { - throw new Error("ESSymbol not implemented"); + return createKeywordTypeNode(SyntaxKind.SymbolKeyword); } if (type.flags & TypeFlags.NonPrimitive) { - throw new Error("Non primitive not implemented"); + return createKeywordTypeNode(SyntaxKind.ObjectKeyword); } if (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType) { if (context.inObjectTypeLiteral) { diff --git a/tests/cases/fourslash/codeFixClassImplementInterfacePropertyEnum.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceProperty.ts similarity index 57% rename from tests/cases/fourslash/codeFixClassImplementInterfacePropertyEnum.ts rename to tests/cases/fourslash/codeFixClassImplementInterfaceProperty.ts index 8b04e4a4b4..53cfce5ff6 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfacePropertyEnum.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceProperty.ts @@ -4,10 +4,16 @@ //// enum E { a,b,c } //// interface I { -//// a: E; +//// x: E; +//// y: E.a +//// z: symbol; +//// w: object; //// } //// class C implements I {[| |]} verify.rangeAfterCodeFix(` - a: E; + x: E; + y: E.a; + z: symbol; + w: object; `); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixClassImplementInterfacePropertyEnumLiteral.ts b/tests/cases/fourslash/codeFixClassImplementInterfacePropertyEnumLiteral.ts deleted file mode 100644 index 720acc1ccc..0000000000 --- a/tests/cases/fourslash/codeFixClassImplementInterfacePropertyEnumLiteral.ts +++ /dev/null @@ -1,13 +0,0 @@ -/// - -// @lib: es2017 - -//// enum E { a,b,c } -//// interface I { -//// a: E.a -//// } -//// class C implements I {[| |]} - -verify.rangeAfterCodeFix(` - a: E.a; -`); \ No newline at end of file From a39bb0aaaaa161daeaac2c84ca0aaa1ade913418 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Mon, 27 Mar 2017 00:34:48 -0700 Subject: [PATCH 155/164] midway through response to ron's comments --- src/compiler/checker.ts | 64 +++++++-------- src/compiler/factory.ts | 167 +++++++++++++++++++--------------------- src/compiler/types.ts | 6 +- 3 files changed, 110 insertions(+), 127 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7a7ce2536f..6c24def150 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2384,13 +2384,13 @@ namespace ts { function createMappedTypeNodeFromType(type: MappedType) { Debug.assert(!!(type.flags & TypeFlags.Object)); - const typeParameter = getTypeParameterFromMappedType(type); + const typeParameter = getTypeParameterFromMappedType(type); const typeParameterNode = typeParameterToDeclaration(typeParameter); - const templateType = getTemplateTypeFromMappedType(type); - const templateTypeNode = templateType && typeToTypeNodeHelper(templateType); - const readonlyToken = (type).declaration && (type).declaration.readonlyToken ? createToken(SyntaxKind.ReadonlyKeyword) : undefined; - const questionToken = (type).declaration && (type).declaration.questionToken ? createToken(SyntaxKind.QuestionToken) : undefined; + const templateType = getTemplateTypeFromMappedType(type); + const templateTypeNode = typeToTypeNodeHelper(templateType); + const readonlyToken = type.declaration && type.declaration.readonlyToken ? createToken(SyntaxKind.ReadonlyKeyword) : undefined; + const questionToken = type.declaration && type.declaration.questionToken ? createToken(SyntaxKind.QuestionToken) : undefined; return createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode); } @@ -2402,7 +2402,7 @@ namespace ts { if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) || symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule) || shouldWriteTypeOfFunctionSymbol()) { - return createTypeQueryNodeFromType(type); + return createTypeQueryNodeFromSymbol(symbol); } else if (contains(context.symbolStack, symbol)) { // If type is an anonymous type literal in a type alias declaration, use type alias name @@ -2477,12 +2477,9 @@ namespace ts { return createTypeLiteralNode(members); } - function createTypeQueryNodeFromType(type: Type) { - const symbol = type.symbol; - if (symbol) { - const entityName = symbolToName(symbol, /*expectsIdentifier*/ false); - return createTypeQueryNode(entityName); - } + function createTypeQueryNodeFromSymbol(symbol: Symbol) { + const entityName = symbolToName(symbol, /*expectsIdentifier*/ false); + return createTypeQueryNode(entityName); } function typeReferenceToTypeNode(type: TypeReference) { @@ -2542,7 +2539,7 @@ namespace ts { entityName = nameIdentifier; } const typeParameterCount = (type.target.typeParameters || emptyArray).length; - const typeArgumentNodes = typeArguments.length > 0 ? mapToTypeNodeArray(typeArguments.slice(i, typeParameterCount - i)) : undefined; + const typeArgumentNodes = some(typeArguments) ? mapToTypeNodeArray(typeArguments.slice(i, typeParameterCount - i)) : undefined; return createTypeReferenceNode(entityName, typeArgumentNodes); } } @@ -2604,13 +2601,13 @@ namespace ts { const name = getNameFromIndexInfo(indexInfo); const indexingParameter = createParameter( - /*decorators*/ undefined, - /*modifiers*/ undefined, - /*dotDotDotToken*/ undefined, + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, name, - /*questionToken*/ undefined, + /*questionToken*/ undefined, indexerTypeNode, - /*initializer*/ undefined); + /*initializer*/ undefined); const typeNode = typeToTypeNodeHelper(indexInfo.type); return createIndexSignatureDeclaration( [indexingParameter], @@ -2623,21 +2620,14 @@ namespace ts { const typeParameters = signature.typeParameters && signature.typeParameters.map(parameter => typeParameterToDeclaration(parameter)); const parameters = signature.parameters.map(parameter => symbolToParameterDeclaration(parameter)); - const returnTypeNode = typeToTypeNodeExceptAny(getReturnTypeOfSignature(signature)); + const returnType = getReturnTypeOfSignature(signature); + const returnTypeNode = returnType && typeToTypeNodeHelper(returnType); + const returnTypeNodeExceptAny = returnTypeNode && returnTypeNode.kind !== SyntaxKind.AnyKeyword ? returnTypeNode : undefined; - return createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNode); - - function typeToTypeNodeExceptAny(type: Type): TypeNode | undefined { - const typeNode = type && typeToTypeNodeHelper(type); - return typeNode && typeNode.kind !== SyntaxKind.AnyKeyword ? typeNode : undefined; - } + return createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNodeExceptAny); } function typeParameterToDeclaration(type: TypeParameter): TypeParameterDeclaration { - if (!(type && type.symbol && type.flags & TypeFlags.TypeParameter)) { - return undefined; - } - const constraint = getConstraintFromTypeParameter(type); const constraintNode = constraint && typeToTypeNodeHelper(constraint); const defaultParameter = getDefaultFromTypeParameter(type); @@ -2647,10 +2637,10 @@ namespace ts { } function symbolToParameterDeclaration(parameterSymbol: Symbol): ParameterDeclaration { - const parameterDeclaration = parameterSymbol.declarations[0] as ParameterDeclaration; + const parameterDeclaration = getDeclarationOfKind(parameterSymbol, SyntaxKind.Parameter); const parameterType = getTypeOfSymbol(parameterSymbol); const parameterTypeNode = typeToTypeNodeHelper(parameterType); - // TODO(aozgaa): check initializer accessibility correctly. + // TODO(aozgaa): In the future, check initializer accessibility. const parameterNode = createParameter( parameterDeclaration.decorators, parameterDeclaration.modifiers, @@ -2666,7 +2656,6 @@ namespace ts { function symbolToName(symbol: Symbol, expectsIdentifier: true): Identifier; function symbolToName(symbol: Symbol, expectsIdentifier: false): EntityName; function symbolToName(symbol: Symbol, expectsIdentifier: boolean): EntityName { - let parentSymbol: Symbol; // Try to get qualified name if the symbol is not a type parameter and there is an enclosing declaration. let chain: Symbol[]; @@ -2679,8 +2668,6 @@ namespace ts { chain = [symbol]; } - parentSymbol = undefined; - if (expectsIdentifier && chain.length !== 1 && !context.encounteredError && !(context.flags & NodeBuilderFlags.allowQualifedNameInPlaceOfIdentifier)) { @@ -2728,6 +2715,7 @@ namespace ts { /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */ function getSymbolChain(symbol: Symbol, meaning: SymbolFlags, endOfChain: boolean): Symbol[] | undefined { let accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, /*useOnlyExternalAliasing*/false); + let parentSymbol: Symbol; if (!accessibleSymbolChain || needsQualification(accessibleSymbolChain[0], context.enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) { @@ -2737,6 +2725,7 @@ namespace ts { if (parent) { const parentChain = getSymbolChain(parent, getQualifiedLeftMeaning(meaning), /*endOfChain*/ false); if (parentChain) { + parentSymbol = parent; accessibleSymbolChain = parentChain.concat(accessibleSymbolChain || [symbol]); } } @@ -2745,8 +2734,7 @@ namespace ts { if (accessibleSymbolChain) { return accessibleSymbolChain; } - - else if ( + if ( // If this is the last part of outputting the symbol, always output. The cases apply only to parent symbols. endOfChain || // If a parent symbol is an external module, don't write it. (We prefer just `x` vs `"foo/bar".x`.) @@ -2759,8 +2747,8 @@ namespace ts { } function getNameOfSymbol(symbol: Symbol): string { - if (symbol.declarations && symbol.declarations.length) { - const declaration = symbol.declarations[0]; + const declaration = firstOrUndefined(symbol.declarations); + if (declaration) { if (declaration.name) { return declarationNameToString(declaration.name); } diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index e1e4e2c4ae..4c5a4b4067 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -46,9 +46,6 @@ namespace ts { */ /* @internal */ export function getSynthesizedClone(node: T | undefined): T { - if (node === undefined) { - return undefined; - } // We don't use "clone" from core.ts here, as we need to preserve the prototype chain of // the original node. We also need to exclude specific properties and only include own- // properties (to skip members already defined on the shared prototype). @@ -169,23 +166,23 @@ namespace ts { // Reserved words export function createSuper() { - return createSynthesizedNode(SyntaxKind.SuperKeyword); + return createSynthesizedNode(SyntaxKind.SuperKeyword); } export function createThis() { - return createSynthesizedNode(SyntaxKind.ThisKeyword); + return >createSynthesizedNode(SyntaxKind.ThisKeyword); } export function createNull() { - return createSynthesizedNode(SyntaxKind.NullKeyword); + return >createSynthesizedNode(SyntaxKind.NullKeyword); } export function createTrue() { - return createSynthesizedNode(SyntaxKind.TrueKeyword); + return >createSynthesizedNode(SyntaxKind.TrueKeyword); } export function createFalse() { - return createSynthesizedNode(SyntaxKind.FalseKeyword); + return >createSynthesizedNode(SyntaxKind.FalseKeyword); } // Names @@ -218,11 +215,74 @@ namespace ts { // Type Elements - // TODO: add signatures + export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) { + const signatureDeclaration = createSynthesizedNode(kind) as SignatureDeclaration; + signatureDeclaration.typeParameters = asNodeArray(typeParameters); + signatureDeclaration.parameters = asNodeArray(parameters); + signatureDeclaration.type = type; + return signatureDeclaration; + } + + function updateSignatureDeclaration(node: SignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) { + return node.typeParameters !== typeParameters + || node.parameters !== parameters + || node.type !== type + ? updateNode(createSignatureDeclaration(node.kind, typeParameters, parameters, type), node) + : node; + } + + export function createFunctionTypeNode(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) { + return createSignatureDeclaration(SyntaxKind.FunctionType, typeParameters, parameters, type) as FunctionTypeNode; + } + + export function updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) { + return updateSignatureDeclaration(node, typeParameters, parameters, type); + } + + export function createConstructorTypeNode(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) { + return createSignatureDeclaration(SyntaxKind.ConstructorType, typeParameters, parameters, type) as ConstructorTypeNode; + } + + export function updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) { + return updateSignatureDeclaration(node, typeParameters, parameters, type); + } + + export function createCallSignatureDeclaration(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) { + return createSignatureDeclaration(SyntaxKind.CallSignature, typeParameters, parameters, type) as CallSignatureDeclaration; + } + + export function updateCallSignatureDeclaration(node: CallSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) { + return updateSignatureDeclaration(node, typeParameters, parameters, type); + } + + export function createConstructSignatureDeclaration(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) { + return createSignatureDeclaration(SyntaxKind.ConstructSignature, typeParameters, parameters, type) as ConstructSignatureDeclaration; + } + + export function updateConstructSignatureDeclaration(node: ConstructSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) { + return updateSignatureDeclaration(node, typeParameters, parameters, type); + } + + export function createMethodSignature(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined) { + const methodSignature = createSignatureDeclaration(SyntaxKind.MethodSignature, typeParameters, parameters, type) as MethodSignature; + methodSignature.name = asName(name); + methodSignature.questionToken = questionToken; + return methodSignature; + } + + export function updateMethodSignature(node: MethodSignature, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined, name: PropertyName, questionToken: QuestionToken | undefined) { + return node.typeParameters !== typeParameters + || node.parameters !== parameters + || node.type !== type + || node.name !== name + || node.questionToken !== questionToken + ? updateNode(createMethodSignature(typeParameters, parameters, type, name, questionToken), node) + : node; + } // Types - export function createKeywordTypeNode(kind: KeywordTypeNode["kind"]): KeywordTypeNode { + export function createKeywordTypeNode(kind: KeywordTypeNode["kind"]) { return createSynthesizedNode(kind); } @@ -259,10 +319,10 @@ namespace ts { } export function updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName) { - return node.exprName !== exprName ? updateNode(createTypeQueryNode(exprName) , node) : node; + return node.exprName !== exprName ? updateNode(createTypeQueryNode(exprName), node) : node; } - export function createArrayTypeNode(elementType: TypeNode): ArrayTypeNode { + export function createArrayTypeNode(elementType: TypeNode) { const arrayTypeNode = createSynthesizedNode(SyntaxKind.ArrayType) as ArrayTypeNode; arrayTypeNode.elementType = elementType; return arrayTypeNode; @@ -277,9 +337,9 @@ namespace ts { export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType, types: TypeNode[]): UnionTypeNode; export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.IntersectionType, types: TypeNode[]): IntersectionTypeNode; export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: TypeNode[]): UnionOrIntersectionTypeNode; - export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: TypeNode[]): UnionOrIntersectionTypeNode { + export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: TypeNode[]) { const unionTypeNode = createSynthesizedNode(kind) as UnionTypeNode | IntersectionTypeNode; - unionTypeNode.types = asNodeArray(types); + unionTypeNode.types = createNodeArray(types); return unionTypeNode; } @@ -291,7 +351,7 @@ namespace ts { export function createTypeLiteralNode(members: TypeElement[]) { const typeLiteralNode = createSynthesizedNode(SyntaxKind.TypeLiteral) as TypeLiteralNode; - typeLiteralNode.members = asNodeArray(members); + typeLiteralNode.members = createNodeArray(members); return typeLiteralNode; } @@ -303,7 +363,7 @@ namespace ts { export function createTupleTypeNode(elementTypes: TypeNode[]) { const tupleTypeNode = createSynthesizedNode(SyntaxKind.TupleType) as TupleTypeNode; - tupleTypeNode.elementTypes = asNodeArray(elementTypes); + tupleTypeNode.elementTypes = createNodeArray(elementTypes); return tupleTypeNode; } @@ -349,7 +409,6 @@ namespace ts { return indexedAccessTypeNode; } - export function updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) { return node.objectType !== objectType || node.indexType !== indexType @@ -357,86 +416,22 @@ namespace ts { : node; } - // Type Declarations - export function createTypeParameterDeclaration(name: string | Identifier, constraint: TypeNode | undefined, defaultParameter: TypeNode | undefined) { + export function createTypeParameterDeclaration(name: string | Identifier, constraint: TypeNode | undefined, defaultType: TypeNode | undefined) { const typeParameter = createSynthesizedNode(SyntaxKind.TypeParameter) as TypeParameterDeclaration; typeParameter.name = asName(name); typeParameter.constraint = constraint; - typeParameter.default = defaultParameter; + typeParameter.default = defaultType; return typeParameter; } - export function updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode | undefined, defaultParameter: TypeNode | undefined) { + export function updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode | undefined, defaultType: TypeNode | undefined) { return node.name !== name || node.constraint !== constraint - || node.default !== defaultParameter - ? updateNode(createTypeParameterDeclaration(name, constraint, defaultParameter), node) - : node; - } - - // TODO: Split according to AST nodes. - export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) { - const signatureDeclaration = createSynthesizedNode(kind) as SignatureDeclaration; - signatureDeclaration.typeParameters = asNodeArray(typeParameters); - signatureDeclaration.parameters = asNodeArray(parameters); - signatureDeclaration.type = type; - return signatureDeclaration; - } - - export function updateSignatureDeclaration(node: SignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) { - return node.typeParameters !== typeParameters - || node.parameters !== parameters - || node.type !== type - ? updateNode(createSignatureDeclaration(node.kind, typeParameters, parameters, type), node) - : node; - } - - export function createFunctionTypeNode(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined): FunctionTypeNode { - return createSignatureDeclaration(SyntaxKind.FunctionType, typeParameters, parameters, type) as FunctionTypeNode; - } - - export function updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): FunctionTypeNode { - return updateSignatureDeclaration(node, typeParameters, parameters, type); - } - - export function createConstructorTypeNode(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined): ConstructorTypeNode { - return createSignatureDeclaration(SyntaxKind.ConstructorType, typeParameters, parameters, type) as ConstructorTypeNode; - } - export function updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): ConstructorTypeNode { - return updateSignatureDeclaration(node, typeParameters, parameters, type); - } - - export function createCallSignatureDeclaration(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined): CallSignatureDeclaration { - return createSignatureDeclaration(SyntaxKind.CallSignature, typeParameters, parameters, type) as CallSignatureDeclaration; - } - export function updateCallSignatureDeclaration(node: CallSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): CallSignatureDeclaration { - return updateSignatureDeclaration(node, typeParameters, parameters, type); - } - - export function createConstructSignatureDeclaration(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined): ConstructSignatureDeclaration { - return createSignatureDeclaration(SyntaxKind.ConstructSignature, typeParameters, parameters, type) as ConstructSignatureDeclaration; - } - export function updateConstructSignatureDeclaration(node: ConstructSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): ConstructSignatureDeclaration { - return updateSignatureDeclaration(node, typeParameters, parameters, type); - } - - export function createMethodSignature(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined): MethodSignature { - const methodSignature = createSignatureDeclaration(SyntaxKind.MethodSignature, typeParameters, parameters, type) as MethodSignature; - methodSignature.name = asName(name); - methodSignature.questionToken = questionToken; - return methodSignature; - } - - export function updateMethodSignature(node: MethodSignature, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined, name?: PropertyName, questionToken?: QuestionToken): MethodSignature { - return node.typeParameters !== typeParameters - || node.parameters !== parameters - || node.type !== type - || node.name !== name - || node.questionToken !== questionToken - ? updateNode(createMethodSignature(typeParameters, parameters, type, name, questionToken), node) + || node.default !== defaultType + ? updateNode(createTypeParameterDeclaration(name, constraint, defaultType), node) : node; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a93e8bddef..45a4de01c9 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1034,15 +1034,15 @@ namespace ts { _primaryExpressionBrand: any; } - export interface NullLiteral extends PrimaryExpression { + export interface NullLiteral extends PrimaryExpression, TypeNode { kind: SyntaxKind.NullKeyword; } - export interface BooleanLiteral extends PrimaryExpression { + export interface BooleanLiteral extends PrimaryExpression, TypeNode { kind: SyntaxKind.TrueKeyword | SyntaxKind.FalseKeyword; } - export interface ThisExpression extends PrimaryExpression { + export interface ThisExpression extends PrimaryExpression, TypeNode { kind: SyntaxKind.ThisKeyword; } From cca7ac25578593db034bfa09df33558b105b5a8c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 27 Mar 2017 11:37:27 +0200 Subject: [PATCH 156/164] Use immediate constraint, not base constraint, of indexed access --- src/compiler/checker.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 70cbda14f6..b29916c62f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7942,16 +7942,9 @@ namespace ts { } } else if (target.flags & TypeFlags.IndexedAccess) { - // if we have indexed access types with identical index types, see if relationship holds for - // the two object types. - if (source.flags & TypeFlags.IndexedAccess && (source).indexType === (target).indexType) { - if (result = isRelatedTo((source).objectType, (target).objectType, reportErrors)) { - return result; - } - } // A type S is related to a type T[K] if S is related to A[K], where K is string-like and // A is the apparent type of S. - const constraint = getBaseConstraintOfType(target); + const constraint = getConstraintOfType(target); if (constraint) { if (result = isRelatedTo(source, constraint, reportErrors)) { errorInfo = saveErrorInfo; @@ -7998,6 +7991,13 @@ namespace ts { return result; } } + else if (target.flags & TypeFlags.IndexedAccess && (source).indexType === (target).indexType) { + // if we have indexed access types with identical index types, see if relationship holds for + // the two object types. + if (result = isRelatedTo((source).objectType, (target).objectType, reportErrors)) { + return result; + } + } } else { if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (source).target === (target).target) { From 4aeab77783bbae630b3708ca2da42baa8a04cb86 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 27 Mar 2017 11:38:05 +0200 Subject: [PATCH 157/164] Accept new baselines --- .../mappedTypeRelationships.errors.txt | 128 ++++++++++++++---- 1 file changed, 104 insertions(+), 24 deletions(-) diff --git a/tests/baselines/reference/mappedTypeRelationships.errors.txt b/tests/baselines/reference/mappedTypeRelationships.errors.txt index bc26bb272f..ec2bacbe66 100644 --- a/tests/baselines/reference/mappedTypeRelationships.errors.txt +++ b/tests/baselines/reference/mappedTypeRelationships.errors.txt @@ -1,39 +1,71 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(12,5): error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. Type 'T[string]' is not assignable to type 'U[keyof T]'. - Type 'T' is not assignable to type 'U'. + Type 'T[string]' is not assignable to type 'U[string]'. + Type 'T' is not assignable to type 'U'. + Type 'T[keyof T]' is not assignable to type 'U[string]'. + Type 'T[string]' is not assignable to type 'U[string]'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(17,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. Type 'T[string]' is not assignable to type 'U[K]'. - Type 'T' is not assignable to type 'U'. + Type 'T[string]' is not assignable to type 'U[string]'. + Type 'T' is not assignable to type 'U'. + Type 'T[K]' is not assignable to type 'U[string]'. + Type 'T[string]' is not assignable to type 'U[string]'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(21,5): error TS2536: Type 'keyof U' cannot be used to index type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(22,5): error TS2322: Type 'T[keyof U]' is not assignable to type 'U[keyof U]'. Type 'T[string]' is not assignable to type 'U[keyof U]'. - Type 'T' is not assignable to type 'U'. + Type 'T[string]' is not assignable to type 'U[string]'. + Type 'T' is not assignable to type 'U'. + Type 'T[keyof U]' is not assignable to type 'U[string]'. + Type 'T[string]' is not assignable to type 'U[string]'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(22,12): error TS2536: Type 'keyof U' cannot be used to index type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(26,5): error TS2536: Type 'K' cannot be used to index type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(27,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. Type 'T[string]' is not assignable to type 'U[K]'. - Type 'T' is not assignable to type 'U'. + Type 'T[string]' is not assignable to type 'U[string]'. + Type 'T' is not assignable to type 'U'. + Type 'T[K]' is not assignable to type 'U[string]'. + Type 'T[string]' is not assignable to type 'U[string]'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(27,12): error TS2536: Type 'K' cannot be used to index type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(31,5): error TS2322: Type 'T[keyof T] | undefined' is not assignable to type 'T[keyof T]'. Type 'undefined' is not assignable to type 'T[keyof T]'. + Type 'undefined' is not assignable to type 'T[string]'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(36,5): error TS2322: Type 'T[K] | undefined' is not assignable to type 'T[K]'. Type 'undefined' is not assignable to type 'T[K]'. + Type 'undefined' is not assignable to type 'T[string]'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(41,5): error TS2322: Type 'U[keyof T] | undefined' is not assignable to type 'T[keyof T]'. Type 'undefined' is not assignable to type 'T[keyof T]'. + Type 'undefined' is not assignable to type 'T[string]'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(42,5): error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T] | undefined'. Type 'T[string]' is not assignable to type 'U[keyof T] | undefined'. Type 'T[string]' is not assignable to type 'U[keyof T]'. - Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. - Type 'T[string]' is not assignable to type 'U[keyof T]'. - Type 'T' is not assignable to type 'U'. + Type 'T[string]' is not assignable to type 'U[string]'. + Type 'T' is not assignable to type 'U'. + Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. + Type 'T[string]' is not assignable to type 'U[keyof T]'. + Type 'T[string]' is not assignable to type 'U[string]'. + Type 'T' is not assignable to type 'U'. + Type 'T[keyof T]' is not assignable to type 'U[string]'. + Type 'T[string]' is not assignable to type 'U[string]'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(46,5): error TS2322: Type 'U[K] | undefined' is not assignable to type 'T[K]'. Type 'undefined' is not assignable to type 'T[K]'. + Type 'undefined' is not assignable to type 'T[string]'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(47,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K] | undefined'. Type 'T[string]' is not assignable to type 'U[K] | undefined'. Type 'T[string]' is not assignable to type 'U[K]'. - Type 'T[K]' is not assignable to type 'U[K]'. - Type 'T[string]' is not assignable to type 'U[K]'. - Type 'T' is not assignable to type 'U'. + Type 'T[string]' is not assignable to type 'U[string]'. + Type 'T' is not assignable to type 'U'. + Type 'T[K]' is not assignable to type 'U[K]'. + Type 'T[string]' is not assignable to type 'U[K]'. + Type 'T[string]' is not assignable to type 'U[string]'. + Type 'T' is not assignable to type 'U'. + Type 'T[K]' is not assignable to type 'U[string]'. + Type 'T[string]' is not assignable to type 'U[string]'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(52,5): error TS2542: Index signature in type 'Readonly' only permits reading. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(57,5): error TS2542: Index signature in type 'Readonly' only permits reading. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(62,5): error TS2542: Index signature in type 'Readonly' only permits reading. @@ -44,7 +76,11 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(126,5): error TS tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(142,5): error TS2322: Type '{ [P in keyof T]: T[P]; }' is not assignable to type '{ [P in keyof T]: U[P]; }'. Type 'T[P]' is not assignable to type 'U[P]'. Type 'T[string]' is not assignable to type 'U[P]'. - Type 'T' is not assignable to type 'U'. + Type 'T[string]' is not assignable to type 'U[string]'. + Type 'T' is not assignable to type 'U'. + Type 'T[P]' is not assignable to type 'U[string]'. + Type 'T[string]' is not assignable to type 'U[string]'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(147,5): error TS2322: Type '{ [P in keyof T]: T[P]; }' is not assignable to type '{ [P in keyof U]: U[P]; }'. Type 'keyof U' is not assignable to type 'keyof T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(152,5): error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in keyof T]: T[P]; }'. @@ -56,7 +92,11 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(162,5): error TS tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(167,5): error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in K]: U[P]; }'. Type 'T[P]' is not assignable to type 'U[P]'. Type 'T[string]' is not assignable to type 'U[P]'. - Type 'T' is not assignable to type 'U'. + Type 'T[string]' is not assignable to type 'U[string]'. + Type 'T' is not assignable to type 'U'. + Type 'T[P]' is not assignable to type 'U[string]'. + Type 'T[string]' is not assignable to type 'U[string]'. + Type 'T' is not assignable to type 'U'. ==== tests/cases/conformance/types/mapped/mappedTypeRelationships.ts (27 errors) ==== @@ -75,7 +115,11 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(167,5): error TS ~~~~ !!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. !!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. } function f4(x: T, y: U, k: K) { @@ -84,7 +128,11 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(167,5): error TS ~~~~ !!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. !!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[K]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. } function f5(x: T, y: U, k: keyof U) { @@ -95,7 +143,11 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(167,5): error TS ~~~~ !!! error TS2322: Type 'T[keyof U]' is not assignable to type 'U[keyof U]'. !!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof U]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[keyof U]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. ~~~~ !!! error TS2536: Type 'keyof U' cannot be used to index type 'T'. } @@ -108,7 +160,11 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(167,5): error TS ~~~~ !!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. !!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[K]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. ~~~~ !!! error TS2536: Type 'K' cannot be used to index type 'T'. } @@ -118,6 +174,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(167,5): error TS ~~~~ !!! error TS2322: Type 'T[keyof T] | undefined' is not assignable to type 'T[keyof T]'. !!! error TS2322: Type 'undefined' is not assignable to type 'T[keyof T]'. +!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'. y[k] = x[k]; } @@ -126,6 +183,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(167,5): error TS ~~~~ !!! error TS2322: Type 'T[K] | undefined' is not assignable to type 'T[K]'. !!! error TS2322: Type 'undefined' is not assignable to type 'T[K]'. +!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'. y[k] = x[k]; } @@ -134,14 +192,21 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(167,5): error TS ~~~~ !!! error TS2322: Type 'U[keyof T] | undefined' is not assignable to type 'T[keyof T]'. !!! error TS2322: Type 'undefined' is not assignable to type 'T[keyof T]'. +!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'. y[k] = x[k]; // Error ~~~~ !!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T] | undefined'. !!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T] | undefined'. !!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. } function f13(x: T, y: Partial, k: K) { @@ -149,14 +214,21 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(167,5): error TS ~~~~ !!! error TS2322: Type 'U[K] | undefined' is not assignable to type 'T[K]'. !!! error TS2322: Type 'undefined' is not assignable to type 'T[K]'. +!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'. y[k] = x[k]; // Error ~~~~ !!! error TS2322: Type 'T[K]' is not assignable to type 'U[K] | undefined'. !!! error TS2322: Type 'T[string]' is not assignable to type 'U[K] | undefined'. !!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[K]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. } function f20(x: T, y: Readonly, k: keyof T) { @@ -270,7 +342,11 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(167,5): error TS !!! error TS2322: Type '{ [P in keyof T]: T[P]; }' is not assignable to type '{ [P in keyof T]: U[P]; }'. !!! error TS2322: Type 'T[P]' is not assignable to type 'U[P]'. !!! error TS2322: Type 'T[string]' is not assignable to type 'U[P]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[P]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. } function f72(x: { [P in keyof T]: T[P] }, y: { [P in keyof U]: U[P] }) { @@ -312,6 +388,10 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(167,5): error TS !!! error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in K]: U[P]; }'. !!! error TS2322: Type 'T[P]' is not assignable to type 'U[P]'. !!! error TS2322: Type 'T[string]' is not assignable to type 'U[P]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[P]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. } \ No newline at end of file From 0b8a9fc3d0d912276d12d025bcaff60dff41e194 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 27 Mar 2017 11:44:49 +0200 Subject: [PATCH 158/164] Add regression test --- .../reference/indexedAccessRelation.js | 56 +++++++++++++++++++ .../reference/indexedAccessRelation.symbols | 53 ++++++++++++++++++ .../reference/indexedAccessRelation.types | 55 ++++++++++++++++++ tests/cases/compiler/indexedAccessRelation.ts | 18 ++++++ 4 files changed, 182 insertions(+) create mode 100644 tests/baselines/reference/indexedAccessRelation.js create mode 100644 tests/baselines/reference/indexedAccessRelation.symbols create mode 100644 tests/baselines/reference/indexedAccessRelation.types create mode 100644 tests/cases/compiler/indexedAccessRelation.ts diff --git a/tests/baselines/reference/indexedAccessRelation.js b/tests/baselines/reference/indexedAccessRelation.js new file mode 100644 index 0000000000..c58c214e69 --- /dev/null +++ b/tests/baselines/reference/indexedAccessRelation.js @@ -0,0 +1,56 @@ +//// [indexedAccessRelation.ts] +// Repro from #14723 + +class Component { + setState(state: Pick) {} +} + +export interface State { + a?: T; +} + +class Foo {} + +class Comp extends Component> +{ + foo(a: T) { + this.setState({ a: a }); + } +} + + +//// [indexedAccessRelation.js] +// Repro from #14723 +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +exports.__esModule = true; +var Component = (function () { + function Component() { + } + Component.prototype.setState = function (state) { }; + return Component; +}()); +var Foo = (function () { + function Foo() { + } + return Foo; +}()); +var Comp = (function (_super) { + __extends(Comp, _super); + function Comp() { + return _super !== null && _super.apply(this, arguments) || this; + } + Comp.prototype.foo = function (a) { + this.setState({ a: a }); + }; + return Comp; +}(Component)); diff --git a/tests/baselines/reference/indexedAccessRelation.symbols b/tests/baselines/reference/indexedAccessRelation.symbols new file mode 100644 index 0000000000..40fa52652f --- /dev/null +++ b/tests/baselines/reference/indexedAccessRelation.symbols @@ -0,0 +1,53 @@ +=== tests/cases/compiler/indexedAccessRelation.ts === +// Repro from #14723 + +class Component { +>Component : Symbol(Component, Decl(indexedAccessRelation.ts, 0, 0)) +>S : Symbol(S, Decl(indexedAccessRelation.ts, 2, 16)) + + setState(state: Pick) {} +>setState : Symbol(Component.setState, Decl(indexedAccessRelation.ts, 2, 20)) +>K : Symbol(K, Decl(indexedAccessRelation.ts, 3, 13)) +>S : Symbol(S, Decl(indexedAccessRelation.ts, 2, 16)) +>state : Symbol(state, Decl(indexedAccessRelation.ts, 3, 32)) +>Pick : Symbol(Pick, Decl(lib.d.ts, --, --)) +>S : Symbol(S, Decl(indexedAccessRelation.ts, 2, 16)) +>K : Symbol(K, Decl(indexedAccessRelation.ts, 3, 13)) +} + +export interface State { +>State : Symbol(State, Decl(indexedAccessRelation.ts, 4, 1)) +>T : Symbol(T, Decl(indexedAccessRelation.ts, 6, 23)) + + a?: T; +>a : Symbol(State.a, Decl(indexedAccessRelation.ts, 6, 27)) +>T : Symbol(T, Decl(indexedAccessRelation.ts, 6, 23)) +} + +class Foo {} +>Foo : Symbol(Foo, Decl(indexedAccessRelation.ts, 8, 1)) + +class Comp extends Component> +>Comp : Symbol(Comp, Decl(indexedAccessRelation.ts, 10, 12)) +>T : Symbol(T, Decl(indexedAccessRelation.ts, 12, 11)) +>Foo : Symbol(Foo, Decl(indexedAccessRelation.ts, 8, 1)) +>S : Symbol(S, Decl(indexedAccessRelation.ts, 12, 25)) +>Component : Symbol(Component, Decl(indexedAccessRelation.ts, 0, 0)) +>S : Symbol(S, Decl(indexedAccessRelation.ts, 12, 25)) +>State : Symbol(State, Decl(indexedAccessRelation.ts, 4, 1)) +>T : Symbol(T, Decl(indexedAccessRelation.ts, 12, 11)) +{ + foo(a: T) { +>foo : Symbol(Comp.foo, Decl(indexedAccessRelation.ts, 13, 1)) +>a : Symbol(a, Decl(indexedAccessRelation.ts, 14, 8)) +>T : Symbol(T, Decl(indexedAccessRelation.ts, 12, 11)) + + this.setState({ a: a }); +>this.setState : Symbol(Component.setState, Decl(indexedAccessRelation.ts, 2, 20)) +>this : Symbol(Comp, Decl(indexedAccessRelation.ts, 10, 12)) +>setState : Symbol(Component.setState, Decl(indexedAccessRelation.ts, 2, 20)) +>a : Symbol(a, Decl(indexedAccessRelation.ts, 15, 23)) +>a : Symbol(a, Decl(indexedAccessRelation.ts, 14, 8)) + } +} + diff --git a/tests/baselines/reference/indexedAccessRelation.types b/tests/baselines/reference/indexedAccessRelation.types new file mode 100644 index 0000000000..2564a82702 --- /dev/null +++ b/tests/baselines/reference/indexedAccessRelation.types @@ -0,0 +1,55 @@ +=== tests/cases/compiler/indexedAccessRelation.ts === +// Repro from #14723 + +class Component { +>Component : Component +>S : S + + setState(state: Pick) {} +>setState : (state: Pick) => void +>K : K +>S : S +>state : Pick +>Pick : Pick +>S : S +>K : K +} + +export interface State { +>State : State +>T : T + + a?: T; +>a : T +>T : T +} + +class Foo {} +>Foo : Foo + +class Comp extends Component> +>Comp : Comp +>T : T +>Foo : Foo +>S : S +>Component : Component> +>S : S +>State : State +>T : T +{ + foo(a: T) { +>foo : (a: T) => void +>a : T +>T : T + + this.setState({ a: a }); +>this.setState({ a: a }) : void +>this.setState : )>(state: Pick, K>) => void +>this : this +>setState : )>(state: Pick, K>) => void +>{ a: a } : { a: T; } +>a : T +>a : T + } +} + diff --git a/tests/cases/compiler/indexedAccessRelation.ts b/tests/cases/compiler/indexedAccessRelation.ts new file mode 100644 index 0000000000..ccfcd559e2 --- /dev/null +++ b/tests/cases/compiler/indexedAccessRelation.ts @@ -0,0 +1,18 @@ +// Repro from #14723 + +class Component { + setState(state: Pick) {} +} + +export interface State { + a?: T; +} + +class Foo {} + +class Comp extends Component> +{ + foo(a: T) { + this.setState({ a: a }); + } +} From 523ced704f49604bc566efa45a2026ab033d48f7 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Mon, 27 Mar 2017 16:51:38 +0100 Subject: [PATCH 159/164] symbolDisplay comment fix: "experts" vs "exports" --- src/services/symbolDisplay.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index b457165b67..3fcc467f6a 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -419,7 +419,7 @@ namespace ts.SymbolDisplay { if (!documentation) { documentation = symbol.getDocumentationComment(); if (documentation.length === 0 && symbol.flags & SymbolFlags.Property) { - // For some special property access expressions like `experts.foo = foo` or `module.exports.foo = foo` + // For some special property access expressions like `exports.foo = foo` or `module.exports.foo = foo` // there documentation comments might be attached to the right hand side symbol of their declarations. // The pattern of such special property access is that the parent symbol is the symbol of the file. if (symbol.parent && forEach(symbol.parent.declarations, declaration => declaration.kind === SyntaxKind.SourceFile)) { From 7340c4ca1ef40521b66074ece970cbfeec037ba3 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Mon, 27 Mar 2017 11:53:44 -0700 Subject: [PATCH 160/164] type predicate support --- src/compiler/checker.ts | 19 ++++++-- src/compiler/factory.ts | 35 ++++++++++---- src/compiler/types.ts | 8 +--- src/compiler/utilities.ts | 2 +- src/compiler/visitor.ts | 47 +++++-------------- src/services/codefixes/fixAddMissingMember.ts | 6 +-- src/services/codefixes/helpers.ts | 8 ---- src/services/textChanges.ts | 20 ++++++++ ...ssImplementInterfaceMethodTypePredicate.ts | 16 +++++++ 9 files changed, 93 insertions(+), 68 deletions(-) create mode 100644 tests/cases/fourslash/codeFixClassImplementInterfaceMethodTypePredicate.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6c24def150..2471ebcb52 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2610,18 +2610,27 @@ namespace ts { /*initializer*/ undefined); const typeNode = typeToTypeNodeHelper(indexInfo.type); return createIndexSignatureDeclaration( - [indexingParameter], - typeNode, /*decorators*/ undefined, - indexInfo.isReadonly ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined); + indexInfo.isReadonly ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined, + [indexingParameter], + typeNode); } function signatureToSignatureDeclarationHelper(signature: Signature, kind: SyntaxKind): SignatureDeclaration { const typeParameters = signature.typeParameters && signature.typeParameters.map(parameter => typeParameterToDeclaration(parameter)); const parameters = signature.parameters.map(parameter => symbolToParameterDeclaration(parameter)); - const returnType = getReturnTypeOfSignature(signature); - const returnTypeNode = returnType && typeToTypeNodeHelper(returnType); + let returnTypeNode: TypeNode | TypePredicate; + if (signature.typePredicate) { + const typePredicate = signature.typePredicate; + const parameterName = typePredicate.kind === TypePredicateKind.Identifier ? createIdentifier((typePredicate).parameterName) : createThisTypeNode(); + const typeNode = typeToTypeNodeHelper(typePredicate.type); + returnTypeNode = createTypePredicateNode(parameterName, typeNode); + } + else { + const returnType = getReturnTypeOfSignature(signature); + returnTypeNode = returnType && typeToTypeNodeHelper(returnType); + } const returnTypeNodeExceptAny = returnTypeNode && returnTypeNode.kind !== SyntaxKind.AnyKeyword ? returnTypeNode : undefined; return createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNodeExceptAny); diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 4c5a4b4067..66b3eb713e 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -286,6 +286,10 @@ namespace ts { return createSynthesizedNode(kind); } + export function createThisTypeNode() { + return createSynthesizedNode(SyntaxKind.ThisType); + } + export function createLiteralTypeNode(literal: Expression) { const literalTypeNode = createSynthesizedNode(SyntaxKind.LiteralType) as LiteralTypeNode; literalTypeNode.literal = literal; @@ -312,6 +316,20 @@ namespace ts { : node; } + export function createTypePredicateNode(parameterName: Identifier | ThisTypeNode | string, type: TypeNode) { + const typePredicateNode = createSynthesizedNode(SyntaxKind.TypePredicate) as TypePredicateNode; + typePredicateNode.parameterName = asName(parameterName); + typePredicateNode.type = type; + return typePredicateNode; + } + + export function updateTypePredicateNode(node: TypePredicateNode, parameterName: Identifier | ThisTypeNode, type: TypeNode) { + return node.parameterName !== parameterName + || node.type !== type + ? updateNode(createTypePredicateNode(parameterName, type), node) + : node; + } + export function createTypeQueryNode(exprName: EntityName) { const typeQueryNode = createSynthesizedNode(SyntaxKind.TypeQuery) as TypeQueryNode; typeQueryNode.exprName = exprName; @@ -455,21 +473,21 @@ namespace ts { : node; } - export function createIndexSignatureDeclaration(parameters: ParameterDeclaration[], type: TypeNode, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined): IndexSignatureDeclaration { + export function createIndexSignatureDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, parameters: ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration { const indexSignature = createSynthesizedNode(SyntaxKind.IndexSignature) as IndexSignatureDeclaration; - indexSignature.parameters = asNodeArray(parameters); - indexSignature.type = type; indexSignature.decorators = asNodeArray(decorators); indexSignature.modifiers = asNodeArray(modifiers); + indexSignature.parameters = createNodeArray(parameters); + indexSignature.type = type; return indexSignature; } - export function updateIndexSignatureDeclaration(node: IndexSignatureDeclaration, parameters: ParameterDeclaration[], type: TypeNode, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined) { + export function updateIndexSignatureDeclaration(node: IndexSignatureDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, parameters: ParameterDeclaration[], type: TypeNode) { return node.parameters !== parameters || node.type !== type || node.decorators !== decorators || node.modifiers !== modifiers - ? updateNode(createIndexSignatureDeclaration(parameters, type, decorators, modifiers), node) + ? updateNode(createIndexSignatureDeclaration(decorators, modifiers, parameters, type), node) : node; } @@ -542,7 +560,7 @@ namespace ts { node.name = asName(name); node.questionToken = questionToken; node.typeParameters = asNodeArray(typeParameters); - node.parameters = asNodeArray(parameters); + node.parameters = createNodeArray(parameters); node.type = type; node.body = body; return node; @@ -2052,7 +2070,8 @@ namespace ts { function asName(name: string | BindingName): BindingName; function asName(name: string | PropertyName): PropertyName; function asName(name: string | EntityName): EntityName; - function asName(name: string | Identifier | BindingName | PropertyName | QualifiedName) { + function asName(name: string | Identifier | ThisTypeNode): Identifier | ThisTypeNode; + function asName(name: string | Identifier | BindingName | PropertyName | QualifiedName | ThisTypeNode) { return typeof name === "string" ? createIdentifier(name) : name; } @@ -2060,7 +2079,7 @@ namespace ts { return typeof value === "string" || typeof value === "number" ? createLiteral(value) : value; } - export function asNodeArray(array: T[] | undefined): NodeArray | undefined { + function asNodeArray(array: T[] | undefined): NodeArray | undefined { return array ? createNodeArray(array) : undefined; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 45a4de01c9..038f8bf316 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1042,7 +1042,7 @@ namespace ts { kind: SyntaxKind.TrueKeyword | SyntaxKind.FalseKeyword; } - export interface ThisExpression extends PrimaryExpression, TypeNode { + export interface ThisExpression extends PrimaryExpression, KeywordTypeNode { kind: SyntaxKind.ThisKeyword; } @@ -3248,12 +3248,6 @@ namespace ts { declaration?: SignatureDeclaration; } - export interface SignatureParts { - typeParameters: TypeParameterDeclaration[] | undefined; - parameters: ParameterDeclaration[]; - type: TypeNode; - } - /* @internal */ export interface TypeMapper { (t: TypeParameter): Type; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index f4f288d0cb..33cb0d8f48 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3735,7 +3735,7 @@ namespace ts { * of a TypeNode. */ export function isTypeNode(node: Node): node is TypeNode { - return node && isTypeNodeKind(node.kind); + return isTypeNodeKind(node.kind); } // Binding patterns diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index b8eb0210d0..c110ea4227 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -3,26 +3,6 @@ /// namespace ts { - export const nullTransformationContext: TransformationContext = { - enableEmitNotification: noop, - enableSubstitution: noop, - endLexicalEnvironment: () => undefined, - getCompilerOptions: notImplemented, - getEmitHost: notImplemented, - getEmitResolver: notImplemented, - hoistFunctionDeclaration: noop, - hoistVariableDeclaration: noop, - isEmitNotificationEnabled: notImplemented, - isSubstitutionEnabled: notImplemented, - onEmitNode: noop, - onSubstituteNode: notImplemented, - readEmitHelpers: notImplemented, - requestEmitHelper: noop, - resumeLexicalEnvironment: noop, - startLexicalEnvironment: noop, - suspendLexicalEnvironment: noop - }; - /** * Visits a Node using the supplied visitor, possibly returning a new Node in its place. * @@ -234,7 +214,7 @@ namespace ts { const kind = node.kind; // No need to visit nodes with no children. - if ((kind > SyntaxKind.FirstToken && kind <= SyntaxKind.LastToken)) { + if ((kind > SyntaxKind.FirstToken && kind <= SyntaxKind.LastToken) || kind === SyntaxKind.ThisType) { return node; } @@ -293,10 +273,10 @@ namespace ts { case SyntaxKind.IndexSignature: return updateIndexSignatureDeclaration(node, - visitParameterList((node).parameters, visitor, context, nodesVisitor), - visitNode((node).type, visitor, isTypeNode), nodesVisitor((node).decorators, visitor, isDecorator), - nodesVisitor((node).modifiers, visitor, isModifier)); + nodesVisitor((node).modifiers, visitor, isModifier), + visitParameterList((node).parameters, visitor, context, nodesVisitor), + visitNode((node).type, visitor, isTypeNode)); case SyntaxKind.Parameter: return updateParameter(node, @@ -314,13 +294,16 @@ namespace ts { // Types - case SyntaxKind.TypePredicate: - throw new Error("reached unsupported type in visitor."); case SyntaxKind.TypeReference: return updateTypeReferenceNode(node, visitNode((node).typeName, visitor, isEntityName), nodesVisitor((node).typeArguments, visitor, isTypeNode)); + case SyntaxKind.TypePredicate: + return updateTypePredicateNode(node, + visitNode((node).parameterName, visitor), + visitNode((node).type, visitor, isTypeNode)); + case SyntaxKind.TypeQuery: return updateTypeQueryNode((node), visitNode((node).exprName, visitor, isEntityName)); @@ -339,9 +322,8 @@ namespace ts { nodesVisitor((node).types, visitor, isTypeNode)); case SyntaxKind.ParenthesizedType: - throw new Error("reached unsupported type in visitor."); - case SyntaxKind.ThisType: - throw new Error("reached unsupported type in visitor."); + Debug.fail("not implemented."); + case SyntaxKind.TypeOperator: return updateTypeOperatorNode(node, visitNode((node).type, visitor, isTypeNode)); case SyntaxKind.IndexedAccessType: @@ -376,13 +358,6 @@ namespace ts { visitNode((node).type, visitor, isTypeNode), visitNode((node).initializer, visitor, isExpression)); - case SyntaxKind.IndexSignature: - return updateIndexSignatureDeclaration(node, - visitParameterList((node).parameters, visitor, context, nodesVisitor), - visitNode((node).type, visitor, isTypeNode), - nodesVisitor((node).decorators, visitor, isDecorator), - nodesVisitor((node).modifiers, visitor, isModifier)); - case SyntaxKind.PropertyDeclaration: return updateProperty(node, nodesVisitor((node).decorators, visitor, isDecorator), diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index 4ef9fce067..bfb931e866 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -65,10 +65,10 @@ namespace ts.codefix { stringTypeNode, /*initializer*/ undefined); const indexSignature = createIndexSignatureDeclaration( - [indexingParameter], - typeNode, /*decorators*/undefined, - /*modifiers*/ undefined); + /*modifiers*/ undefined, + [indexingParameter], + typeNode); const indexSignatureChangeTracker = textChanges.ChangeTracker.fromCodeFixContext(context); indexSignatureChangeTracker.insertNodeAfter(sourceFile, openBrace, indexSignature, { suffix: context.newLineCharacter }); diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 49f95243c9..a7809cdd21 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -230,12 +230,4 @@ namespace ts.codefix { } return undefined; } - - function stripComments(node: Node): Node { - if (node === undefined) { - return node; - } - const strippedChildren = visitEachChild(node, stripComments, nullTransformationContext); - return strippedChildren === node ? getSynthesizedClone(strippedChildren) : strippedChildren; - } } \ No newline at end of file diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index f5b0ec678d..73d5fc61bc 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -528,6 +528,26 @@ namespace ts.textChanges { return skipTrivia(s, 0) === s.length; } + const nullTransformationContext: TransformationContext = { + enableEmitNotification: noop, + enableSubstitution: noop, + endLexicalEnvironment: () => undefined, + getCompilerOptions: notImplemented, + getEmitHost: notImplemented, + getEmitResolver: notImplemented, + hoistFunctionDeclaration: noop, + hoistVariableDeclaration: noop, + isEmitNotificationEnabled: notImplemented, + isSubstitutionEnabled: notImplemented, + onEmitNode: noop, + onSubstituteNode: notImplemented, + readEmitHelpers: notImplemented, + requestEmitHelper: noop, + resumeLexicalEnvironment: noop, + startLexicalEnvironment: noop, + suspendLexicalEnvironment: noop + }; + function assignPositionsToNode(node: Node): Node { const visited = visitEachChild(node, assignPositionsToNode, nullTransformationContext, assignPositionsToNodeArray, assignPositionsToNode); // create proxy node for non synthesized nodes diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceMethodTypePredicate.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceMethodTypePredicate.ts new file mode 100644 index 0000000000..2eb6c2fabc --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceMethodTypePredicate.ts @@ -0,0 +1,16 @@ +/// + +//// interface I { +//// f(i: any): i is I; +//// f(): this is I; +//// } +//// +//// class C implements I {[| |]} + +verify.rangeAfterCodeFix(` +f(i: any): i is I; +f(): this is I; +f(i?: any) { + throw new Error("Method not implemented."); +} +`); From 4329b4524eb4b215752fc2a81d1676d8d4830aea Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Mon, 27 Mar 2017 12:01:56 -0700 Subject: [PATCH 161/164] Cleanup --- src/compiler/visitor.ts | 2 ++ src/harness/fourslash.ts | 2 +- src/services/codefixes/helpers.ts | 13 +++++++------ src/services/textChanges.ts | 4 ++-- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index c110ea4227..297d2cc0dd 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -326,10 +326,12 @@ namespace ts { case SyntaxKind.TypeOperator: return updateTypeOperatorNode(node, visitNode((node).type, visitor, isTypeNode)); + case SyntaxKind.IndexedAccessType: return updateIndexedAccessTypeNode((node), visitNode((node).objectType, visitor, isTypeNode), visitNode((node).indexType, visitor, isTypeNode)); + case SyntaxKind.MappedType: return updateMappedTypeNode((node), visitNode((node).readonlyToken, tokenVisitor, isToken), diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 4ef6b54e1b..98ebacd49b 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1676,7 +1676,7 @@ namespace FourSlash { // 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. Assumption is that these edit ranges don't overlap let runningOffset = 0; - edits = ts.stableSort(edits, (a, b) => a.span.start - b.span.start); + edits = edits.sort((a, b) => a.span.start - b.span.start); // 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); diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index a7809cdd21..b836815fc2 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -11,7 +11,7 @@ namespace ts.codefix { } const changes = changeTracker.getChanges(); - if (!(changes && changes.length > 0)) { + if (!some(changes)) { return changes; } @@ -93,7 +93,7 @@ namespace ts.codefix { // (eg: an abstract method or interface declaration), there is a 1-1 // correspondence of declarations and signatures. const signatures = checker.getSignaturesOfType(type, SignatureKind.Call); - if (!(signatures && signatures.length > 0)) { + if (!some(signatures)) { return undefined; } @@ -103,7 +103,7 @@ namespace ts.codefix { return signatureToMethodDeclaration(signature, enclosingDeclaration, createStubbedMethodBody()); } - const signatureDeclarations = []; + const signatureDeclarations: MethodDeclaration[] = []; for (let i = 0; i < signatures.length; i++) { const signature = signatures[i]; const methodDeclaration = signatureToMethodDeclaration(signature, enclosingDeclaration); @@ -132,6 +132,7 @@ namespace ts.codefix { function signatureToMethodDeclaration(signature: Signature, enclosingDeclaration: Node, body?: Block) { const signatureDeclaration = checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration); if (signatureDeclaration) { + signatureDeclaration.decorators = undefined; signatureDeclaration.modifiers = modifiers; signatureDeclaration.name = name; signatureDeclaration.questionToken = optional ? createToken(SyntaxKind.QuestionToken) : undefined; @@ -142,8 +143,6 @@ namespace ts.codefix { } function createMethodImplementingSignatures(signatures: Signature[], name: PropertyName, optional: boolean, modifiers: Modifier[] | undefined): MethodDeclaration { - Debug.assert(signatures && signatures.length > 0); - /** This is *a* signature with the maximal number of arguments, * such that if there is a "maximal" signature without rest arguments, * this is one of them. @@ -154,7 +153,9 @@ namespace ts.codefix { for (let i = 0; i < signatures.length; i++) { const sig = signatures[i]; minArgumentCount = Math.min(sig.minArgumentCount, minArgumentCount); - someSigHasRestParameter = someSigHasRestParameter || sig.hasRestParameter; + if (sig.hasRestParameter) { + someSigHasRestParameter = true; + } if (sig.parameters.length >= maxArgsSignature.parameters.length && (!sig.hasRestParameter || maxArgsSignature.hasRestParameter)) { maxArgsSignature = sig; } diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 73d5fc61bc..afc9892749 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -276,7 +276,7 @@ namespace ts.textChanges { /** * This function should be used to insert nodes in lists when nodes don't carry separators as the part of the node range, * i.e. arguments in arguments lists, parameters in parameter lists etc. - * Note that separators are art of the node in statements and class elements. + * Note that separators are part of the node in statements and class elements. */ public insertNodeInListAfter(sourceFile: SourceFile, after: Node, newNode: Node) { const containingList = formatting.SmartIndenter.getContainingList(after, sourceFile); @@ -484,7 +484,7 @@ namespace ts.textChanges { private static normalize(changes: Change[]) { // order changes by start position const normalized = stableSort(changes, (a, b) => a.range.pos - b.range.pos); - // verify that change intervals to not overlap, except possible at end points. + // verify that change intervals do not overlap, except possibly at end points. for (let i = 0; i < normalized.length - 2; i++) { Debug.assert(normalized[i].range.end <= normalized[i + 1].range.pos); } From e630ab1a3181b6b5d6a25069d15cbcb77bc3eb1b Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 27 Mar 2017 14:20:00 -0700 Subject: [PATCH 162/164] Report semantic errors for JS files if checkJs is enabled --- src/server/session.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/server/session.ts b/src/server/session.ts index 11c99dfe46..337aab1c3f 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -31,7 +31,8 @@ namespace ts.server { } else { // For configured projects, require that skipLibCheck be set also - return project.getCompilerOptions().skipLibCheck && project.isJsOnlyProject(); + const options = project.getCompilerOptions(); + return options.skipLibCheck && !options.checkJs && project.isJsOnlyProject(); } } From dd06cbb3156aa6499756cf4da75e3492ae4b2e0a Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Mon, 27 Mar 2017 14:32:45 -0700 Subject: [PATCH 163/164] getSpecialPropertyAssignmentKind: Always check for BinaryExpression *outside*, always check for JS file *inside* --- src/compiler/binder.ts | 48 +++++++++++++++++++-------------------- src/compiler/checker.ts | 6 ++--- src/compiler/utilities.ts | 5 +--- 3 files changed, 27 insertions(+), 32 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 650797c6db..45e8efdf51 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -259,7 +259,7 @@ namespace ts { case SyntaxKind.ExportAssignment: return (node).isExportEquals ? "export=" : "default"; case SyntaxKind.BinaryExpression: - switch (getSpecialPropertyAssignmentKind(node)) { + switch (getSpecialPropertyAssignmentKind(node as BinaryExpression)) { case SpecialPropertyAssignmentKind.ModuleExports: // module.exports = ... return "export="; @@ -2017,30 +2017,28 @@ namespace ts { } break; case SyntaxKind.BinaryExpression: - if (isInJavaScriptFile(node)) { - const specialKind = getSpecialPropertyAssignmentKind(node); - switch (specialKind) { - case SpecialPropertyAssignmentKind.ExportsProperty: - bindExportsPropertyAssignment(node); - break; - case SpecialPropertyAssignmentKind.ModuleExports: - bindModuleExportsAssignment(node); - break; - case SpecialPropertyAssignmentKind.PrototypeProperty: - bindPrototypePropertyAssignment(node); - break; - case SpecialPropertyAssignmentKind.ThisProperty: - bindThisPropertyAssignment(node); - break; - case SpecialPropertyAssignmentKind.Property: - bindStaticPropertyAssignment(node); - break; - case SpecialPropertyAssignmentKind.None: - // Nothing to do - break; - default: - Debug.fail("Unknown special property assignment kind"); - } + const specialKind = getSpecialPropertyAssignmentKind(node as BinaryExpression); + switch (specialKind) { + case SpecialPropertyAssignmentKind.ExportsProperty: + bindExportsPropertyAssignment(node); + break; + case SpecialPropertyAssignmentKind.ModuleExports: + bindModuleExportsAssignment(node); + break; + case SpecialPropertyAssignmentKind.PrototypeProperty: + bindPrototypePropertyAssignment(node); + break; + case SpecialPropertyAssignmentKind.ThisProperty: + bindThisPropertyAssignment(node); + break; + case SpecialPropertyAssignmentKind.Property: + bindStaticPropertyAssignment(node); + break; + case SpecialPropertyAssignmentKind.None: + // Nothing to do + break; + default: + Debug.fail("Unknown special property assignment kind"); } return checkStrictModeBinaryExpression(node); case SyntaxKind.CatchClause: diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4e55a1c46b..408739f480 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11929,8 +11929,8 @@ namespace ts { // If this is a function in a JS file, it might be a class method. Check if it's the RHS // of a x.prototype.y = function [name]() { .... } if (container.kind === SyntaxKind.FunctionExpression && - isInJavaScriptFile(container.parent) && - getSpecialPropertyAssignmentKind(container.parent) === SpecialPropertyAssignmentKind.PrototypeProperty) { + container.parent.kind === SyntaxKind.BinaryExpression && + getSpecialPropertyAssignmentKind(container.parent as BinaryExpression) === SpecialPropertyAssignmentKind.PrototypeProperty) { // Get the 'x' of 'x.prototype.y = f' (here, 'f' is 'container') const className = (((container.parent as BinaryExpression) // x.prototype.y = f .left as PropertyAccessExpression) // x.prototype.y @@ -21641,7 +21641,7 @@ namespace ts { } function getSpecialPropertyAssignmentSymbolFromEntityName(entityName: EntityName | PropertyAccessExpression) { - const specialPropertyAssignmentKind = getSpecialPropertyAssignmentKind(entityName.parent.parent); + const specialPropertyAssignmentKind = getSpecialPropertyAssignmentKind(entityName.parent.parent as BinaryExpression); switch (specialPropertyAssignmentKind) { case SpecialPropertyAssignmentKind.ExportsProperty: case SpecialPropertyAssignmentKind.PrototypeProperty: diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 33cb0d8f48..f091685598 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1450,13 +1450,10 @@ namespace ts { /// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property /// assignments we treat as special in the binder - export function getSpecialPropertyAssignmentKind(expression: Node): SpecialPropertyAssignmentKind { + export function getSpecialPropertyAssignmentKind(expression: ts.BinaryExpression): SpecialPropertyAssignmentKind { if (!isInJavaScriptFile(expression)) { return SpecialPropertyAssignmentKind.None; } - if (expression.kind !== SyntaxKind.BinaryExpression) { - return SpecialPropertyAssignmentKind.None; - } const expr = expression; if (expr.operatorToken.kind !== SyntaxKind.EqualsToken || expr.left.kind !== SyntaxKind.PropertyAccessExpression) { return SpecialPropertyAssignmentKind.None; From cac60457b18f880c850c1a8d585016e52dcc6ee0 Mon Sep 17 00:00:00 2001 From: ncoley Date: Tue, 28 Mar 2017 21:53:14 -0400 Subject: [PATCH 164/164] Update FormData methods with appropriate types --- src/lib/dom.iterable.d.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/dom.iterable.d.ts b/src/lib/dom.iterable.d.ts index ea0d43d364..c79e007996 100644 --- a/src/lib/dom.iterable.d.ts +++ b/src/lib/dom.iterable.d.ts @@ -8,7 +8,7 @@ interface FormData { /** * Returns an array of key, value pairs for every entry in the list */ - entries(): IterableIterator<[string, any]>; + entries(): IterableIterator<[string, string | File]>; /** * Returns a list of keys in the list */ @@ -16,9 +16,9 @@ interface FormData { /** * Returns a list of values in the list */ - values(): IterableIterator; + values(): IterableIterator; - [Symbol.iterator](): IterableIterator; + [Symbol.iterator](): IterableIterator; } interface NodeList {