diff --git a/Jakefile.js b/Jakefile.js index 8ba49afadfc..5b8cffac240 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -245,7 +245,7 @@ var librarySourceMap = [ { target: "lib.es2015.d.ts", sources: ["header.d.ts", "es2015.d.ts"] }, { target: "lib.es2016.d.ts", sources: ["header.d.ts", "es2016.d.ts"] }, { target: "lib.es2017.d.ts", sources: ["header.d.ts", "es2017.d.ts"] }, - + // JavaScript + all host library { target: "lib.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(hostsLibrarySources) }, { target: "lib.es6.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") } @@ -722,24 +722,32 @@ function cleanTestDirs() { } // used to pass data from jake command line directly to run.js -function writeTestConfigFile(testConfigFile, tests, light, stackTraceLimit) { +function writeTestConfigFile(tests, light, taskConfigFolder, workerCount, stackTraceLimit) { var testConfig; if (tests) { - console.log('Running test(s): ' + tests); - (testConfig || (testConfig = {})).tests = [tests]; + (testConfig || (testConfig = {})).test = [tests]; } if (light) { (testConfig || (testConfig = {})).light = light; } + if (workerCount) { + (testConfig || (testConfig = {})).workerCount = workerCount; + } + + if (taskConfigFolder) { + (testConfig || (testConfig = {})).taskConfigFolder = taskConfigFolder; + } + if (/^(\d+|full)$/.test(stackTraceLimit)) { (testConfig || (testConfig = {})).stackTraceLimit = stackTraceLimit; } if (testConfig) { var testConfigContents = JSON.stringify(testConfig); - fs.writeFileSync(testConfigFile, testConfigContents); + console.log('Running tests with config: ' + testConfigContents); + fs.writeFileSync('test.config', testConfigContents); } } @@ -874,7 +882,7 @@ function runTestsAndWriteOutput(file) { }); } -function runConsoleTests(defaultReporter, defaultSubsets, dirty) { +function runConsoleTests(defaultReporter, runInParallel, dirty) { if (!dirty) { cleanTestDirs(); } @@ -887,9 +895,22 @@ function runConsoleTests(defaultReporter, defaultSubsets, dirty) { if (fs.existsSync(testConfigFile)) { fs.unlinkSync(testConfigFile); } + var workerCount, taskConfigsFolder; + if (runInParallel) { + // generate name to store task configuration files + var prefix = os.tmpdir() + "/ts-tests"; + var i = 1; + do { + taskConfigsFolder = prefix + i; + i++; + } while (fs.existsSync(taskConfigsFolder)); + fs.mkdirSync(taskConfigsFolder); - if (tests || light) { - writeTestConfigFile(testConfigFile, tests, light, stackTraceLimit); + workerCount = process.env.workerCount || os.cpus().length; + } + + if (tests || light || taskConfigsFolder) { + writeTestConfigFile(tests, light, taskConfigsFolder, workerCount, stackTraceLimit); } if (tests && tests.toLocaleLowerCase() === "rwc") { @@ -903,63 +924,93 @@ function runConsoleTests(defaultReporter, defaultSubsets, dirty) { // timeout normally isn't necessary but Travis-CI has been timing out on compiler baselines occasionally // default timeout is 2sec which really should be enough, but maybe we just need a small amount longer - var subsetRegexes; - if(defaultSubsets.length === 0) { - subsetRegexes = [tests]; - } - else { - var subsets = tests ? tests.split("|") : defaultSubsets; - subsetRegexes = subsets.map(function (sub) { return "^" + sub + ".*$"; }); - subsetRegexes.push("^(?!" + subsets.join("|") + ").*$"); - } - var counter = subsetRegexes.length; - var errorStatus; - subsetRegexes.forEach(function (subsetRegex, i) { - tests = subsetRegex ? ' -g "' + subsetRegex + '"' : ''; + if(!runInParallel) { + tests = tests ? ' -g "' + tests + '"' : ''; var cmd = "mocha" + (debug ? " --debug-brk" : "") + " -R " + reporter + tests + colors + ' -t ' + testTimeout + ' ' + run; console.log(cmd); - function finish(status) { - counter--; - // save first error status - if (status !== undefined && errorStatus === undefined) { - errorStatus = status; - } - - deleteTemporaryProjectOutput(); - if (counter !== 0 || errorStatus === undefined) { - // run linter when last worker is finished - if (lintFlag && counter === 0 && !dirty) { - var lint = jake.Task['lint']; - lint.addListener('complete', function () { - complete(); - }); - lint.invoke(); - } - else { - complete(); - } - } - else { - fail("Process exited with code " + status); - } - } exec(cmd, function () { + runLinter(); finish(); }, function(e, status) { finish(status); }); - }); + + } + else { + // run task to load all tests and partition them between workers + var cmd = "mocha " + " -R min " + colors + run; + console.log(cmd); + exec(cmd, function() { + // read all configuration files and spawn a worker for every config + var configFiles = fs.readdirSync(taskConfigsFolder); + var counter = configFiles.length; + var firstErrorStatus; + // schedule work for chunks + configFiles.forEach(function (f) { + var configPath = path.join(taskConfigsFolder, f); + var workerCmd = "mocha" + " -t " + testTimeout + " -R " + reporter + " " + colors + " " + run + " --config='" + configPath + "'"; + console.log(workerCmd); + exec(workerCmd, finishWorker, finishWorker) + }); + + function finishWorker(e, errorStatus) { + counter--; + if (firstErrorStatus === undefined && errorStatus !== undefined) { + firstErrorStatus = errorStatus; + } + if (counter !== 0) { + complete(); + } + else { + // last worker clean everything and runs linter in case if there were no errors + deleteTemporaryProjectOutput(); + jake.rmRf(taskConfigsFolder); + if (firstErrorStatus === undefined) { + runLinter(); + complete(); + } + else { + failWithStatus(firstErrorStatus); + } + } + } + }); + } + + function failWithStatus(status) { + fail("Process exited with code " + status); + } + + function finish(errorStatus) { + deleteTemporaryProjectOutput(); + if (errorStatus !== undefined) { + failWithStatus(errorStatus); + } + else { + complete(); + } + } + function runLinter() { + if (!lintFlag || dirty) { + return; + } + var lint = jake.Task['lint']; + lint.addListener('complete', function () { + complete(); + }); + lint.invoke(); + } } var testTimeout = 20000; desc("Runs all the tests in parallel using the built run.js file. Optional arguments are: t[ests]=category1|category2|... d[ebug]=true."); task("runtests-parallel", ["build-rules", "tests", builtLocalDirectory], function() { - runConsoleTests('min', ['compiler', 'conformance', 'Projects', 'fourslash']); + runConsoleTests('min', /*runInParallel*/ true); }, {async: true}); desc("Runs the tests using the built run.js file. Optional arguments are: t[ests]=regex r[eporter]=[list|spec|json|] d[ebug]=true color[s]=false lint=true."); task("runtests", ["build-rules", "tests", builtLocalDirectory], function() { - runConsoleTests('mocha-fivemat-progress-reporter', []); + runConsoleTests('mocha-fivemat-progress-reporter', /*runInParallel*/ false); }, {async: true}); task("runtests-file", ["build-rules", "tests", builtLocalDirectory], function () { @@ -1000,7 +1051,7 @@ task("runtests-browser", ["tests", "browserify", builtLocalDirectory, servicesFi fs.unlinkSync(testConfigFile); } if(tests || light) { - writeTestConfigFile(testConfigFile, tests, light); + writeTestConfigFile(tests, light); } tests = tests ? tests : ''; diff --git a/lib/lib.d.ts b/lib/lib.d.ts index 6bded7a1135..15745c5d533 100644 --- a/lib/lib.d.ts +++ b/lib/lib.d.ts @@ -965,38 +965,22 @@ interface JSON { * If a member contains nested objects, the nested objects are transformed before the parent object is. */ parse(text: string, reviver?: (key: any, value: any) => any): any; - /** - * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. - * @param value A JavaScript value, usually an object or array, to be converted. - */ - stringify(value: any): string; - /** - * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. - * @param value A JavaScript value, usually an object or array, to be converted. - * @param replacer A function that transforms the results. - */ - stringify(value: any, replacer: (key: string, value: any) => any): string; - /** - * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. - * @param value A JavaScript value, usually an object or array, to be converted. - * @param replacer Array that transforms the results. - */ - stringify(value: any, replacer: any[]): string; /** * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. * @param value A JavaScript value, usually an object or array, to be converted. * @param replacer A function that transforms the results. * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. */ - stringify(value: any, replacer: (key: string, value: any) => any, space: string | number): string; + stringify(value: any, replacer?: (key: string, value: any) => any, space?: string | number): string; /** * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. * @param value A JavaScript value, usually an object or array, to be converted. - * @param replacer Array that transforms the results. + * @param replacer An array of strings and numbers that acts as a white list for selecting the object properties that will be stringified. * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. */ - stringify(value: any, replacer: any[], space: string | number): string; + stringify(value: any, replacer?: (number | string)[] | null, space?: string | number): string; } + /** * An intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format. */ diff --git a/lib/lib.es5.d.ts b/lib/lib.es5.d.ts index 3a0f73f3cc7..e4e0334e0cb 100644 --- a/lib/lib.es5.d.ts +++ b/lib/lib.es5.d.ts @@ -965,38 +965,22 @@ interface JSON { * If a member contains nested objects, the nested objects are transformed before the parent object is. */ parse(text: string, reviver?: (key: any, value: any) => any): any; - /** - * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. - * @param value A JavaScript value, usually an object or array, to be converted. - */ - stringify(value: any): string; - /** - * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. - * @param value A JavaScript value, usually an object or array, to be converted. - * @param replacer A function that transforms the results. - */ - stringify(value: any, replacer: (key: string, value: any) => any): string; - /** - * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. - * @param value A JavaScript value, usually an object or array, to be converted. - * @param replacer Array that transforms the results. - */ - stringify(value: any, replacer: any[]): string; /** * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. * @param value A JavaScript value, usually an object or array, to be converted. * @param replacer A function that transforms the results. * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. */ - stringify(value: any, replacer: (key: string, value: any) => any, space: string | number): string; + stringify(value: any, replacer?: (key: string, value: any) => any, space?: string | number): string; /** * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. * @param value A JavaScript value, usually an object or array, to be converted. - * @param replacer Array that transforms the results. + * @param replacer An array of strings and numbers that acts as a white list for selecting the object properties that will be stringified. * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. */ - stringify(value: any, replacer: any[], space: string | number): string; + stringify(value: any, replacer?: (number | string)[] | null, space?: string | number): string; } + /** * An intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format. */ diff --git a/lib/lib.es6.d.ts b/lib/lib.es6.d.ts index 6ed743d739a..ae54e8e8570 100644 --- a/lib/lib.es6.d.ts +++ b/lib/lib.es6.d.ts @@ -965,38 +965,22 @@ interface JSON { * If a member contains nested objects, the nested objects are transformed before the parent object is. */ parse(text: string, reviver?: (key: any, value: any) => any): any; - /** - * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. - * @param value A JavaScript value, usually an object or array, to be converted. - */ - stringify(value: any): string; - /** - * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. - * @param value A JavaScript value, usually an object or array, to be converted. - * @param replacer A function that transforms the results. - */ - stringify(value: any, replacer: (key: string, value: any) => any): string; - /** - * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. - * @param value A JavaScript value, usually an object or array, to be converted. - * @param replacer Array that transforms the results. - */ - stringify(value: any, replacer: any[]): string; /** * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. * @param value A JavaScript value, usually an object or array, to be converted. * @param replacer A function that transforms the results. * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. */ - stringify(value: any, replacer: (key: string, value: any) => any, space: string | number): string; + stringify(value: any, replacer?: (key: string, value: any) => any, space?: string | number): string; /** * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. * @param value A JavaScript value, usually an object or array, to be converted. - * @param replacer Array that transforms the results. + * @param replacer An array of strings and numbers that acts as a white list for selecting the object properties that will be stringified. * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. */ - stringify(value: any, replacer: any[], space: string | number): string; + stringify(value: any, replacer?: (number | string)[] | null, space?: string | number): string; } + /** * An intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format. */ diff --git a/lib/tsc.js b/lib/tsc.js index 8dba7a921dc..ca303c49f7b 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -913,6 +913,10 @@ var ts; } return result.sort(); } + function getDirectories(path) { + var folder = fso.GetFolder(path); + return getNames(folder.subfolders); + } function readDirectory(path, extension, exclude) { var result = []; exclude = ts.map(exclude, function (s) { return getCanonicalPath(ts.combinePaths(path, s)); }); @@ -967,6 +971,7 @@ var ts; getCurrentDirectory: function () { return new ActiveXObject("WScript.Shell").CurrentDirectory; }, + getDirectories: getDirectories, readDirectory: readDirectory, exit: function (exitCode) { try { @@ -1114,6 +1119,9 @@ var ts; function directoryExists(path) { return fileSystemEntryExists(path, 1); } + function getDirectories(path) { + return ts.filter(_fs.readdirSync(path), function (p) { return fileSystemEntryExists(ts.combinePaths(path, p), 1); }); + } function readDirectory(path, extension, exclude) { var result = []; exclude = ts.map(exclude, function (s) { return getCanonicalPath(ts.combinePaths(path, s)); }); @@ -1206,6 +1214,7 @@ var ts; getCurrentDirectory: function () { return process.cwd(); }, + getDirectories: getDirectories, readDirectory: readDirectory, getModifiedTime: function (path) { try { @@ -1256,6 +1265,7 @@ var ts; createDirectory: ChakraHost.createDirectory, getExecutingFilePath: function () { return ChakraHost.executingFile; }, getCurrentDirectory: function () { return ChakraHost.currentDirectory; }, + getDirectories: ChakraHost.getDirectories, readDirectory: ChakraHost.readDirectory, exit: ChakraHost.quit, realpath: realpath @@ -1389,7 +1399,7 @@ var ts; or_expected: { code: 1144, category: ts.DiagnosticCategory.Error, key: "or_expected_1144", message: "'{' or ';' expected." }, Declaration_expected: { code: 1146, category: ts.DiagnosticCategory.Error, key: "Declaration_expected_1146", message: "Declaration expected." }, Import_declarations_in_a_namespace_cannot_reference_a_module: { code: 1147, category: ts.DiagnosticCategory.Error, key: "Import_declarations_in_a_namespace_cannot_reference_a_module_1147", message: "Import declarations in a namespace cannot reference a module." }, - Cannot_compile_modules_unless_the_module_flag_is_provided_with_a_valid_module_type_Consider_setting_the_module_compiler_option_in_a_tsconfig_json_file: { code: 1148, category: ts.DiagnosticCategory.Error, key: "Cannot_compile_modules_unless_the_module_flag_is_provided_with_a_valid_module_type_Consider_setting__1148", message: "Cannot compile modules unless the '--module' flag is provided with a valid module type. Consider setting the 'module' compiler option in a 'tsconfig.json' file." }, + Cannot_use_imports_exports_or_module_augmentations_when_module_is_none: { code: 1148, category: ts.DiagnosticCategory.Error, key: "Cannot_use_imports_exports_or_module_augmentations_when_module_is_none_1148", message: "Cannot use imports, exports, or module augmentations when '--module' is 'none'." }, File_name_0_differs_from_already_included_file_name_1_only_in_casing: { code: 1149, category: ts.DiagnosticCategory.Error, key: "File_name_0_differs_from_already_included_file_name_1_only_in_casing_1149", message: "File name '{0}' differs from already included file name '{1}' only in casing" }, new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead: { code: 1150, category: ts.DiagnosticCategory.Error, key: "new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead_1150", message: "'new T[]' cannot be used to create an array. Use 'new Array()' instead." }, const_declarations_must_be_initialized: { code: 1155, category: ts.DiagnosticCategory.Error, key: "const_declarations_must_be_initialized_1155", message: "'const' declarations must be initialized" }, @@ -1759,6 +1769,8 @@ var ts; this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation: { code: 2683, category: ts.DiagnosticCategory.Error, key: "this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_2683", message: "'this' implicitly has type 'any' because it does not have a type annotation." }, The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1: { code: 2684, category: ts.DiagnosticCategory.Error, key: "The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1_2684", message: "The 'this' context of type '{0}' is not assignable to method's 'this' of type '{1}'." }, The_this_types_of_each_signature_are_incompatible: { code: 2685, category: ts.DiagnosticCategory.Error, key: "The_this_types_of_each_signature_are_incompatible_2685", message: "The 'this' types of each signature are incompatible." }, + Identifier_0_must_be_imported_from_a_module: { code: 2686, category: ts.DiagnosticCategory.Error, key: "Identifier_0_must_be_imported_from_a_module_2686", message: "Identifier '{0}' must be imported from a module" }, + All_declarations_of_0_must_have_identical_modifiers: { code: 2687, category: ts.DiagnosticCategory.Error, key: "All_declarations_of_0_must_have_identical_modifiers_2687", message: "All declarations of '{0}' must have identical modifiers." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: ts.DiagnosticCategory.Error, key: "Import_declaration_0_is_using_private_name_1_4000", message: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: ts.DiagnosticCategory.Error, key: "Type_parameter_0_of_exported_class_has_or_is_using_private_name_1_4002", message: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: ts.DiagnosticCategory.Error, key: "Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1_4004", message: "Type parameter '{0}' of exported interface has or is using private name '{1}'." }, @@ -1852,7 +1864,7 @@ var ts; Option_paths_cannot_be_used_without_specifying_baseUrl_option: { code: 5060, category: ts.DiagnosticCategory.Error, key: "Option_paths_cannot_be_used_without_specifying_baseUrl_option_5060", message: "Option 'paths' cannot be used without specifying '--baseUrl' option." }, Pattern_0_can_have_at_most_one_Asterisk_character: { code: 5061, category: ts.DiagnosticCategory.Error, key: "Pattern_0_can_have_at_most_one_Asterisk_character_5061", message: "Pattern '{0}' can have at most one '*' character" }, Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character: { code: 5062, category: ts.DiagnosticCategory.Error, key: "Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character_5062", message: "Substitution '{0}' in pattern '{1}' in can have at most one '*' character" }, - Substututions_for_pattern_0_should_be_an_array: { code: 5063, category: ts.DiagnosticCategory.Error, key: "Substututions_for_pattern_0_should_be_an_array_5063", message: "Substututions for pattern '{0}' should be an array." }, + Substitutions_for_pattern_0_should_be_an_array: { code: 5063, category: ts.DiagnosticCategory.Error, key: "Substitutions_for_pattern_0_should_be_an_array_5063", message: "Substitutions for pattern '{0}' should be an array." }, Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2: { code: 5064, category: ts.DiagnosticCategory.Error, key: "Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2_5064", message: "Substitution '{0}' for pattern '{1}' has incorrect type, expected 'string', got '{2}'." }, Concatenate_and_emit_output_to_single_file: { code: 6001, category: ts.DiagnosticCategory.Message, key: "Concatenate_and_emit_output_to_single_file_6001", message: "Concatenate and emit output to single file." }, Generates_corresponding_d_ts_file: { code: 6002, category: ts.DiagnosticCategory.Message, key: "Generates_corresponding_d_ts_file_6002", message: "Generates corresponding '.d.ts' file." }, @@ -1865,6 +1877,7 @@ var ts; Do_not_emit_comments_to_output: { code: 6009, category: ts.DiagnosticCategory.Message, key: "Do_not_emit_comments_to_output_6009", message: "Do not emit comments to output." }, Do_not_emit_outputs: { code: 6010, category: ts.DiagnosticCategory.Message, key: "Do_not_emit_outputs_6010", message: "Do not emit outputs." }, Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking: { code: 6011, category: ts.DiagnosticCategory.Message, key: "Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011", message: "Allow default imports from modules with no default export. This does not affect code emit, just typechecking." }, + Skip_type_checking_of_declaration_files: { code: 6012, category: ts.DiagnosticCategory.Message, key: "Skip_type_checking_of_declaration_files_6012", message: "Skip type checking of declaration files." }, Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015: { code: 6015, category: ts.DiagnosticCategory.Message, key: "Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015_6015", message: "Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES2015'" }, Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015: { code: 6016, category: ts.DiagnosticCategory.Message, key: "Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015_6016", message: "Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'" }, Print_this_message: { code: 6017, category: ts.DiagnosticCategory.Message, key: "Print_this_message_6017", message: "Print this message." }, @@ -1966,6 +1979,7 @@ var ts; Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set: { code: 6128, category: ts.DiagnosticCategory.Message, key: "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set_6128", message: "======== Resolving type reference directive '{0}', containing file not set, root directory not set. ========" }, The_config_file_0_found_doesn_t_contain_any_source_files: { code: 6129, category: ts.DiagnosticCategory.Error, key: "The_config_file_0_found_doesn_t_contain_any_source_files_6129", message: "The config file '{0}' found doesn't contain any source files." }, Resolving_real_path_for_0_result_1: { code: 6130, category: ts.DiagnosticCategory.Message, key: "Resolving_real_path_for_0_result_1_6130", message: "Resolving real path for '{0}', result '{1}'" }, + Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system: { code: 6131, category: ts.DiagnosticCategory.Error, key: "Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system_6131", message: "Cannot compile modules using option '{0}' unless the '--module' flag is 'amd' or 'system'." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable_0_implicitly_has_an_1_type_7005", message: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter_0_implicitly_has_an_1_type_7006", message: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member_0_implicitly_has_an_1_type_7008", message: "Member '{0}' implicitly has an '{1}' type." }, @@ -5004,7 +5018,7 @@ var ts; } ts.isWellKnownSymbolSyntactically = isWellKnownSymbolSyntactically; function getPropertyNameForPropertyNameNode(name) { - if (name.kind === 69 || name.kind === 9 || name.kind === 8) { + if (name.kind === 69 || name.kind === 9 || name.kind === 8 || name.kind === 142) { return name.text; } if (name.kind === 140) { @@ -12050,10 +12064,10 @@ var ts; case 145: case 144: case 266: - return bindPropertyOrMethodOrAccessor(node, 4 | (node.questionToken ? 536870912 : 0), 107455); + return bindPropertyOrMethodOrAccessor(node, 4 | (node.questionToken ? 536870912 : 0), 0); case 253: case 254: - return bindPropertyOrMethodOrAccessor(node, 4, 107455); + return bindPropertyOrMethodOrAccessor(node, 4, 0); case 255: return bindPropertyOrMethodOrAccessor(node, 8, 107455); case 247: @@ -12065,7 +12079,7 @@ var ts; return declareSymbolAndAddToSymbolTable(node, 131072, 0); case 147: case 146: - return bindPropertyOrMethodOrAccessor(node, 8192 | (node.questionToken ? 536870912 : 0), ts.isObjectLiteralMethod(node) ? 107455 : 99263); + return bindPropertyOrMethodOrAccessor(node, 8192 | (node.questionToken ? 536870912 : 0), ts.isObjectLiteralMethod(node) ? 0 : 99263); case 220: return bindFunctionDeclaration(node); case 148: @@ -12108,7 +12122,7 @@ var ts; case 238: return declareSymbolAndAddToSymbolTable(node, 8388608, 8388608); case 228: - return bindGlobalModuleExportDeclaration(node); + return bindNamespaceExportDeclaration(node); case 231: return bindImportClause(node); case 236: @@ -12144,13 +12158,13 @@ var ts; bindAnonymousDeclaration(node, 8388608, getDeclarationName(node)); } else if (boundExpression.kind === 69 && node.kind === 235) { - declareSymbol(container.symbol.exports, container.symbol, node, 8388608, 107455 | 8388608); + declareSymbol(container.symbol.exports, container.symbol, node, 8388608, 0 | 8388608); } else { - declareSymbol(container.symbol.exports, container.symbol, node, 4, 107455 | 8388608); + declareSymbol(container.symbol.exports, container.symbol, node, 4, 0 | 8388608); } } - function bindGlobalModuleExportDeclaration(node) { + function bindNamespaceExportDeclaration(node) { if (node.modifiers && node.modifiers.length) { file.bindDiagnostics.push(ts.createDiagnosticForNode(node, ts.Diagnostics.Modifiers_cannot_appear_here)); } @@ -12202,7 +12216,7 @@ var ts; function bindThisPropertyAssignment(node) { if (container.kind === 179 || container.kind === 220) { container.symbol.members = container.symbol.members || {}; - declareSymbol(container.symbol.members, container.symbol, node, 4, 107455 & ~4); + declareSymbol(container.symbol.members, container.symbol, node, 4, 0 & ~4); } } function bindPrototypePropertyAssignment(node) { @@ -12219,7 +12233,7 @@ var ts; if (!funcSymbol.members) { funcSymbol.members = {}; } - declareSymbol(funcSymbol.members, funcSymbol, leftSideOfAssignment, 4, 107455); + declareSymbol(funcSymbol.members, funcSymbol, leftSideOfAssignment, 4, 0); } function bindCallExpression(node) { if (!file.commonJsModuleIndicator && ts.isRequireCall(node, false)) { @@ -12295,7 +12309,7 @@ var ts; } if (ts.isParameterPropertyDeclaration(node)) { var classDeclaration = node.parent.parent; - declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4, 107455); + declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4, 0); } } function bindFunctionDeclaration(node) { @@ -12595,7 +12609,7 @@ var ts; if (flags & 1) result |= 107454; if (flags & 4) - result |= 107455; + result |= 0; if (flags & 8) result |= 107455; if (flags & 16) @@ -12851,6 +12865,7 @@ var ts; var propertyWithInvalidInitializer; var errorLocation = location; var grandparent; + var isInExternalModule = false; loop: while (location) { if (location.locals && !isGlobalSourceFile(location)) { if (result = getSymbol(location.locals, name, meaning)) { @@ -12882,6 +12897,7 @@ var ts; case 256: if (!ts.isExternalOrCommonJsModule(location)) break; + isInExternalModule = true; case 225: var moduleExports = getSymbolOfNode(location).exports; if (location.kind === 256 || ts.isAmbientModule(location)) { @@ -13005,6 +13021,12 @@ var ts; checkResolvedBlockScopedVariable(exportOrLocalSymbol, errorLocation); } } + if (result && isInExternalModule) { + var decls = result.declarations; + if (decls && decls.length === 1 && decls[0].kind === 228) { + error(errorLocation, ts.Diagnostics.Identifier_0_must_be_imported_from_a_module, name); + } + } } return result; } @@ -14480,7 +14502,7 @@ var ts; } function getTypeForBindingElementParent(node) { var symbol = getSymbolOfNode(node); - return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node); + return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node, false); } function getTextOfPropertyName(name) { switch (name.kind) { @@ -14585,7 +14607,7 @@ var ts; function addOptionality(type, optional) { return strictNullChecks && optional ? addNullableKind(type, 32) : type; } - function getTypeForVariableLikeDeclaration(declaration) { + function getTypeForVariableLikeDeclaration(declaration, includeOptionality) { if (declaration.flags & 134217728) { var type = getTypeForVariableLikeDeclarationFromJSDocComment(declaration); if (type && type !== unknownType) { @@ -14602,7 +14624,7 @@ var ts; return getTypeForBindingElement(declaration); } if (declaration.type) { - return addOptionality(getTypeFromTypeNode(declaration.type), !!declaration.questionToken); + return addOptionality(getTypeFromTypeNode(declaration.type), declaration.questionToken && includeOptionality); } if (declaration.kind === 142) { var func = declaration.parent; @@ -14621,11 +14643,11 @@ var ts; ? getContextuallyTypedThisType(func) : getContextuallyTypedParameterType(declaration); if (type) { - return addOptionality(type, !!declaration.questionToken); + return addOptionality(type, declaration.questionToken && includeOptionality); } } if (declaration.initializer) { - return addOptionality(checkExpressionCached(declaration.initializer), !!declaration.questionToken); + return addOptionality(checkExpressionCached(declaration.initializer), declaration.questionToken && includeOptionality); } if (declaration.kind === 254) { return checkIdentifier(declaration.name); @@ -14693,7 +14715,7 @@ var ts; : getTypeFromArrayBindingPattern(pattern, includePatternInType); } function getWidenedTypeForVariableLikeDeclaration(declaration, reportErrors) { - var type = getTypeForVariableLikeDeclaration(declaration); + var type = getTypeForVariableLikeDeclaration(declaration, true); if (type) { if (reportErrors) { reportErrorsFromWidening(declaration, type); @@ -17010,7 +17032,7 @@ var ts; return isIdenticalTo(source, target); } if (!(target.flags & 134217728)) { - if (target.flags & 1) + if (target.flags & 1 || source.flags & 134217728) return -1; if (source.flags & 32) { if (!strictNullChecks || target.flags & (32 | 16) || source === emptyArrayElementType) @@ -17030,7 +17052,7 @@ var ts; if (source.flags & 256 && target === stringType) return -1; if (relation === assignableRelation || relation === comparableRelation) { - if (source.flags & (1 | 134217728)) + if (source.flags & 1) return -1; if (source === numberType && target.flags & 128) return -1; @@ -17807,41 +17829,47 @@ var ts; getSignaturesOfType(type, 0).length === 0 && getSignaturesOfType(type, 1).length === 0; } + function createTransientSymbol(source, type) { + var symbol = createSymbol(source.flags | 67108864, source.name); + symbol.declarations = source.declarations; + symbol.parent = source.parent; + symbol.type = type; + symbol.target = source; + if (source.valueDeclaration) { + symbol.valueDeclaration = source.valueDeclaration; + } + return symbol; + } + function transformTypeOfMembers(type, f) { + var members = {}; + for (var _i = 0, _a = getPropertiesOfObjectType(type); _i < _a.length; _i++) { + var property = _a[_i]; + var original = getTypeOfSymbol(property); + var updated = f(original); + members[property.name] = updated === original ? property : createTransientSymbol(property, updated); + } + ; + return members; + } function getRegularTypeOfObjectLiteral(type) { - if (type.flags & 1048576) { - var regularType = type.regularType; - if (!regularType) { - regularType = createType(type.flags & ~1048576); - regularType.symbol = type.symbol; - regularType.members = type.members; - regularType.properties = type.properties; - regularType.callSignatures = type.callSignatures; - regularType.constructSignatures = type.constructSignatures; - regularType.stringIndexInfo = type.stringIndexInfo; - regularType.numberIndexInfo = type.numberIndexInfo; - type.regularType = regularType; - } + if (!(type.flags & 1048576)) { + return type; + } + var regularType = type.regularType; + if (regularType) { return regularType; } - return type; + var resolved = type; + var members = transformTypeOfMembers(type, getRegularTypeOfObjectLiteral); + var regularNew = createAnonymousType(resolved.symbol, members, resolved.callSignatures, resolved.constructSignatures, resolved.stringIndexInfo, resolved.numberIndexInfo); + regularNew.flags = resolved.flags & ~1048576; + type.regularType = regularNew; + return regularNew; } function getWidenedTypeOfObjectLiteral(type) { - var properties = getPropertiesOfObjectType(type); - var members = {}; - ts.forEach(properties, function (p) { - var propType = getTypeOfSymbol(p); - var widenedType = getWidenedType(propType); - if (propType !== widenedType) { - var symbol = createSymbol(p.flags | 67108864, p.name); - symbol.declarations = p.declarations; - symbol.parent = p.parent; - symbol.type = widenedType; - symbol.target = p; - if (p.valueDeclaration) - symbol.valueDeclaration = p.valueDeclaration; - p = symbol; - } - members[p.name] = p; + var members = transformTypeOfMembers(type, function (prop) { + var widened = getWidenedType(prop); + return prop === widened ? prop : widened; }); var stringIndexInfo = getIndexInfoOfType(type, 0); var numberIndexInfo = getIndexInfoOfType(type, 1); @@ -18062,7 +18090,7 @@ var ts; inferFromTypes(source, t); } } - if (target.flags & 16384 && typeParameterCount === 1) { + if (typeParameterCount === 1) { inferiority++; inferFromTypes(source, typeParameter); inferiority--; @@ -19134,7 +19162,7 @@ var ts; } return nodeCheckFlag === 512 ? getBaseConstructorTypeOfClass(classType) - : baseClassType; + : getTypeWithThisArgument(baseClassType, classType.thisType); function isLegalUsageOfSuperExpression(container) { if (!container) { return false; @@ -21182,7 +21210,7 @@ var ts; var types = void 0; var funcIsGenerator = !!func.asteriskToken; if (funcIsGenerator) { - types = checkAndAggregateYieldOperandTypes(func.body, contextualMapper); + types = checkAndAggregateYieldOperandTypes(func, contextualMapper); if (types.length === 0) { var iterableIteratorAny = createIterableIteratorType(anyType); if (compilerOptions.noImplicitAny) { @@ -21192,8 +21220,7 @@ var ts; } } else { - var hasImplicitReturn = !!(func.flags & 32768); - types = checkAndAggregateReturnExpressionTypes(func.body, contextualMapper, isAsync, hasImplicitReturn); + types = checkAndAggregateReturnExpressionTypes(func, contextualMapper); if (!types) { return neverType; } @@ -21240,9 +21267,9 @@ var ts; return widenedType; } } - function checkAndAggregateYieldOperandTypes(body, contextualMapper) { + function checkAndAggregateYieldOperandTypes(func, contextualMapper) { var aggregatedTypes = []; - ts.forEachYieldExpression(body, function (yieldExpression) { + ts.forEachYieldExpression(func.body, function (yieldExpression) { var expr = yieldExpression.expression; if (expr) { var type = checkExpressionCached(expr, contextualMapper); @@ -21256,28 +21283,34 @@ var ts; }); return aggregatedTypes; } - function checkAndAggregateReturnExpressionTypes(body, contextualMapper, isAsync, hasImplicitReturn) { + function checkAndAggregateReturnExpressionTypes(func, contextualMapper) { + var isAsync = ts.isAsyncFunctionLike(func); var aggregatedTypes = []; - var hasOmittedExpressions = false; - ts.forEachReturnStatement(body, function (returnStatement) { + var hasReturnWithNoExpression = !!(func.flags & 32768); + var hasReturnOfTypeNever = false; + ts.forEachReturnStatement(func.body, function (returnStatement) { var expr = returnStatement.expression; if (expr) { var type = checkExpressionCached(expr, contextualMapper); if (isAsync) { - type = checkAwaitedType(type, body.parent, ts.Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member); + type = checkAwaitedType(type, func, ts.Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member); } - if (type !== neverType && !ts.contains(aggregatedTypes, type)) { + if (type === neverType) { + hasReturnOfTypeNever = true; + } + else if (!ts.contains(aggregatedTypes, type)) { aggregatedTypes.push(type); } } else { - hasOmittedExpressions = true; + hasReturnWithNoExpression = true; } }); - if (aggregatedTypes.length === 0 && !hasOmittedExpressions && !hasImplicitReturn) { + if (aggregatedTypes.length === 0 && !hasReturnWithNoExpression && (hasReturnOfTypeNever || + func.kind === 179 || func.kind === 180)) { return undefined; } - if (strictNullChecks && aggregatedTypes.length && (hasOmittedExpressions || hasImplicitReturn)) { + if (strictNullChecks && aggregatedTypes.length && hasReturnWithNoExpression) { if (!ts.contains(aggregatedTypes, undefinedType)) { aggregatedTypes.push(undefinedType); } @@ -21407,7 +21440,9 @@ var ts; (expr.kind === 172 || expr.kind === 173) && expr.expression.kind === 97) { var func = ts.getContainingFunction(expr); - return !(func && func.kind === 148 && func.parent === symbol.valueDeclaration.parent); + if (!(func && func.kind === 148)) + return true; + return !(func.parent === symbol.valueDeclaration.parent || func === symbol.valueDeclaration.parent); } return true; } @@ -22231,6 +22266,79 @@ var ts; } } } + function checkClassForDuplicateDeclarations(node) { + var getter = 1, setter = 2, property = getter | setter; + var instanceNames = {}; + var staticNames = {}; + for (var _i = 0, _a = node.members; _i < _a.length; _i++) { + var member = _a[_i]; + if (member.kind === 148) { + for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) { + var param = _c[_b]; + if (ts.isParameterPropertyDeclaration(param)) { + addName(instanceNames, param.name, param.name.text, property); + } + } + } + else { + var static = ts.forEach(member.modifiers, function (m) { return m.kind === 113; }); + var names = static ? staticNames : instanceNames; + var memberName = member.name && ts.getPropertyNameForPropertyNameNode(member.name); + if (memberName) { + switch (member.kind) { + case 149: + addName(names, member.name, memberName, getter); + break; + case 150: + addName(names, member.name, memberName, setter); + break; + case 145: + addName(names, member.name, memberName, property); + break; + } + } + } + } + function addName(names, location, name, meaning) { + if (ts.hasProperty(names, name)) { + var prev = names[name]; + if (prev & meaning) { + error(location, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(location)); + } + else { + names[name] = prev | meaning; + } + } + else { + names[name] = meaning; + } + } + } + function checkObjectTypeForDuplicateDeclarations(node) { + var names = {}; + for (var _i = 0, _a = node.members; _i < _a.length; _i++) { + var member = _a[_i]; + if (member.kind == 144) { + var memberName = void 0; + switch (member.name.kind) { + case 9: + case 8: + case 69: + memberName = member.name.text; + break; + default: + continue; + } + if (ts.hasProperty(names, memberName)) { + error(member.symbol.valueDeclaration.name, ts.Diagnostics.Duplicate_identifier_0, memberName); + error(member.name, ts.Diagnostics.Duplicate_identifier_0, memberName); + } + else { + names[memberName] = true; + } + } + } + } function checkTypeForDuplicateIndexSignatures(node) { if (node.kind === 222) { var nodeSymbol = getSymbolOfNode(node); @@ -22449,6 +22557,7 @@ var ts; var type = getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node); checkIndexConstraints(type); checkTypeForDuplicateIndexSignatures(node); + checkObjectTypeForDuplicateDeclarations(node); } } function checkArrayType(node) { @@ -23208,6 +23317,10 @@ var ts; if (node.initializer) { checkTypeAssignableTo(checkExpressionCached(node.initializer), declarationType, node, undefined); } + if (!areDeclarationFlagsIdentical(node, symbol.valueDeclaration)) { + error(symbol.valueDeclaration.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name)); + error(node.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name)); + } } if (node.kind !== 145 && node.kind !== 144) { checkExportsOnMergedDeclarations(node); @@ -23220,6 +23333,18 @@ var ts; checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name); } } + function areDeclarationFlagsIdentical(left, right) { + if (ts.hasQuestionToken(left) !== ts.hasQuestionToken(right)) { + return false; + } + var interestingFlags = 8 | + 16 | + 256 | + 128 | + 64 | + 32; + return (left.flags & interestingFlags) === (right.flags & interestingFlags); + } function checkVariableDeclaration(node) { checkGrammarVariableDeclaration(node); return checkVariableLikeDeclaration(node); @@ -23770,6 +23895,7 @@ var ts; var typeWithThis = getTypeWithThisArgument(type); var staticType = getTypeOfSymbol(symbol); checkTypeParameterListsIdentical(node, symbol); + checkClassForDuplicateDeclarations(node); var baseTypeNode = ts.getClassExtendsHeritageClauseElement(node); if (baseTypeNode) { var baseTypes = getBaseTypes(type); @@ -23981,6 +24107,7 @@ var ts; checkIndexConstraints(type); } } + checkObjectTypeForDuplicateDeclarations(node); } ts.forEach(ts.getInterfaceBaseTypeNodes(node), function (heritageElement) { if (!ts.isSupportedExpressionWithTypeArguments(heritageElement)) { @@ -24735,10 +24862,8 @@ var ts; function checkSourceFileWorker(node) { var links = getNodeLinks(node); if (!(links.flags & 1)) { - if (compilerOptions.skipDefaultLibCheck) { - if (node.hasNoDefaultLib) { - return; - } + if (compilerOptions.skipLibCheck && node.isDeclarationFile || compilerOptions.skipDefaultLibCheck && node.hasNoDefaultLib) { + return; } checkGrammarSourceFile(node); potentialThisCollisions.length = 0; @@ -25107,7 +25232,7 @@ var ts; return symbol && getTypeOfSymbol(symbol); } if (ts.isBindingPattern(node)) { - return getTypeForVariableLikeDeclaration(node.parent); + return getTypeForVariableLikeDeclaration(node.parent, true); } if (isInRightSideOfImportOrExportAssignment(node)) { var symbol = getSymbolAtLocation(node); @@ -25546,7 +25671,7 @@ var ts; if (file.moduleAugmentations.length) { (augmentations || (augmentations = [])).push(file.moduleAugmentations); } - if (file.wasReferenced && file.symbol && file.symbol.globalExports) { + if (file.symbol && file.symbol.globalExports) { mergeSymbolTable(globals, file.symbol.globalExports); } }); @@ -26116,7 +26241,6 @@ var ts; if (prop.kind === 193 || name_20.kind === 140) { checkGrammarComputedPropertyName(name_20); - return "continue"; } if (prop.kind === 254 && !inDestructuring && prop.objectAssignmentInitializer) { return { value: grammarErrorOnNode(prop.equalsToken, ts.Diagnostics.can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment) }; @@ -26146,17 +26270,21 @@ var ts; else { ts.Debug.fail("Unexpected syntax kind:" + prop.kind); } - if (!ts.hasProperty(seen, name_20.text)) { - seen[name_20.text] = currentKind; + var effectiveName = ts.getPropertyNameForPropertyNameNode(name_20); + if (effectiveName === undefined) { + return "continue"; + } + if (!ts.hasProperty(seen, effectiveName)) { + seen[effectiveName] = currentKind; } else { - var existingKind = seen[name_20.text]; + var existingKind = seen[effectiveName]; if (currentKind === Property && existingKind === Property) { - return "continue"; + grammarErrorOnNode(name_20, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(name_20)); } else if ((currentKind & GetOrSetAccessor) && (existingKind & GetOrSetAccessor)) { if (existingKind !== GetOrSetAccessor && currentKind !== existingKind) { - seen[name_20.text] = currentKind | existingKind; + seen[effectiveName] = currentKind | existingKind; } else { return { value: grammarErrorOnNode(name_20, ts.Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name) }; @@ -34613,7 +34741,7 @@ var ts; skipTsx: true, traceEnabled: traceEnabled }; - var rootDir = options.typesRoot || (options.configFilePath ? ts.getDirectoryPath(options.configFilePath) : undefined); + var rootDir = options.typesRoot || (options.configFilePath ? ts.getDirectoryPath(options.configFilePath) : (host.getCurrentDirectory && host.getCurrentDirectory())); if (traceEnabled) { if (containingFile === undefined) { if (rootDir === undefined) { @@ -35116,12 +35244,25 @@ var ts; } } } + function getDefaultTypeDirectiveNames(rootPath) { + var localTypes = ts.combinePaths(rootPath, "types"); + var npmTypes = ts.combinePaths(rootPath, "node_modules/@types"); + var result = []; + if (ts.sys.directoryExists(localTypes)) { + result = result.concat(ts.sys.getDirectories(localTypes)); + } + if (ts.sys.directoryExists(npmTypes)) { + result = result.concat(ts.sys.getDirectories(npmTypes)); + } + return result; + } function getDefaultLibLocation() { return ts.getDirectoryPath(ts.normalizePath(ts.sys.getExecutingFilePath())); } var newLine = ts.getNewLineCharacter(options); var realpath = ts.sys.realpath && (function (path) { return ts.sys.realpath(path); }); return { + getDefaultTypeDirectiveNames: getDefaultTypeDirectiveNames, getSourceFile: getSourceFile, getDefaultLibLocation: getDefaultLibLocation, getDefaultLibFileName: function (options) { return ts.combinePaths(getDefaultLibLocation(), ts.getDefaultLibFileName(options)); }, @@ -35189,6 +35330,19 @@ var ts; } return resolutions; } + function getDefaultTypeDirectiveNames(options, rootFiles, host) { + if (options.types) { + return options.types; + } + if (host && host.getDefaultTypeDirectiveNames) { + var commonRoot = computeCommonSourceDirectoryOfFilenames(rootFiles, host.getCurrentDirectory(), function (f) { return host.getCanonicalFileName(f); }); + if (commonRoot) { + return host.getDefaultTypeDirectiveNames(commonRoot); + } + } + return undefined; + } + ts.getDefaultTypeDirectiveNames = getDefaultTypeDirectiveNames; function createProgram(rootNames, options, host, oldProgram) { var program; var files = []; @@ -35224,13 +35378,14 @@ var ts; var filesByName = ts.createFileMap(); var filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? ts.createFileMap(function (fileName) { return fileName.toLowerCase(); }) : undefined; if (!tryReuseStructureFromOldProgram()) { - if (options.types && options.types.length) { - var resolutions = resolveTypeReferenceDirectiveNamesWorker(options.types, undefined); - for (var i = 0; i < options.types.length; i++) { - processTypeReferenceDirective(options.types[i], resolutions[i]); + ts.forEach(rootNames, function (name) { return processRootFile(name, false); }); + var typeReferences = getDefaultTypeDirectiveNames(options, rootNames, host); + if (typeReferences) { + var resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, undefined); + for (var i = 0; i < typeReferences.length; i++) { + processTypeReferenceDirective(typeReferences[i], resolutions[i]); } } - ts.forEach(rootNames, function (name) { return processRootFile(name, false); }); if (!skipDefaultLib) { if (!options.lib) { processRootFile(host.getDefaultLibFileName(options), true); @@ -35807,9 +35962,6 @@ var ts; if (file_1 && options.forceConsistentCasingInFileNames && ts.getNormalizedAbsolutePath(file_1.fileName, currentDirectory) !== ts.getNormalizedAbsolutePath(fileName, currentDirectory)) { reportFileNamesDifferOnlyInCasingError(fileName, file_1.fileName, refFile, refPos, refEnd); } - if (file_1) { - file_1.wasReferenced = file_1.wasReferenced || isReference; - } return file_1; } var file = host.getSourceFile(fileName, options.target, function (hostErrorMessage) { @@ -35822,7 +35974,6 @@ var ts; }); filesByName.set(path, file); if (file) { - file.wasReferenced = file.wasReferenced || isReference; file.path = path; if (host.useCaseSensitiveFileNames()) { var existingFile = filesByNameIgnoreCase.get(path); @@ -35923,17 +36074,7 @@ var ts; !options.noResolve && i < file.imports.length; if (shouldAddFile) { - var importedFile = findSourceFile(resolution.resolvedFileName, ts.toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName), false, false, file, ts.skipTrivia(file.text, file.imports[i].pos), file.imports[i].end); - if (importedFile && resolution.isExternalLibraryImport) { - if (!ts.isExternalModule(importedFile) && importedFile.statements.length) { - var start_5 = ts.getTokenPosOfNode(file.imports[i], file); - fileProcessingDiagnostics.add(ts.createFileDiagnostic(file, start_5, file.imports[i].end - start_5, ts.Diagnostics.Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_the_package_definition, importedFile.fileName)); - } - else if (importedFile.referencedFiles.length) { - var firstRef = importedFile.referencedFiles[0]; - fileProcessingDiagnostics.add(ts.createFileDiagnostic(importedFile, firstRef.pos, firstRef.end - firstRef.pos, ts.Diagnostics.Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_package_author_to_update_the_package_definition)); - } - } + findSourceFile(resolution.resolvedFileName, ts.toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName), false, false, file, ts.skipTrivia(file.text, file.imports[i].pos), file.imports[i].end); } } } @@ -36018,7 +36159,7 @@ var ts; } } else { - programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Substututions_for_pattern_0_should_be_an_array, key)); + programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Substitutions_for_pattern_0_should_be_an_array, key)); } } } @@ -36067,13 +36208,19 @@ var ts; } else if (firstExternalModuleSourceFile && languageVersion < 2 && options.module === ts.ModuleKind.None) { var span = ts.getErrorSpanForNode(firstExternalModuleSourceFile, firstExternalModuleSourceFile.externalModuleIndicator); - programDiagnostics.add(ts.createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_modules_unless_the_module_flag_is_provided_with_a_valid_module_type_Consider_setting_the_module_compiler_option_in_a_tsconfig_json_file)); + programDiagnostics.add(ts.createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none)); } if (options.module === ts.ModuleKind.ES6 && languageVersion < 2) { programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_compile_modules_into_es2015_when_targeting_ES5_or_lower)); } - if (outFile && options.module && !(options.module === ts.ModuleKind.AMD || options.module === ts.ModuleKind.System)) { - programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile")); + if (outFile) { + if (options.module && !(options.module === ts.ModuleKind.AMD || options.module === ts.ModuleKind.System)) { + programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile")); + } + else if (options.module === undefined && firstExternalModuleSourceFile) { + var span = ts.getErrorSpanForNode(firstExternalModuleSourceFile, firstExternalModuleSourceFile.externalModuleIndicator); + programDiagnostics.add(ts.createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system, options.out ? "out" : "outFile")); + } } if (options.outDir || options.sourceRoot || @@ -36156,6 +36303,11 @@ var ts; type: "boolean", description: ts.Diagnostics.Print_this_message }, + { + name: "help", + shortName: "?", + type: "boolean" + }, { name: "init", type: "boolean", @@ -36258,6 +36410,11 @@ var ts; name: "skipDefaultLibCheck", type: "boolean" }, + { + name: "skipLibCheck", + type: "boolean", + description: ts.Diagnostics.Skip_type_checking_of_declaration_files + }, { name: "out", type: "string", diff --git a/lib/tsserver.js b/lib/tsserver.js index ecb7bfb5509..dcf76693225 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -918,6 +918,10 @@ var ts; } return result.sort(); } + function getDirectories(path) { + var folder = fso.GetFolder(path); + return getNames(folder.subfolders); + } function readDirectory(path, extension, exclude) { var result = []; exclude = ts.map(exclude, function (s) { return getCanonicalPath(ts.combinePaths(path, s)); }); @@ -972,6 +976,7 @@ var ts; getCurrentDirectory: function () { return new ActiveXObject("WScript.Shell").CurrentDirectory; }, + getDirectories: getDirectories, readDirectory: readDirectory, exit: function (exitCode) { try { @@ -1119,6 +1124,9 @@ var ts; function directoryExists(path) { return fileSystemEntryExists(path, 1); } + function getDirectories(path) { + return ts.filter(_fs.readdirSync(path), function (p) { return fileSystemEntryExists(ts.combinePaths(path, p), 1); }); + } function readDirectory(path, extension, exclude) { var result = []; exclude = ts.map(exclude, function (s) { return getCanonicalPath(ts.combinePaths(path, s)); }); @@ -1211,6 +1219,7 @@ var ts; getCurrentDirectory: function () { return process.cwd(); }, + getDirectories: getDirectories, readDirectory: readDirectory, getModifiedTime: function (path) { try { @@ -1261,6 +1270,7 @@ var ts; createDirectory: ChakraHost.createDirectory, getExecutingFilePath: function () { return ChakraHost.executingFile; }, getCurrentDirectory: function () { return ChakraHost.currentDirectory; }, + getDirectories: ChakraHost.getDirectories, readDirectory: ChakraHost.readDirectory, exit: ChakraHost.quit, realpath: realpath @@ -1394,7 +1404,7 @@ var ts; or_expected: { code: 1144, category: ts.DiagnosticCategory.Error, key: "or_expected_1144", message: "'{' or ';' expected." }, Declaration_expected: { code: 1146, category: ts.DiagnosticCategory.Error, key: "Declaration_expected_1146", message: "Declaration expected." }, Import_declarations_in_a_namespace_cannot_reference_a_module: { code: 1147, category: ts.DiagnosticCategory.Error, key: "Import_declarations_in_a_namespace_cannot_reference_a_module_1147", message: "Import declarations in a namespace cannot reference a module." }, - Cannot_compile_modules_unless_the_module_flag_is_provided_with_a_valid_module_type_Consider_setting_the_module_compiler_option_in_a_tsconfig_json_file: { code: 1148, category: ts.DiagnosticCategory.Error, key: "Cannot_compile_modules_unless_the_module_flag_is_provided_with_a_valid_module_type_Consider_setting__1148", message: "Cannot compile modules unless the '--module' flag is provided with a valid module type. Consider setting the 'module' compiler option in a 'tsconfig.json' file." }, + Cannot_use_imports_exports_or_module_augmentations_when_module_is_none: { code: 1148, category: ts.DiagnosticCategory.Error, key: "Cannot_use_imports_exports_or_module_augmentations_when_module_is_none_1148", message: "Cannot use imports, exports, or module augmentations when '--module' is 'none'." }, File_name_0_differs_from_already_included_file_name_1_only_in_casing: { code: 1149, category: ts.DiagnosticCategory.Error, key: "File_name_0_differs_from_already_included_file_name_1_only_in_casing_1149", message: "File name '{0}' differs from already included file name '{1}' only in casing" }, new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead: { code: 1150, category: ts.DiagnosticCategory.Error, key: "new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead_1150", message: "'new T[]' cannot be used to create an array. Use 'new Array()' instead." }, const_declarations_must_be_initialized: { code: 1155, category: ts.DiagnosticCategory.Error, key: "const_declarations_must_be_initialized_1155", message: "'const' declarations must be initialized" }, @@ -1764,6 +1774,8 @@ var ts; this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation: { code: 2683, category: ts.DiagnosticCategory.Error, key: "this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_2683", message: "'this' implicitly has type 'any' because it does not have a type annotation." }, The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1: { code: 2684, category: ts.DiagnosticCategory.Error, key: "The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1_2684", message: "The 'this' context of type '{0}' is not assignable to method's 'this' of type '{1}'." }, The_this_types_of_each_signature_are_incompatible: { code: 2685, category: ts.DiagnosticCategory.Error, key: "The_this_types_of_each_signature_are_incompatible_2685", message: "The 'this' types of each signature are incompatible." }, + Identifier_0_must_be_imported_from_a_module: { code: 2686, category: ts.DiagnosticCategory.Error, key: "Identifier_0_must_be_imported_from_a_module_2686", message: "Identifier '{0}' must be imported from a module" }, + All_declarations_of_0_must_have_identical_modifiers: { code: 2687, category: ts.DiagnosticCategory.Error, key: "All_declarations_of_0_must_have_identical_modifiers_2687", message: "All declarations of '{0}' must have identical modifiers." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: ts.DiagnosticCategory.Error, key: "Import_declaration_0_is_using_private_name_1_4000", message: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: ts.DiagnosticCategory.Error, key: "Type_parameter_0_of_exported_class_has_or_is_using_private_name_1_4002", message: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: ts.DiagnosticCategory.Error, key: "Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1_4004", message: "Type parameter '{0}' of exported interface has or is using private name '{1}'." }, @@ -1857,7 +1869,7 @@ var ts; Option_paths_cannot_be_used_without_specifying_baseUrl_option: { code: 5060, category: ts.DiagnosticCategory.Error, key: "Option_paths_cannot_be_used_without_specifying_baseUrl_option_5060", message: "Option 'paths' cannot be used without specifying '--baseUrl' option." }, Pattern_0_can_have_at_most_one_Asterisk_character: { code: 5061, category: ts.DiagnosticCategory.Error, key: "Pattern_0_can_have_at_most_one_Asterisk_character_5061", message: "Pattern '{0}' can have at most one '*' character" }, Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character: { code: 5062, category: ts.DiagnosticCategory.Error, key: "Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character_5062", message: "Substitution '{0}' in pattern '{1}' in can have at most one '*' character" }, - Substututions_for_pattern_0_should_be_an_array: { code: 5063, category: ts.DiagnosticCategory.Error, key: "Substututions_for_pattern_0_should_be_an_array_5063", message: "Substututions for pattern '{0}' should be an array." }, + Substitutions_for_pattern_0_should_be_an_array: { code: 5063, category: ts.DiagnosticCategory.Error, key: "Substitutions_for_pattern_0_should_be_an_array_5063", message: "Substitutions for pattern '{0}' should be an array." }, Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2: { code: 5064, category: ts.DiagnosticCategory.Error, key: "Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2_5064", message: "Substitution '{0}' for pattern '{1}' has incorrect type, expected 'string', got '{2}'." }, Concatenate_and_emit_output_to_single_file: { code: 6001, category: ts.DiagnosticCategory.Message, key: "Concatenate_and_emit_output_to_single_file_6001", message: "Concatenate and emit output to single file." }, Generates_corresponding_d_ts_file: { code: 6002, category: ts.DiagnosticCategory.Message, key: "Generates_corresponding_d_ts_file_6002", message: "Generates corresponding '.d.ts' file." }, @@ -1870,6 +1882,7 @@ var ts; Do_not_emit_comments_to_output: { code: 6009, category: ts.DiagnosticCategory.Message, key: "Do_not_emit_comments_to_output_6009", message: "Do not emit comments to output." }, Do_not_emit_outputs: { code: 6010, category: ts.DiagnosticCategory.Message, key: "Do_not_emit_outputs_6010", message: "Do not emit outputs." }, Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking: { code: 6011, category: ts.DiagnosticCategory.Message, key: "Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011", message: "Allow default imports from modules with no default export. This does not affect code emit, just typechecking." }, + Skip_type_checking_of_declaration_files: { code: 6012, category: ts.DiagnosticCategory.Message, key: "Skip_type_checking_of_declaration_files_6012", message: "Skip type checking of declaration files." }, Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015: { code: 6015, category: ts.DiagnosticCategory.Message, key: "Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015_6015", message: "Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES2015'" }, Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015: { code: 6016, category: ts.DiagnosticCategory.Message, key: "Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015_6016", message: "Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'" }, Print_this_message: { code: 6017, category: ts.DiagnosticCategory.Message, key: "Print_this_message_6017", message: "Print this message." }, @@ -1971,6 +1984,7 @@ var ts; Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set: { code: 6128, category: ts.DiagnosticCategory.Message, key: "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set_6128", message: "======== Resolving type reference directive '{0}', containing file not set, root directory not set. ========" }, The_config_file_0_found_doesn_t_contain_any_source_files: { code: 6129, category: ts.DiagnosticCategory.Error, key: "The_config_file_0_found_doesn_t_contain_any_source_files_6129", message: "The config file '{0}' found doesn't contain any source files." }, Resolving_real_path_for_0_result_1: { code: 6130, category: ts.DiagnosticCategory.Message, key: "Resolving_real_path_for_0_result_1_6130", message: "Resolving real path for '{0}', result '{1}'" }, + Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system: { code: 6131, category: ts.DiagnosticCategory.Error, key: "Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system_6131", message: "Cannot compile modules using option '{0}' unless the '--module' flag is 'amd' or 'system'." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable_0_implicitly_has_an_1_type_7005", message: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter_0_implicitly_has_an_1_type_7006", message: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member_0_implicitly_has_an_1_type_7008", message: "Member '{0}' implicitly has an '{1}' type." }, @@ -3537,6 +3551,11 @@ var ts; type: "boolean", description: ts.Diagnostics.Print_this_message }, + { + name: "help", + shortName: "?", + type: "boolean" + }, { name: "init", type: "boolean", @@ -3639,6 +3658,11 @@ var ts; name: "skipDefaultLibCheck", type: "boolean" }, + { + name: "skipLibCheck", + type: "boolean", + description: ts.Diagnostics.Skip_type_checking_of_declaration_files + }, { name: "out", type: "string", @@ -5758,7 +5782,7 @@ var ts; } ts.isWellKnownSymbolSyntactically = isWellKnownSymbolSyntactically; function getPropertyNameForPropertyNameNode(name) { - if (name.kind === 69 || name.kind === 9 || name.kind === 8) { + if (name.kind === 69 || name.kind === 9 || name.kind === 8 || name.kind === 142) { return name.text; } if (name.kind === 140) { @@ -12804,10 +12828,10 @@ var ts; case 145: case 144: case 266: - return bindPropertyOrMethodOrAccessor(node, 4 | (node.questionToken ? 536870912 : 0), 107455); + return bindPropertyOrMethodOrAccessor(node, 4 | (node.questionToken ? 536870912 : 0), 0); case 253: case 254: - return bindPropertyOrMethodOrAccessor(node, 4, 107455); + return bindPropertyOrMethodOrAccessor(node, 4, 0); case 255: return bindPropertyOrMethodOrAccessor(node, 8, 107455); case 247: @@ -12819,7 +12843,7 @@ var ts; return declareSymbolAndAddToSymbolTable(node, 131072, 0); case 147: case 146: - return bindPropertyOrMethodOrAccessor(node, 8192 | (node.questionToken ? 536870912 : 0), ts.isObjectLiteralMethod(node) ? 107455 : 99263); + return bindPropertyOrMethodOrAccessor(node, 8192 | (node.questionToken ? 536870912 : 0), ts.isObjectLiteralMethod(node) ? 0 : 99263); case 220: return bindFunctionDeclaration(node); case 148: @@ -12862,7 +12886,7 @@ var ts; case 238: return declareSymbolAndAddToSymbolTable(node, 8388608, 8388608); case 228: - return bindGlobalModuleExportDeclaration(node); + return bindNamespaceExportDeclaration(node); case 231: return bindImportClause(node); case 236: @@ -12898,13 +12922,13 @@ var ts; bindAnonymousDeclaration(node, 8388608, getDeclarationName(node)); } else if (boundExpression.kind === 69 && node.kind === 235) { - declareSymbol(container.symbol.exports, container.symbol, node, 8388608, 107455 | 8388608); + declareSymbol(container.symbol.exports, container.symbol, node, 8388608, 0 | 8388608); } else { - declareSymbol(container.symbol.exports, container.symbol, node, 4, 107455 | 8388608); + declareSymbol(container.symbol.exports, container.symbol, node, 4, 0 | 8388608); } } - function bindGlobalModuleExportDeclaration(node) { + function bindNamespaceExportDeclaration(node) { if (node.modifiers && node.modifiers.length) { file.bindDiagnostics.push(ts.createDiagnosticForNode(node, ts.Diagnostics.Modifiers_cannot_appear_here)); } @@ -12956,7 +12980,7 @@ var ts; function bindThisPropertyAssignment(node) { if (container.kind === 179 || container.kind === 220) { container.symbol.members = container.symbol.members || {}; - declareSymbol(container.symbol.members, container.symbol, node, 4, 107455 & ~4); + declareSymbol(container.symbol.members, container.symbol, node, 4, 0 & ~4); } } function bindPrototypePropertyAssignment(node) { @@ -12973,7 +12997,7 @@ var ts; if (!funcSymbol.members) { funcSymbol.members = {}; } - declareSymbol(funcSymbol.members, funcSymbol, leftSideOfAssignment, 4, 107455); + declareSymbol(funcSymbol.members, funcSymbol, leftSideOfAssignment, 4, 0); } function bindCallExpression(node) { if (!file.commonJsModuleIndicator && ts.isRequireCall(node, false)) { @@ -13049,7 +13073,7 @@ var ts; } if (ts.isParameterPropertyDeclaration(node)) { var classDeclaration = node.parent.parent; - declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4, 107455); + declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4, 0); } } function bindFunctionDeclaration(node) { @@ -13349,7 +13373,7 @@ var ts; if (flags & 1) result |= 107454; if (flags & 4) - result |= 107455; + result |= 0; if (flags & 8) result |= 107455; if (flags & 16) @@ -13605,6 +13629,7 @@ var ts; var propertyWithInvalidInitializer; var errorLocation = location; var grandparent; + var isInExternalModule = false; loop: while (location) { if (location.locals && !isGlobalSourceFile(location)) { if (result = getSymbol(location.locals, name, meaning)) { @@ -13636,6 +13661,7 @@ var ts; case 256: if (!ts.isExternalOrCommonJsModule(location)) break; + isInExternalModule = true; case 225: var moduleExports = getSymbolOfNode(location).exports; if (location.kind === 256 || ts.isAmbientModule(location)) { @@ -13759,6 +13785,12 @@ var ts; checkResolvedBlockScopedVariable(exportOrLocalSymbol, errorLocation); } } + if (result && isInExternalModule) { + var decls = result.declarations; + if (decls && decls.length === 1 && decls[0].kind === 228) { + error(errorLocation, ts.Diagnostics.Identifier_0_must_be_imported_from_a_module, name); + } + } } return result; } @@ -15234,7 +15266,7 @@ var ts; } function getTypeForBindingElementParent(node) { var symbol = getSymbolOfNode(node); - return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node); + return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node, false); } function getTextOfPropertyName(name) { switch (name.kind) { @@ -15339,7 +15371,7 @@ var ts; function addOptionality(type, optional) { return strictNullChecks && optional ? addNullableKind(type, 32) : type; } - function getTypeForVariableLikeDeclaration(declaration) { + function getTypeForVariableLikeDeclaration(declaration, includeOptionality) { if (declaration.flags & 134217728) { var type = getTypeForVariableLikeDeclarationFromJSDocComment(declaration); if (type && type !== unknownType) { @@ -15356,7 +15388,7 @@ var ts; return getTypeForBindingElement(declaration); } if (declaration.type) { - return addOptionality(getTypeFromTypeNode(declaration.type), !!declaration.questionToken); + return addOptionality(getTypeFromTypeNode(declaration.type), declaration.questionToken && includeOptionality); } if (declaration.kind === 142) { var func = declaration.parent; @@ -15375,11 +15407,11 @@ var ts; ? getContextuallyTypedThisType(func) : getContextuallyTypedParameterType(declaration); if (type) { - return addOptionality(type, !!declaration.questionToken); + return addOptionality(type, declaration.questionToken && includeOptionality); } } if (declaration.initializer) { - return addOptionality(checkExpressionCached(declaration.initializer), !!declaration.questionToken); + return addOptionality(checkExpressionCached(declaration.initializer), declaration.questionToken && includeOptionality); } if (declaration.kind === 254) { return checkIdentifier(declaration.name); @@ -15447,7 +15479,7 @@ var ts; : getTypeFromArrayBindingPattern(pattern, includePatternInType); } function getWidenedTypeForVariableLikeDeclaration(declaration, reportErrors) { - var type = getTypeForVariableLikeDeclaration(declaration); + var type = getTypeForVariableLikeDeclaration(declaration, true); if (type) { if (reportErrors) { reportErrorsFromWidening(declaration, type); @@ -17764,7 +17796,7 @@ var ts; return isIdenticalTo(source, target); } if (!(target.flags & 134217728)) { - if (target.flags & 1) + if (target.flags & 1 || source.flags & 134217728) return -1; if (source.flags & 32) { if (!strictNullChecks || target.flags & (32 | 16) || source === emptyArrayElementType) @@ -17784,7 +17816,7 @@ var ts; if (source.flags & 256 && target === stringType) return -1; if (relation === assignableRelation || relation === comparableRelation) { - if (source.flags & (1 | 134217728)) + if (source.flags & 1) return -1; if (source === numberType && target.flags & 128) return -1; @@ -18561,41 +18593,47 @@ var ts; getSignaturesOfType(type, 0).length === 0 && getSignaturesOfType(type, 1).length === 0; } + function createTransientSymbol(source, type) { + var symbol = createSymbol(source.flags | 67108864, source.name); + symbol.declarations = source.declarations; + symbol.parent = source.parent; + symbol.type = type; + symbol.target = source; + if (source.valueDeclaration) { + symbol.valueDeclaration = source.valueDeclaration; + } + return symbol; + } + function transformTypeOfMembers(type, f) { + var members = {}; + for (var _i = 0, _a = getPropertiesOfObjectType(type); _i < _a.length; _i++) { + var property = _a[_i]; + var original = getTypeOfSymbol(property); + var updated = f(original); + members[property.name] = updated === original ? property : createTransientSymbol(property, updated); + } + ; + return members; + } function getRegularTypeOfObjectLiteral(type) { - if (type.flags & 1048576) { - var regularType = type.regularType; - if (!regularType) { - regularType = createType(type.flags & ~1048576); - regularType.symbol = type.symbol; - regularType.members = type.members; - regularType.properties = type.properties; - regularType.callSignatures = type.callSignatures; - regularType.constructSignatures = type.constructSignatures; - regularType.stringIndexInfo = type.stringIndexInfo; - regularType.numberIndexInfo = type.numberIndexInfo; - type.regularType = regularType; - } + if (!(type.flags & 1048576)) { + return type; + } + var regularType = type.regularType; + if (regularType) { return regularType; } - return type; + var resolved = type; + var members = transformTypeOfMembers(type, getRegularTypeOfObjectLiteral); + var regularNew = createAnonymousType(resolved.symbol, members, resolved.callSignatures, resolved.constructSignatures, resolved.stringIndexInfo, resolved.numberIndexInfo); + regularNew.flags = resolved.flags & ~1048576; + type.regularType = regularNew; + return regularNew; } function getWidenedTypeOfObjectLiteral(type) { - var properties = getPropertiesOfObjectType(type); - var members = {}; - ts.forEach(properties, function (p) { - var propType = getTypeOfSymbol(p); - var widenedType = getWidenedType(propType); - if (propType !== widenedType) { - var symbol = createSymbol(p.flags | 67108864, p.name); - symbol.declarations = p.declarations; - symbol.parent = p.parent; - symbol.type = widenedType; - symbol.target = p; - if (p.valueDeclaration) - symbol.valueDeclaration = p.valueDeclaration; - p = symbol; - } - members[p.name] = p; + var members = transformTypeOfMembers(type, function (prop) { + var widened = getWidenedType(prop); + return prop === widened ? prop : widened; }); var stringIndexInfo = getIndexInfoOfType(type, 0); var numberIndexInfo = getIndexInfoOfType(type, 1); @@ -18816,7 +18854,7 @@ var ts; inferFromTypes(source, t); } } - if (target.flags & 16384 && typeParameterCount === 1) { + if (typeParameterCount === 1) { inferiority++; inferFromTypes(source, typeParameter); inferiority--; @@ -19888,7 +19926,7 @@ var ts; } return nodeCheckFlag === 512 ? getBaseConstructorTypeOfClass(classType) - : baseClassType; + : getTypeWithThisArgument(baseClassType, classType.thisType); function isLegalUsageOfSuperExpression(container) { if (!container) { return false; @@ -21936,7 +21974,7 @@ var ts; var types = void 0; var funcIsGenerator = !!func.asteriskToken; if (funcIsGenerator) { - types = checkAndAggregateYieldOperandTypes(func.body, contextualMapper); + types = checkAndAggregateYieldOperandTypes(func, contextualMapper); if (types.length === 0) { var iterableIteratorAny = createIterableIteratorType(anyType); if (compilerOptions.noImplicitAny) { @@ -21946,8 +21984,7 @@ var ts; } } else { - var hasImplicitReturn = !!(func.flags & 32768); - types = checkAndAggregateReturnExpressionTypes(func.body, contextualMapper, isAsync, hasImplicitReturn); + types = checkAndAggregateReturnExpressionTypes(func, contextualMapper); if (!types) { return neverType; } @@ -21994,9 +22031,9 @@ var ts; return widenedType; } } - function checkAndAggregateYieldOperandTypes(body, contextualMapper) { + function checkAndAggregateYieldOperandTypes(func, contextualMapper) { var aggregatedTypes = []; - ts.forEachYieldExpression(body, function (yieldExpression) { + ts.forEachYieldExpression(func.body, function (yieldExpression) { var expr = yieldExpression.expression; if (expr) { var type = checkExpressionCached(expr, contextualMapper); @@ -22010,28 +22047,34 @@ var ts; }); return aggregatedTypes; } - function checkAndAggregateReturnExpressionTypes(body, contextualMapper, isAsync, hasImplicitReturn) { + function checkAndAggregateReturnExpressionTypes(func, contextualMapper) { + var isAsync = ts.isAsyncFunctionLike(func); var aggregatedTypes = []; - var hasOmittedExpressions = false; - ts.forEachReturnStatement(body, function (returnStatement) { + var hasReturnWithNoExpression = !!(func.flags & 32768); + var hasReturnOfTypeNever = false; + ts.forEachReturnStatement(func.body, function (returnStatement) { var expr = returnStatement.expression; if (expr) { var type = checkExpressionCached(expr, contextualMapper); if (isAsync) { - type = checkAwaitedType(type, body.parent, ts.Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member); + type = checkAwaitedType(type, func, ts.Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member); } - if (type !== neverType && !ts.contains(aggregatedTypes, type)) { + if (type === neverType) { + hasReturnOfTypeNever = true; + } + else if (!ts.contains(aggregatedTypes, type)) { aggregatedTypes.push(type); } } else { - hasOmittedExpressions = true; + hasReturnWithNoExpression = true; } }); - if (aggregatedTypes.length === 0 && !hasOmittedExpressions && !hasImplicitReturn) { + if (aggregatedTypes.length === 0 && !hasReturnWithNoExpression && (hasReturnOfTypeNever || + func.kind === 179 || func.kind === 180)) { return undefined; } - if (strictNullChecks && aggregatedTypes.length && (hasOmittedExpressions || hasImplicitReturn)) { + if (strictNullChecks && aggregatedTypes.length && hasReturnWithNoExpression) { if (!ts.contains(aggregatedTypes, undefinedType)) { aggregatedTypes.push(undefinedType); } @@ -22161,7 +22204,9 @@ var ts; (expr.kind === 172 || expr.kind === 173) && expr.expression.kind === 97) { var func = ts.getContainingFunction(expr); - return !(func && func.kind === 148 && func.parent === symbol.valueDeclaration.parent); + if (!(func && func.kind === 148)) + return true; + return !(func.parent === symbol.valueDeclaration.parent || func === symbol.valueDeclaration.parent); } return true; } @@ -22985,6 +23030,79 @@ var ts; } } } + function checkClassForDuplicateDeclarations(node) { + var getter = 1, setter = 2, property = getter | setter; + var instanceNames = {}; + var staticNames = {}; + for (var _i = 0, _a = node.members; _i < _a.length; _i++) { + var member = _a[_i]; + if (member.kind === 148) { + for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) { + var param = _c[_b]; + if (ts.isParameterPropertyDeclaration(param)) { + addName(instanceNames, param.name, param.name.text, property); + } + } + } + else { + var static = ts.forEach(member.modifiers, function (m) { return m.kind === 113; }); + var names = static ? staticNames : instanceNames; + var memberName = member.name && ts.getPropertyNameForPropertyNameNode(member.name); + if (memberName) { + switch (member.kind) { + case 149: + addName(names, member.name, memberName, getter); + break; + case 150: + addName(names, member.name, memberName, setter); + break; + case 145: + addName(names, member.name, memberName, property); + break; + } + } + } + } + function addName(names, location, name, meaning) { + if (ts.hasProperty(names, name)) { + var prev = names[name]; + if (prev & meaning) { + error(location, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(location)); + } + else { + names[name] = prev | meaning; + } + } + else { + names[name] = meaning; + } + } + } + function checkObjectTypeForDuplicateDeclarations(node) { + var names = {}; + for (var _i = 0, _a = node.members; _i < _a.length; _i++) { + var member = _a[_i]; + if (member.kind == 144) { + var memberName = void 0; + switch (member.name.kind) { + case 9: + case 8: + case 69: + memberName = member.name.text; + break; + default: + continue; + } + if (ts.hasProperty(names, memberName)) { + error(member.symbol.valueDeclaration.name, ts.Diagnostics.Duplicate_identifier_0, memberName); + error(member.name, ts.Diagnostics.Duplicate_identifier_0, memberName); + } + else { + names[memberName] = true; + } + } + } + } function checkTypeForDuplicateIndexSignatures(node) { if (node.kind === 222) { var nodeSymbol = getSymbolOfNode(node); @@ -23203,6 +23321,7 @@ var ts; var type = getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node); checkIndexConstraints(type); checkTypeForDuplicateIndexSignatures(node); + checkObjectTypeForDuplicateDeclarations(node); } } function checkArrayType(node) { @@ -23962,6 +24081,10 @@ var ts; if (node.initializer) { checkTypeAssignableTo(checkExpressionCached(node.initializer), declarationType, node, undefined); } + if (!areDeclarationFlagsIdentical(node, symbol.valueDeclaration)) { + error(symbol.valueDeclaration.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name)); + error(node.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name)); + } } if (node.kind !== 145 && node.kind !== 144) { checkExportsOnMergedDeclarations(node); @@ -23974,6 +24097,18 @@ var ts; checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name); } } + function areDeclarationFlagsIdentical(left, right) { + if (ts.hasQuestionToken(left) !== ts.hasQuestionToken(right)) { + return false; + } + var interestingFlags = 8 | + 16 | + 256 | + 128 | + 64 | + 32; + return (left.flags & interestingFlags) === (right.flags & interestingFlags); + } function checkVariableDeclaration(node) { checkGrammarVariableDeclaration(node); return checkVariableLikeDeclaration(node); @@ -24524,6 +24659,7 @@ var ts; var typeWithThis = getTypeWithThisArgument(type); var staticType = getTypeOfSymbol(symbol); checkTypeParameterListsIdentical(node, symbol); + checkClassForDuplicateDeclarations(node); var baseTypeNode = ts.getClassExtendsHeritageClauseElement(node); if (baseTypeNode) { var baseTypes = getBaseTypes(type); @@ -24735,6 +24871,7 @@ var ts; checkIndexConstraints(type); } } + checkObjectTypeForDuplicateDeclarations(node); } ts.forEach(ts.getInterfaceBaseTypeNodes(node), function (heritageElement) { if (!ts.isSupportedExpressionWithTypeArguments(heritageElement)) { @@ -25489,10 +25626,8 @@ var ts; function checkSourceFileWorker(node) { var links = getNodeLinks(node); if (!(links.flags & 1)) { - if (compilerOptions.skipDefaultLibCheck) { - if (node.hasNoDefaultLib) { - return; - } + if (compilerOptions.skipLibCheck && node.isDeclarationFile || compilerOptions.skipDefaultLibCheck && node.hasNoDefaultLib) { + return; } checkGrammarSourceFile(node); potentialThisCollisions.length = 0; @@ -25861,7 +25996,7 @@ var ts; return symbol && getTypeOfSymbol(symbol); } if (ts.isBindingPattern(node)) { - return getTypeForVariableLikeDeclaration(node.parent); + return getTypeForVariableLikeDeclaration(node.parent, true); } if (isInRightSideOfImportOrExportAssignment(node)) { var symbol = getSymbolAtLocation(node); @@ -26300,7 +26435,7 @@ var ts; if (file.moduleAugmentations.length) { (augmentations || (augmentations = [])).push(file.moduleAugmentations); } - if (file.wasReferenced && file.symbol && file.symbol.globalExports) { + if (file.symbol && file.symbol.globalExports) { mergeSymbolTable(globals, file.symbol.globalExports); } }); @@ -26870,7 +27005,6 @@ var ts; if (prop.kind === 193 || name_20.kind === 140) { checkGrammarComputedPropertyName(name_20); - return "continue"; } if (prop.kind === 254 && !inDestructuring && prop.objectAssignmentInitializer) { return { value: grammarErrorOnNode(prop.equalsToken, ts.Diagnostics.can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment) }; @@ -26900,17 +27034,21 @@ var ts; else { ts.Debug.fail("Unexpected syntax kind:" + prop.kind); } - if (!ts.hasProperty(seen, name_20.text)) { - seen[name_20.text] = currentKind; + var effectiveName = ts.getPropertyNameForPropertyNameNode(name_20); + if (effectiveName === undefined) { + return "continue"; + } + if (!ts.hasProperty(seen, effectiveName)) { + seen[effectiveName] = currentKind; } else { - var existingKind = seen[name_20.text]; + var existingKind = seen[effectiveName]; if (currentKind === Property && existingKind === Property) { - return "continue"; + grammarErrorOnNode(name_20, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(name_20)); } else if ((currentKind & GetOrSetAccessor) && (existingKind & GetOrSetAccessor)) { if (existingKind !== GetOrSetAccessor && currentKind !== existingKind) { - seen[name_20.text] = currentKind | existingKind; + seen[effectiveName] = currentKind | existingKind; } else { return { value: grammarErrorOnNode(name_20, ts.Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name) }; @@ -35367,7 +35505,7 @@ var ts; skipTsx: true, traceEnabled: traceEnabled }; - var rootDir = options.typesRoot || (options.configFilePath ? ts.getDirectoryPath(options.configFilePath) : undefined); + var rootDir = options.typesRoot || (options.configFilePath ? ts.getDirectoryPath(options.configFilePath) : (host.getCurrentDirectory && host.getCurrentDirectory())); if (traceEnabled) { if (containingFile === undefined) { if (rootDir === undefined) { @@ -35870,12 +36008,25 @@ var ts; } } } + function getDefaultTypeDirectiveNames(rootPath) { + var localTypes = ts.combinePaths(rootPath, "types"); + var npmTypes = ts.combinePaths(rootPath, "node_modules/@types"); + var result = []; + if (ts.sys.directoryExists(localTypes)) { + result = result.concat(ts.sys.getDirectories(localTypes)); + } + if (ts.sys.directoryExists(npmTypes)) { + result = result.concat(ts.sys.getDirectories(npmTypes)); + } + return result; + } function getDefaultLibLocation() { return ts.getDirectoryPath(ts.normalizePath(ts.sys.getExecutingFilePath())); } var newLine = ts.getNewLineCharacter(options); var realpath = ts.sys.realpath && (function (path) { return ts.sys.realpath(path); }); return { + getDefaultTypeDirectiveNames: getDefaultTypeDirectiveNames, getSourceFile: getSourceFile, getDefaultLibLocation: getDefaultLibLocation, getDefaultLibFileName: function (options) { return ts.combinePaths(getDefaultLibLocation(), ts.getDefaultLibFileName(options)); }, @@ -35943,6 +36094,19 @@ var ts; } return resolutions; } + function getDefaultTypeDirectiveNames(options, rootFiles, host) { + if (options.types) { + return options.types; + } + if (host && host.getDefaultTypeDirectiveNames) { + var commonRoot = computeCommonSourceDirectoryOfFilenames(rootFiles, host.getCurrentDirectory(), function (f) { return host.getCanonicalFileName(f); }); + if (commonRoot) { + return host.getDefaultTypeDirectiveNames(commonRoot); + } + } + return undefined; + } + ts.getDefaultTypeDirectiveNames = getDefaultTypeDirectiveNames; function createProgram(rootNames, options, host, oldProgram) { var program; var files = []; @@ -35978,13 +36142,14 @@ var ts; var filesByName = ts.createFileMap(); var filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? ts.createFileMap(function (fileName) { return fileName.toLowerCase(); }) : undefined; if (!tryReuseStructureFromOldProgram()) { - if (options.types && options.types.length) { - var resolutions = resolveTypeReferenceDirectiveNamesWorker(options.types, undefined); - for (var i = 0; i < options.types.length; i++) { - processTypeReferenceDirective(options.types[i], resolutions[i]); + ts.forEach(rootNames, function (name) { return processRootFile(name, false); }); + var typeReferences = getDefaultTypeDirectiveNames(options, rootNames, host); + if (typeReferences) { + var resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, undefined); + for (var i = 0; i < typeReferences.length; i++) { + processTypeReferenceDirective(typeReferences[i], resolutions[i]); } } - ts.forEach(rootNames, function (name) { return processRootFile(name, false); }); if (!skipDefaultLib) { if (!options.lib) { processRootFile(host.getDefaultLibFileName(options), true); @@ -36561,9 +36726,6 @@ var ts; if (file_1 && options.forceConsistentCasingInFileNames && ts.getNormalizedAbsolutePath(file_1.fileName, currentDirectory) !== ts.getNormalizedAbsolutePath(fileName, currentDirectory)) { reportFileNamesDifferOnlyInCasingError(fileName, file_1.fileName, refFile, refPos, refEnd); } - if (file_1) { - file_1.wasReferenced = file_1.wasReferenced || isReference; - } return file_1; } var file = host.getSourceFile(fileName, options.target, function (hostErrorMessage) { @@ -36576,7 +36738,6 @@ var ts; }); filesByName.set(path, file); if (file) { - file.wasReferenced = file.wasReferenced || isReference; file.path = path; if (host.useCaseSensitiveFileNames()) { var existingFile = filesByNameIgnoreCase.get(path); @@ -36677,17 +36838,7 @@ var ts; !options.noResolve && i < file.imports.length; if (shouldAddFile) { - var importedFile = findSourceFile(resolution.resolvedFileName, ts.toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName), false, false, file, ts.skipTrivia(file.text, file.imports[i].pos), file.imports[i].end); - if (importedFile && resolution.isExternalLibraryImport) { - if (!ts.isExternalModule(importedFile) && importedFile.statements.length) { - var start_5 = ts.getTokenPosOfNode(file.imports[i], file); - fileProcessingDiagnostics.add(ts.createFileDiagnostic(file, start_5, file.imports[i].end - start_5, ts.Diagnostics.Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_the_package_definition, importedFile.fileName)); - } - else if (importedFile.referencedFiles.length) { - var firstRef = importedFile.referencedFiles[0]; - fileProcessingDiagnostics.add(ts.createFileDiagnostic(importedFile, firstRef.pos, firstRef.end - firstRef.pos, ts.Diagnostics.Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_package_author_to_update_the_package_definition)); - } - } + findSourceFile(resolution.resolvedFileName, ts.toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName), false, false, file, ts.skipTrivia(file.text, file.imports[i].pos), file.imports[i].end); } } } @@ -36772,7 +36923,7 @@ var ts; } } else { - programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Substututions_for_pattern_0_should_be_an_array, key)); + programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Substitutions_for_pattern_0_should_be_an_array, key)); } } } @@ -36821,13 +36972,19 @@ var ts; } else if (firstExternalModuleSourceFile && languageVersion < 2 && options.module === ts.ModuleKind.None) { var span = ts.getErrorSpanForNode(firstExternalModuleSourceFile, firstExternalModuleSourceFile.externalModuleIndicator); - programDiagnostics.add(ts.createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_modules_unless_the_module_flag_is_provided_with_a_valid_module_type_Consider_setting_the_module_compiler_option_in_a_tsconfig_json_file)); + programDiagnostics.add(ts.createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none)); } if (options.module === ts.ModuleKind.ES6 && languageVersion < 2) { programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_compile_modules_into_es2015_when_targeting_ES5_or_lower)); } - if (outFile && options.module && !(options.module === ts.ModuleKind.AMD || options.module === ts.ModuleKind.System)) { - programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile")); + if (outFile) { + if (options.module && !(options.module === ts.ModuleKind.AMD || options.module === ts.ModuleKind.System)) { + programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile")); + } + else if (options.module === undefined && firstExternalModuleSourceFile) { + var span = ts.getErrorSpanForNode(firstExternalModuleSourceFile, firstExternalModuleSourceFile.externalModuleIndicator); + programDiagnostics.add(ts.createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system, options.out ? "out" : "outFile")); + } } if (options.outDir || options.sourceRoot || @@ -37517,7 +37674,7 @@ var ts; (function (ts) { var NavigateTo; (function (NavigateTo) { - function getNavigateToItems(program, cancellationToken, searchValue, maxResultCount) { + function getNavigateToItems(program, checker, cancellationToken, searchValue, maxResultCount) { var patternMatcher = ts.createPatternMatcher(searchValue); var rawItems = []; var baseSensitivity = { sensitivity: "base" }; @@ -37550,6 +37707,17 @@ var ts; } } }); + rawItems = ts.filter(rawItems, function (item) { + var decl = item.declaration; + if (decl.kind === 231 || decl.kind === 234 || decl.kind === 229) { + var importer = checker.getSymbolAtLocation(decl.name); + var imported = checker.getAliasedSymbol(importer); + return importer.name !== imported.name; + } + else { + return true; + } + }); rawItems.sort(compareNavigateToItems); if (maxResultCount !== undefined) { rawItems = rawItems.slice(0, maxResultCount); @@ -37892,8 +38060,12 @@ var ts; return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.memberSetAccessorElement); case 153: return createItem(node, "[]", ts.ScriptElementKind.indexSignatureElement); + case 224: + return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.enumElement); case 255: return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.memberVariableElement); + case 222: + return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.interfaceElement); case 151: return createItem(node, "()", ts.ScriptElementKind.callSignatureElement); case 152: @@ -39263,7 +39435,7 @@ var ts; } } function findRightmostChildNodeWithTokens(children, exclusiveStartPosition) { - for (var i = exclusiveStartPosition - 1; i >= 0; --i) { + for (var i = exclusiveStartPosition - 1; i >= 0; i--) { if (nodeHasTokens(children[i])) { return children[i]; } @@ -39889,18 +40061,17 @@ var ts; if (!isStarted) { scanner.scan(); } - var t; var pos = scanner.getStartPos(); while (pos < endPos) { - var t_1 = scanner.getToken(); - if (!ts.isTrivia(t_1)) { + var t = scanner.getToken(); + if (!ts.isTrivia(t)) { break; } scanner.scan(); var item = { pos: pos, end: scanner.getStartPos(), - kind: t_1 + kind: t }; pos = scanner.getStartPos(); if (!leadingTrivia) { @@ -41550,7 +41721,7 @@ var ts; else { parts = []; var startPos = commentRange.pos; - for (var line = startLine; line < endLine; ++line) { + for (var line = startLine; line < endLine; line++) { var endOfLine = ts.getEndLinePosition(line, sourceFile); parts.push({ pos: startPos, end: endOfLine }); startPos = ts.getStartPositionOfLine(line + 1, sourceFile); @@ -41568,7 +41739,7 @@ var ts; startLine++; } var delta = indentation - nonWhitespaceColumnInFirstPart.column; - for (var i = startIndex, len = parts.length; i < len; ++i, ++startLine) { + for (var i = startIndex, len = parts.length; i < len; i++, startLine++) { var startLinePos_1 = ts.getStartPositionOfLine(startLine, sourceFile); var nonWhitespaceCharacterAndColumn = i === 0 ? nonWhitespaceColumnInFirstPart @@ -41584,7 +41755,7 @@ var ts; } } function trimTrailingWhitespacesForLines(line1, line2, range) { - for (var line = line1; line < line2; ++line) { + for (var line = line1; line < line2; line++) { var lineStartPosition = ts.getStartPositionOfLine(line, sourceFile); var lineEndPosition = ts.getEndLinePosition(line, sourceFile); if (range && (ts.isComment(range.kind) || ts.isStringOrRegularExpressionOrTemplateLiteral(range.kind)) && range.pos <= lineEndPosition && range.end > lineEndPosition) { @@ -41627,7 +41798,6 @@ var ts; } } function applyRuleEdits(rule, previousRange, previousStartLine, currentRange, currentStartLine) { - var between; switch (rule.Operation.Action) { case 1: return; @@ -41657,14 +41827,6 @@ var ts; } } } - function isSomeBlock(kind) { - switch (kind) { - case 199: - case 226: - return true; - } - return false; - } function getOpenTokenForList(node, list) { switch (node.kind) { case 148: @@ -41722,7 +41884,7 @@ var ts; internedTabsIndentation = []; } if (internedTabsIndentation[tabs] === undefined) { - internedTabsIndentation[tabs] = tabString = repeat('\t', tabs); + internedTabsIndentation[tabs] = tabString = repeat("\t", tabs); } else { tabString = internedTabsIndentation[tabs]; @@ -41747,7 +41909,7 @@ var ts; } function repeat(value, count) { var s = ""; - for (var i = 0; i < count; ++i) { + for (var i = 0; i < count; i++) { s += value; } return s; @@ -42015,7 +42177,7 @@ var ts; ts.Debug.assert(index >= 0 && index < list.length); var node = list[index]; var lineAndCharacter = getStartLineAndCharacterForNode(node, sourceFile); - for (var i = index - 1; i >= 0; --i) { + for (var i = index - 1; i >= 0; i--) { if (list[i].kind === 24) { continue; } @@ -42034,7 +42196,7 @@ var ts; function findFirstNonWhitespaceCharacterAndColumn(startPos, endPos, sourceFile, options) { var character = 0; var column = 0; - for (var pos = startPos; pos < endPos; ++pos) { + for (var pos = startPos; pos < endPos; pos++) { var ch = sourceFile.text.charCodeAt(pos); if (!ts.isWhiteSpace(ch)) { break; @@ -44005,9 +44167,9 @@ var ts; log("getCompletionData: Get previous token 1: " + (new Date().getTime() - start)); var contextToken = previousToken; if (contextToken && position <= contextToken.end && ts.isWord(contextToken.kind)) { - var start_6 = new Date().getTime(); + var start_5 = new Date().getTime(); contextToken = ts.findPrecedingToken(contextToken.getFullStart(), sourceFile); - log("getCompletionData: Get previous token 2: " + (new Date().getTime() - start_6)); + log("getCompletionData: Get previous token 2: " + (new Date().getTime() - start_5)); } var node = currentToken; var isRightOfDot = false; @@ -44234,9 +44396,9 @@ var ts; || contextToken.kind === 166 || contextToken.kind === 10 || ts.isTemplateLiteralKind(contextToken.kind)) { - var start_7 = contextToken.getStart(); + var start_6 = contextToken.getStart(); var end = contextToken.getEnd(); - if (start_7 < position && position < end) { + if (start_6 < position && position < end) { return true; } if (position === end) { @@ -45314,8 +45476,7 @@ var ts; } function getDocumentHighlights(fileName, position, filesToSearch) { synchronizeHostData(); - filesToSearch = ts.map(filesToSearch, ts.normalizeSlashes); - var sourceFilesToSearch = ts.filter(program.getSourceFiles(), function (f) { return ts.contains(filesToSearch, f.fileName); }); + var sourceFilesToSearch = ts.map(filesToSearch, function (f) { return program.getSourceFile(f); }); var sourceFile = getValidSourceFile(fileName); var node = ts.getTouchingWord(sourceFile, position); if (!node) { @@ -46498,7 +46659,8 @@ var ts; } function getNavigateToItems(searchValue, maxResultCount) { synchronizeHostData(); - return ts.NavigateTo.getNavigateToItems(program, cancellationToken, searchValue, maxResultCount); + var checker = getProgram().getTypeChecker(); + return ts.NavigateTo.getNavigateToItems(program, checker, cancellationToken, searchValue, maxResultCount); } function getEmitOutput(fileName) { synchronizeHostData(); @@ -51195,6 +51357,9 @@ var ts; LanguageServiceShimHostAdapter.prototype.getCurrentDirectory = function () { return this.shimHost.getCurrentDirectory(); }; + LanguageServiceShimHostAdapter.prototype.getDirectories = function (path) { + return this.shimHost.getDirectories(path); + }; LanguageServiceShimHostAdapter.prototype.getDefaultLibFileName = function (options) { return this.shimHost.getDefaultLibFileName(JSON.stringify(options)); }; diff --git a/lib/tsserverlibrary.d.ts b/lib/tsserverlibrary.d.ts index 0629ad983a3..76b66dda93b 100644 --- a/lib/tsserverlibrary.d.ts +++ b/lib/tsserverlibrary.d.ts @@ -247,7 +247,7 @@ declare namespace ts { ModuleDeclaration = 225, ModuleBlock = 226, CaseBlock = 227, - GlobalModuleExportDeclaration = 228, + NamespaceExportDeclaration = 228, ImportEqualsDeclaration = 229, ImportDeclaration = 230, ImportClause = 231, @@ -925,7 +925,7 @@ declare namespace ts { interface NamespaceImport extends Declaration { name: Identifier; } - interface GlobalModuleExportDeclaration extends DeclarationStatement { + interface NamespaceExportDeclaration extends DeclarationStatement { name: Identifier; moduleReference: LiteralLikeNode; } @@ -1087,7 +1087,6 @@ declare namespace ts { scriptKind: ScriptKind; externalModuleIndicator: Node; commonJsModuleIndicator: Node; - wasReferenced?: boolean; identifiers: Map; nodeCount: number; identifierCount: number; @@ -1381,7 +1380,7 @@ declare namespace ts { FunctionScopedVariableExcludes = 107454, BlockScopedVariableExcludes = 107455, ParameterExcludes = 107455, - PropertyExcludes = 107455, + PropertyExcludes = 0, EnumMemberExcludes = 107455, FunctionExcludes = 106927, ClassExcludes = 899519, @@ -1735,6 +1734,7 @@ declare namespace ts { allowJs?: boolean; noImplicitUseStrict?: boolean; strictNullChecks?: boolean; + skipLibCheck?: boolean; listEmittedFiles?: boolean; lib?: string[]; stripInternal?: boolean; @@ -1967,6 +1967,7 @@ declare namespace ts { trace?(s: string): void; directoryExists?(directoryName: string): boolean; realpath?(path: string): string; + getCurrentDirectory?(): string; } interface ResolvedModule { resolvedFileName: string; @@ -1990,6 +1991,7 @@ declare namespace ts { getCancellationToken?(): CancellationToken; getDefaultLibFileName(options: CompilerOptions): string; getDefaultLibLocation?(): string; + getDefaultTypeDirectiveNames?(rootPath: string): string[]; writeFile: WriteFileCallback; getCurrentDirectory(): string; getCanonicalFileName(fileName: string): string; @@ -2136,6 +2138,7 @@ declare namespace ts { createDirectory(path: string): void; getExecutingFilePath(): string; getCurrentDirectory(): string; + getDirectories(path: string): string[]; readDirectory(path: string, extension?: string, exclude?: string[]): string[]; getModifiedTime?(path: string): Date; createHash?(data: string): string; @@ -2820,7 +2823,7 @@ declare namespace ts { key: string; message: string; }; - Cannot_compile_modules_unless_the_module_flag_is_provided_with_a_valid_module_type_Consider_setting_the_module_compiler_option_in_a_tsconfig_json_file: { + Cannot_use_imports_exports_or_module_augmentations_when_module_is_none: { code: number; category: DiagnosticCategory; key: string; @@ -5040,6 +5043,18 @@ declare namespace ts { key: string; message: string; }; + Identifier_0_must_be_imported_from_a_module: { + code: number; + category: DiagnosticCategory; + key: string; + message: string; + }; + All_declarations_of_0_must_have_identical_modifiers: { + code: number; + category: DiagnosticCategory; + key: string; + message: string; + }; Import_declaration_0_is_using_private_name_1: { code: number; category: DiagnosticCategory; @@ -5598,7 +5613,7 @@ declare namespace ts { key: string; message: string; }; - Substututions_for_pattern_0_should_be_an_array: { + Substitutions_for_pattern_0_should_be_an_array: { code: number; category: DiagnosticCategory; key: string; @@ -5676,6 +5691,12 @@ declare namespace ts { key: string; message: string; }; + Skip_type_checking_of_declaration_files: { + code: number; + category: DiagnosticCategory; + key: string; + message: string; + }; Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015: { code: number; category: DiagnosticCategory; @@ -6282,6 +6303,12 @@ declare namespace ts { key: string; message: string; }; + Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system: { + code: number; + category: DiagnosticCategory; + key: string; + message: string; + }; Variable_0_implicitly_has_an_1_type: { code: number; category: DiagnosticCategory; @@ -7024,6 +7051,7 @@ declare namespace ts { function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost; function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; function flattenDiagnosticMessageText(messageText: string | DiagnosticMessageChain, newLine: string): string; + function getDefaultTypeDirectiveNames(options: CompilerOptions, rootFiles: string[], host: CompilerHost): string[]; function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program; } declare namespace ts.BreakpointResolver { @@ -7033,7 +7061,7 @@ declare namespace ts.OutliningElementsCollector { function collectElements(sourceFile: SourceFile): OutliningSpan[]; } declare namespace ts.NavigateTo { - function getNavigateToItems(program: Program, cancellationToken: CancellationToken, searchValue: string, maxResultCount: number): NavigateToItem[]; + function getNavigateToItems(program: Program, checker: TypeChecker, cancellationToken: CancellationToken, searchValue: string, maxResultCount: number): NavigateToItem[]; } declare namespace ts.NavigationBar { function getNavigationBarItems(sourceFile: SourceFile, compilerOptions: CompilerOptions): ts.NavigationBarItem[]; @@ -7431,7 +7459,7 @@ declare namespace ts.formatting { } } declare namespace ts.formatting { - module Shared { + namespace Shared { interface ITokenAccess { GetTokens(): SyntaxKind[]; Contains(token: SyntaxKind): boolean; @@ -7516,7 +7544,7 @@ declare namespace ts.formatting { function getIndentationString(indentation: number, options: FormatCodeOptions): string; } declare namespace ts.formatting { - module SmartIndenter { + namespace SmartIndenter { function getIndentation(position: number, sourceFile: SourceFile, options: EditorOptions): number; function getIndentationForNode(n: Node, ignoreActualIndentationRange: TextRange, sourceFile: SourceFile, options: FormatCodeOptions): number; function childStartsOnTheSameLineWithElseInIfStatement(parent: Node, child: TextRangeWithKind, childStartLine: number, sourceFile: SourceFile): boolean; @@ -8487,6 +8515,7 @@ declare namespace ts { getLocalizedDiagnosticMessages(): string; getCancellationToken(): HostCancellationToken; getCurrentDirectory(): string; + getDirectories(path: string): string[]; getDefaultLibFileName(options: string): string; getNewLine?(): string; getProjectVersion?(): string; @@ -8582,6 +8611,7 @@ declare namespace ts { getLocalizedDiagnosticMessages(): any; getCancellationToken(): HostCancellationToken; getCurrentDirectory(): string; + getDirectories(path: string): string[]; getDefaultLibFileName(options: CompilerOptions): string; } class CoreServicesShimHostAdapter implements ParseConfigHost, ModuleResolutionHost { diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js index 050d9ca265d..f16d02e472c 100644 --- a/lib/tsserverlibrary.js +++ b/lib/tsserverlibrary.js @@ -918,6 +918,10 @@ var ts; } return result.sort(); } + function getDirectories(path) { + var folder = fso.GetFolder(path); + return getNames(folder.subfolders); + } function readDirectory(path, extension, exclude) { var result = []; exclude = ts.map(exclude, function (s) { return getCanonicalPath(ts.combinePaths(path, s)); }); @@ -972,6 +976,7 @@ var ts; getCurrentDirectory: function () { return new ActiveXObject("WScript.Shell").CurrentDirectory; }, + getDirectories: getDirectories, readDirectory: readDirectory, exit: function (exitCode) { try { @@ -1119,6 +1124,9 @@ var ts; function directoryExists(path) { return fileSystemEntryExists(path, 1); } + function getDirectories(path) { + return ts.filter(_fs.readdirSync(path), function (p) { return fileSystemEntryExists(ts.combinePaths(path, p), 1); }); + } function readDirectory(path, extension, exclude) { var result = []; exclude = ts.map(exclude, function (s) { return getCanonicalPath(ts.combinePaths(path, s)); }); @@ -1211,6 +1219,7 @@ var ts; getCurrentDirectory: function () { return process.cwd(); }, + getDirectories: getDirectories, readDirectory: readDirectory, getModifiedTime: function (path) { try { @@ -1261,6 +1270,7 @@ var ts; createDirectory: ChakraHost.createDirectory, getExecutingFilePath: function () { return ChakraHost.executingFile; }, getCurrentDirectory: function () { return ChakraHost.currentDirectory; }, + getDirectories: ChakraHost.getDirectories, readDirectory: ChakraHost.readDirectory, exit: ChakraHost.quit, realpath: realpath @@ -1394,7 +1404,7 @@ var ts; or_expected: { code: 1144, category: ts.DiagnosticCategory.Error, key: "or_expected_1144", message: "'{' or ';' expected." }, Declaration_expected: { code: 1146, category: ts.DiagnosticCategory.Error, key: "Declaration_expected_1146", message: "Declaration expected." }, Import_declarations_in_a_namespace_cannot_reference_a_module: { code: 1147, category: ts.DiagnosticCategory.Error, key: "Import_declarations_in_a_namespace_cannot_reference_a_module_1147", message: "Import declarations in a namespace cannot reference a module." }, - Cannot_compile_modules_unless_the_module_flag_is_provided_with_a_valid_module_type_Consider_setting_the_module_compiler_option_in_a_tsconfig_json_file: { code: 1148, category: ts.DiagnosticCategory.Error, key: "Cannot_compile_modules_unless_the_module_flag_is_provided_with_a_valid_module_type_Consider_setting__1148", message: "Cannot compile modules unless the '--module' flag is provided with a valid module type. Consider setting the 'module' compiler option in a 'tsconfig.json' file." }, + Cannot_use_imports_exports_or_module_augmentations_when_module_is_none: { code: 1148, category: ts.DiagnosticCategory.Error, key: "Cannot_use_imports_exports_or_module_augmentations_when_module_is_none_1148", message: "Cannot use imports, exports, or module augmentations when '--module' is 'none'." }, File_name_0_differs_from_already_included_file_name_1_only_in_casing: { code: 1149, category: ts.DiagnosticCategory.Error, key: "File_name_0_differs_from_already_included_file_name_1_only_in_casing_1149", message: "File name '{0}' differs from already included file name '{1}' only in casing" }, new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead: { code: 1150, category: ts.DiagnosticCategory.Error, key: "new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead_1150", message: "'new T[]' cannot be used to create an array. Use 'new Array()' instead." }, const_declarations_must_be_initialized: { code: 1155, category: ts.DiagnosticCategory.Error, key: "const_declarations_must_be_initialized_1155", message: "'const' declarations must be initialized" }, @@ -1764,6 +1774,8 @@ var ts; this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation: { code: 2683, category: ts.DiagnosticCategory.Error, key: "this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_2683", message: "'this' implicitly has type 'any' because it does not have a type annotation." }, The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1: { code: 2684, category: ts.DiagnosticCategory.Error, key: "The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1_2684", message: "The 'this' context of type '{0}' is not assignable to method's 'this' of type '{1}'." }, The_this_types_of_each_signature_are_incompatible: { code: 2685, category: ts.DiagnosticCategory.Error, key: "The_this_types_of_each_signature_are_incompatible_2685", message: "The 'this' types of each signature are incompatible." }, + Identifier_0_must_be_imported_from_a_module: { code: 2686, category: ts.DiagnosticCategory.Error, key: "Identifier_0_must_be_imported_from_a_module_2686", message: "Identifier '{0}' must be imported from a module" }, + All_declarations_of_0_must_have_identical_modifiers: { code: 2687, category: ts.DiagnosticCategory.Error, key: "All_declarations_of_0_must_have_identical_modifiers_2687", message: "All declarations of '{0}' must have identical modifiers." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: ts.DiagnosticCategory.Error, key: "Import_declaration_0_is_using_private_name_1_4000", message: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: ts.DiagnosticCategory.Error, key: "Type_parameter_0_of_exported_class_has_or_is_using_private_name_1_4002", message: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: ts.DiagnosticCategory.Error, key: "Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1_4004", message: "Type parameter '{0}' of exported interface has or is using private name '{1}'." }, @@ -1857,7 +1869,7 @@ var ts; Option_paths_cannot_be_used_without_specifying_baseUrl_option: { code: 5060, category: ts.DiagnosticCategory.Error, key: "Option_paths_cannot_be_used_without_specifying_baseUrl_option_5060", message: "Option 'paths' cannot be used without specifying '--baseUrl' option." }, Pattern_0_can_have_at_most_one_Asterisk_character: { code: 5061, category: ts.DiagnosticCategory.Error, key: "Pattern_0_can_have_at_most_one_Asterisk_character_5061", message: "Pattern '{0}' can have at most one '*' character" }, Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character: { code: 5062, category: ts.DiagnosticCategory.Error, key: "Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character_5062", message: "Substitution '{0}' in pattern '{1}' in can have at most one '*' character" }, - Substututions_for_pattern_0_should_be_an_array: { code: 5063, category: ts.DiagnosticCategory.Error, key: "Substututions_for_pattern_0_should_be_an_array_5063", message: "Substututions for pattern '{0}' should be an array." }, + Substitutions_for_pattern_0_should_be_an_array: { code: 5063, category: ts.DiagnosticCategory.Error, key: "Substitutions_for_pattern_0_should_be_an_array_5063", message: "Substitutions for pattern '{0}' should be an array." }, Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2: { code: 5064, category: ts.DiagnosticCategory.Error, key: "Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2_5064", message: "Substitution '{0}' for pattern '{1}' has incorrect type, expected 'string', got '{2}'." }, Concatenate_and_emit_output_to_single_file: { code: 6001, category: ts.DiagnosticCategory.Message, key: "Concatenate_and_emit_output_to_single_file_6001", message: "Concatenate and emit output to single file." }, Generates_corresponding_d_ts_file: { code: 6002, category: ts.DiagnosticCategory.Message, key: "Generates_corresponding_d_ts_file_6002", message: "Generates corresponding '.d.ts' file." }, @@ -1870,6 +1882,7 @@ var ts; Do_not_emit_comments_to_output: { code: 6009, category: ts.DiagnosticCategory.Message, key: "Do_not_emit_comments_to_output_6009", message: "Do not emit comments to output." }, Do_not_emit_outputs: { code: 6010, category: ts.DiagnosticCategory.Message, key: "Do_not_emit_outputs_6010", message: "Do not emit outputs." }, Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking: { code: 6011, category: ts.DiagnosticCategory.Message, key: "Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011", message: "Allow default imports from modules with no default export. This does not affect code emit, just typechecking." }, + Skip_type_checking_of_declaration_files: { code: 6012, category: ts.DiagnosticCategory.Message, key: "Skip_type_checking_of_declaration_files_6012", message: "Skip type checking of declaration files." }, Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015: { code: 6015, category: ts.DiagnosticCategory.Message, key: "Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015_6015", message: "Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES2015'" }, Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015: { code: 6016, category: ts.DiagnosticCategory.Message, key: "Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015_6016", message: "Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'" }, Print_this_message: { code: 6017, category: ts.DiagnosticCategory.Message, key: "Print_this_message_6017", message: "Print this message." }, @@ -1971,6 +1984,7 @@ var ts; Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set: { code: 6128, category: ts.DiagnosticCategory.Message, key: "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set_6128", message: "======== Resolving type reference directive '{0}', containing file not set, root directory not set. ========" }, The_config_file_0_found_doesn_t_contain_any_source_files: { code: 6129, category: ts.DiagnosticCategory.Error, key: "The_config_file_0_found_doesn_t_contain_any_source_files_6129", message: "The config file '{0}' found doesn't contain any source files." }, Resolving_real_path_for_0_result_1: { code: 6130, category: ts.DiagnosticCategory.Message, key: "Resolving_real_path_for_0_result_1_6130", message: "Resolving real path for '{0}', result '{1}'" }, + Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system: { code: 6131, category: ts.DiagnosticCategory.Error, key: "Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system_6131", message: "Cannot compile modules using option '{0}' unless the '--module' flag is 'amd' or 'system'." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable_0_implicitly_has_an_1_type_7005", message: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter_0_implicitly_has_an_1_type_7006", message: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member_0_implicitly_has_an_1_type_7008", message: "Member '{0}' implicitly has an '{1}' type." }, @@ -3537,6 +3551,11 @@ var ts; type: "boolean", description: ts.Diagnostics.Print_this_message }, + { + name: "help", + shortName: "?", + type: "boolean" + }, { name: "init", type: "boolean", @@ -3639,6 +3658,11 @@ var ts; name: "skipDefaultLibCheck", type: "boolean" }, + { + name: "skipLibCheck", + type: "boolean", + description: ts.Diagnostics.Skip_type_checking_of_declaration_files + }, { name: "out", type: "string", @@ -5758,7 +5782,7 @@ var ts; } ts.isWellKnownSymbolSyntactically = isWellKnownSymbolSyntactically; function getPropertyNameForPropertyNameNode(name) { - if (name.kind === 69 || name.kind === 9 || name.kind === 8) { + if (name.kind === 69 || name.kind === 9 || name.kind === 8 || name.kind === 142) { return name.text; } if (name.kind === 140) { @@ -12804,10 +12828,10 @@ var ts; case 145: case 144: case 266: - return bindPropertyOrMethodOrAccessor(node, 4 | (node.questionToken ? 536870912 : 0), 107455); + return bindPropertyOrMethodOrAccessor(node, 4 | (node.questionToken ? 536870912 : 0), 0); case 253: case 254: - return bindPropertyOrMethodOrAccessor(node, 4, 107455); + return bindPropertyOrMethodOrAccessor(node, 4, 0); case 255: return bindPropertyOrMethodOrAccessor(node, 8, 107455); case 247: @@ -12819,7 +12843,7 @@ var ts; return declareSymbolAndAddToSymbolTable(node, 131072, 0); case 147: case 146: - return bindPropertyOrMethodOrAccessor(node, 8192 | (node.questionToken ? 536870912 : 0), ts.isObjectLiteralMethod(node) ? 107455 : 99263); + return bindPropertyOrMethodOrAccessor(node, 8192 | (node.questionToken ? 536870912 : 0), ts.isObjectLiteralMethod(node) ? 0 : 99263); case 220: return bindFunctionDeclaration(node); case 148: @@ -12862,7 +12886,7 @@ var ts; case 238: return declareSymbolAndAddToSymbolTable(node, 8388608, 8388608); case 228: - return bindGlobalModuleExportDeclaration(node); + return bindNamespaceExportDeclaration(node); case 231: return bindImportClause(node); case 236: @@ -12898,13 +12922,13 @@ var ts; bindAnonymousDeclaration(node, 8388608, getDeclarationName(node)); } else if (boundExpression.kind === 69 && node.kind === 235) { - declareSymbol(container.symbol.exports, container.symbol, node, 8388608, 107455 | 8388608); + declareSymbol(container.symbol.exports, container.symbol, node, 8388608, 0 | 8388608); } else { - declareSymbol(container.symbol.exports, container.symbol, node, 4, 107455 | 8388608); + declareSymbol(container.symbol.exports, container.symbol, node, 4, 0 | 8388608); } } - function bindGlobalModuleExportDeclaration(node) { + function bindNamespaceExportDeclaration(node) { if (node.modifiers && node.modifiers.length) { file.bindDiagnostics.push(ts.createDiagnosticForNode(node, ts.Diagnostics.Modifiers_cannot_appear_here)); } @@ -12956,7 +12980,7 @@ var ts; function bindThisPropertyAssignment(node) { if (container.kind === 179 || container.kind === 220) { container.symbol.members = container.symbol.members || {}; - declareSymbol(container.symbol.members, container.symbol, node, 4, 107455 & ~4); + declareSymbol(container.symbol.members, container.symbol, node, 4, 0 & ~4); } } function bindPrototypePropertyAssignment(node) { @@ -12973,7 +12997,7 @@ var ts; if (!funcSymbol.members) { funcSymbol.members = {}; } - declareSymbol(funcSymbol.members, funcSymbol, leftSideOfAssignment, 4, 107455); + declareSymbol(funcSymbol.members, funcSymbol, leftSideOfAssignment, 4, 0); } function bindCallExpression(node) { if (!file.commonJsModuleIndicator && ts.isRequireCall(node, false)) { @@ -13049,7 +13073,7 @@ var ts; } if (ts.isParameterPropertyDeclaration(node)) { var classDeclaration = node.parent.parent; - declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4, 107455); + declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4, 0); } } function bindFunctionDeclaration(node) { @@ -13349,7 +13373,7 @@ var ts; if (flags & 1) result |= 107454; if (flags & 4) - result |= 107455; + result |= 0; if (flags & 8) result |= 107455; if (flags & 16) @@ -13605,6 +13629,7 @@ var ts; var propertyWithInvalidInitializer; var errorLocation = location; var grandparent; + var isInExternalModule = false; loop: while (location) { if (location.locals && !isGlobalSourceFile(location)) { if (result = getSymbol(location.locals, name, meaning)) { @@ -13636,6 +13661,7 @@ var ts; case 256: if (!ts.isExternalOrCommonJsModule(location)) break; + isInExternalModule = true; case 225: var moduleExports = getSymbolOfNode(location).exports; if (location.kind === 256 || ts.isAmbientModule(location)) { @@ -13759,6 +13785,12 @@ var ts; checkResolvedBlockScopedVariable(exportOrLocalSymbol, errorLocation); } } + if (result && isInExternalModule) { + var decls = result.declarations; + if (decls && decls.length === 1 && decls[0].kind === 228) { + error(errorLocation, ts.Diagnostics.Identifier_0_must_be_imported_from_a_module, name); + } + } } return result; } @@ -15234,7 +15266,7 @@ var ts; } function getTypeForBindingElementParent(node) { var symbol = getSymbolOfNode(node); - return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node); + return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node, false); } function getTextOfPropertyName(name) { switch (name.kind) { @@ -15339,7 +15371,7 @@ var ts; function addOptionality(type, optional) { return strictNullChecks && optional ? addNullableKind(type, 32) : type; } - function getTypeForVariableLikeDeclaration(declaration) { + function getTypeForVariableLikeDeclaration(declaration, includeOptionality) { if (declaration.flags & 134217728) { var type = getTypeForVariableLikeDeclarationFromJSDocComment(declaration); if (type && type !== unknownType) { @@ -15356,7 +15388,7 @@ var ts; return getTypeForBindingElement(declaration); } if (declaration.type) { - return addOptionality(getTypeFromTypeNode(declaration.type), !!declaration.questionToken); + return addOptionality(getTypeFromTypeNode(declaration.type), declaration.questionToken && includeOptionality); } if (declaration.kind === 142) { var func = declaration.parent; @@ -15375,11 +15407,11 @@ var ts; ? getContextuallyTypedThisType(func) : getContextuallyTypedParameterType(declaration); if (type) { - return addOptionality(type, !!declaration.questionToken); + return addOptionality(type, declaration.questionToken && includeOptionality); } } if (declaration.initializer) { - return addOptionality(checkExpressionCached(declaration.initializer), !!declaration.questionToken); + return addOptionality(checkExpressionCached(declaration.initializer), declaration.questionToken && includeOptionality); } if (declaration.kind === 254) { return checkIdentifier(declaration.name); @@ -15447,7 +15479,7 @@ var ts; : getTypeFromArrayBindingPattern(pattern, includePatternInType); } function getWidenedTypeForVariableLikeDeclaration(declaration, reportErrors) { - var type = getTypeForVariableLikeDeclaration(declaration); + var type = getTypeForVariableLikeDeclaration(declaration, true); if (type) { if (reportErrors) { reportErrorsFromWidening(declaration, type); @@ -17764,7 +17796,7 @@ var ts; return isIdenticalTo(source, target); } if (!(target.flags & 134217728)) { - if (target.flags & 1) + if (target.flags & 1 || source.flags & 134217728) return -1; if (source.flags & 32) { if (!strictNullChecks || target.flags & (32 | 16) || source === emptyArrayElementType) @@ -17784,7 +17816,7 @@ var ts; if (source.flags & 256 && target === stringType) return -1; if (relation === assignableRelation || relation === comparableRelation) { - if (source.flags & (1 | 134217728)) + if (source.flags & 1) return -1; if (source === numberType && target.flags & 128) return -1; @@ -18561,41 +18593,47 @@ var ts; getSignaturesOfType(type, 0).length === 0 && getSignaturesOfType(type, 1).length === 0; } + function createTransientSymbol(source, type) { + var symbol = createSymbol(source.flags | 67108864, source.name); + symbol.declarations = source.declarations; + symbol.parent = source.parent; + symbol.type = type; + symbol.target = source; + if (source.valueDeclaration) { + symbol.valueDeclaration = source.valueDeclaration; + } + return symbol; + } + function transformTypeOfMembers(type, f) { + var members = {}; + for (var _i = 0, _a = getPropertiesOfObjectType(type); _i < _a.length; _i++) { + var property = _a[_i]; + var original = getTypeOfSymbol(property); + var updated = f(original); + members[property.name] = updated === original ? property : createTransientSymbol(property, updated); + } + ; + return members; + } function getRegularTypeOfObjectLiteral(type) { - if (type.flags & 1048576) { - var regularType = type.regularType; - if (!regularType) { - regularType = createType(type.flags & ~1048576); - regularType.symbol = type.symbol; - regularType.members = type.members; - regularType.properties = type.properties; - regularType.callSignatures = type.callSignatures; - regularType.constructSignatures = type.constructSignatures; - regularType.stringIndexInfo = type.stringIndexInfo; - regularType.numberIndexInfo = type.numberIndexInfo; - type.regularType = regularType; - } + if (!(type.flags & 1048576)) { + return type; + } + var regularType = type.regularType; + if (regularType) { return regularType; } - return type; + var resolved = type; + var members = transformTypeOfMembers(type, getRegularTypeOfObjectLiteral); + var regularNew = createAnonymousType(resolved.symbol, members, resolved.callSignatures, resolved.constructSignatures, resolved.stringIndexInfo, resolved.numberIndexInfo); + regularNew.flags = resolved.flags & ~1048576; + type.regularType = regularNew; + return regularNew; } function getWidenedTypeOfObjectLiteral(type) { - var properties = getPropertiesOfObjectType(type); - var members = {}; - ts.forEach(properties, function (p) { - var propType = getTypeOfSymbol(p); - var widenedType = getWidenedType(propType); - if (propType !== widenedType) { - var symbol = createSymbol(p.flags | 67108864, p.name); - symbol.declarations = p.declarations; - symbol.parent = p.parent; - symbol.type = widenedType; - symbol.target = p; - if (p.valueDeclaration) - symbol.valueDeclaration = p.valueDeclaration; - p = symbol; - } - members[p.name] = p; + var members = transformTypeOfMembers(type, function (prop) { + var widened = getWidenedType(prop); + return prop === widened ? prop : widened; }); var stringIndexInfo = getIndexInfoOfType(type, 0); var numberIndexInfo = getIndexInfoOfType(type, 1); @@ -18816,7 +18854,7 @@ var ts; inferFromTypes(source, t); } } - if (target.flags & 16384 && typeParameterCount === 1) { + if (typeParameterCount === 1) { inferiority++; inferFromTypes(source, typeParameter); inferiority--; @@ -19888,7 +19926,7 @@ var ts; } return nodeCheckFlag === 512 ? getBaseConstructorTypeOfClass(classType) - : baseClassType; + : getTypeWithThisArgument(baseClassType, classType.thisType); function isLegalUsageOfSuperExpression(container) { if (!container) { return false; @@ -21936,7 +21974,7 @@ var ts; var types = void 0; var funcIsGenerator = !!func.asteriskToken; if (funcIsGenerator) { - types = checkAndAggregateYieldOperandTypes(func.body, contextualMapper); + types = checkAndAggregateYieldOperandTypes(func, contextualMapper); if (types.length === 0) { var iterableIteratorAny = createIterableIteratorType(anyType); if (compilerOptions.noImplicitAny) { @@ -21946,8 +21984,7 @@ var ts; } } else { - var hasImplicitReturn = !!(func.flags & 32768); - types = checkAndAggregateReturnExpressionTypes(func.body, contextualMapper, isAsync, hasImplicitReturn); + types = checkAndAggregateReturnExpressionTypes(func, contextualMapper); if (!types) { return neverType; } @@ -21994,9 +22031,9 @@ var ts; return widenedType; } } - function checkAndAggregateYieldOperandTypes(body, contextualMapper) { + function checkAndAggregateYieldOperandTypes(func, contextualMapper) { var aggregatedTypes = []; - ts.forEachYieldExpression(body, function (yieldExpression) { + ts.forEachYieldExpression(func.body, function (yieldExpression) { var expr = yieldExpression.expression; if (expr) { var type = checkExpressionCached(expr, contextualMapper); @@ -22010,28 +22047,34 @@ var ts; }); return aggregatedTypes; } - function checkAndAggregateReturnExpressionTypes(body, contextualMapper, isAsync, hasImplicitReturn) { + function checkAndAggregateReturnExpressionTypes(func, contextualMapper) { + var isAsync = ts.isAsyncFunctionLike(func); var aggregatedTypes = []; - var hasOmittedExpressions = false; - ts.forEachReturnStatement(body, function (returnStatement) { + var hasReturnWithNoExpression = !!(func.flags & 32768); + var hasReturnOfTypeNever = false; + ts.forEachReturnStatement(func.body, function (returnStatement) { var expr = returnStatement.expression; if (expr) { var type = checkExpressionCached(expr, contextualMapper); if (isAsync) { - type = checkAwaitedType(type, body.parent, ts.Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member); + type = checkAwaitedType(type, func, ts.Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member); } - if (type !== neverType && !ts.contains(aggregatedTypes, type)) { + if (type === neverType) { + hasReturnOfTypeNever = true; + } + else if (!ts.contains(aggregatedTypes, type)) { aggregatedTypes.push(type); } } else { - hasOmittedExpressions = true; + hasReturnWithNoExpression = true; } }); - if (aggregatedTypes.length === 0 && !hasOmittedExpressions && !hasImplicitReturn) { + if (aggregatedTypes.length === 0 && !hasReturnWithNoExpression && (hasReturnOfTypeNever || + func.kind === 179 || func.kind === 180)) { return undefined; } - if (strictNullChecks && aggregatedTypes.length && (hasOmittedExpressions || hasImplicitReturn)) { + if (strictNullChecks && aggregatedTypes.length && hasReturnWithNoExpression) { if (!ts.contains(aggregatedTypes, undefinedType)) { aggregatedTypes.push(undefinedType); } @@ -22161,7 +22204,9 @@ var ts; (expr.kind === 172 || expr.kind === 173) && expr.expression.kind === 97) { var func = ts.getContainingFunction(expr); - return !(func && func.kind === 148 && func.parent === symbol.valueDeclaration.parent); + if (!(func && func.kind === 148)) + return true; + return !(func.parent === symbol.valueDeclaration.parent || func === symbol.valueDeclaration.parent); } return true; } @@ -22985,6 +23030,79 @@ var ts; } } } + function checkClassForDuplicateDeclarations(node) { + var getter = 1, setter = 2, property = getter | setter; + var instanceNames = {}; + var staticNames = {}; + for (var _i = 0, _a = node.members; _i < _a.length; _i++) { + var member = _a[_i]; + if (member.kind === 148) { + for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) { + var param = _c[_b]; + if (ts.isParameterPropertyDeclaration(param)) { + addName(instanceNames, param.name, param.name.text, property); + } + } + } + else { + var static = ts.forEach(member.modifiers, function (m) { return m.kind === 113; }); + var names = static ? staticNames : instanceNames; + var memberName = member.name && ts.getPropertyNameForPropertyNameNode(member.name); + if (memberName) { + switch (member.kind) { + case 149: + addName(names, member.name, memberName, getter); + break; + case 150: + addName(names, member.name, memberName, setter); + break; + case 145: + addName(names, member.name, memberName, property); + break; + } + } + } + } + function addName(names, location, name, meaning) { + if (ts.hasProperty(names, name)) { + var prev = names[name]; + if (prev & meaning) { + error(location, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(location)); + } + else { + names[name] = prev | meaning; + } + } + else { + names[name] = meaning; + } + } + } + function checkObjectTypeForDuplicateDeclarations(node) { + var names = {}; + for (var _i = 0, _a = node.members; _i < _a.length; _i++) { + var member = _a[_i]; + if (member.kind == 144) { + var memberName = void 0; + switch (member.name.kind) { + case 9: + case 8: + case 69: + memberName = member.name.text; + break; + default: + continue; + } + if (ts.hasProperty(names, memberName)) { + error(member.symbol.valueDeclaration.name, ts.Diagnostics.Duplicate_identifier_0, memberName); + error(member.name, ts.Diagnostics.Duplicate_identifier_0, memberName); + } + else { + names[memberName] = true; + } + } + } + } function checkTypeForDuplicateIndexSignatures(node) { if (node.kind === 222) { var nodeSymbol = getSymbolOfNode(node); @@ -23203,6 +23321,7 @@ var ts; var type = getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node); checkIndexConstraints(type); checkTypeForDuplicateIndexSignatures(node); + checkObjectTypeForDuplicateDeclarations(node); } } function checkArrayType(node) { @@ -23962,6 +24081,10 @@ var ts; if (node.initializer) { checkTypeAssignableTo(checkExpressionCached(node.initializer), declarationType, node, undefined); } + if (!areDeclarationFlagsIdentical(node, symbol.valueDeclaration)) { + error(symbol.valueDeclaration.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name)); + error(node.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name)); + } } if (node.kind !== 145 && node.kind !== 144) { checkExportsOnMergedDeclarations(node); @@ -23974,6 +24097,18 @@ var ts; checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name); } } + function areDeclarationFlagsIdentical(left, right) { + if (ts.hasQuestionToken(left) !== ts.hasQuestionToken(right)) { + return false; + } + var interestingFlags = 8 | + 16 | + 256 | + 128 | + 64 | + 32; + return (left.flags & interestingFlags) === (right.flags & interestingFlags); + } function checkVariableDeclaration(node) { checkGrammarVariableDeclaration(node); return checkVariableLikeDeclaration(node); @@ -24524,6 +24659,7 @@ var ts; var typeWithThis = getTypeWithThisArgument(type); var staticType = getTypeOfSymbol(symbol); checkTypeParameterListsIdentical(node, symbol); + checkClassForDuplicateDeclarations(node); var baseTypeNode = ts.getClassExtendsHeritageClauseElement(node); if (baseTypeNode) { var baseTypes = getBaseTypes(type); @@ -24735,6 +24871,7 @@ var ts; checkIndexConstraints(type); } } + checkObjectTypeForDuplicateDeclarations(node); } ts.forEach(ts.getInterfaceBaseTypeNodes(node), function (heritageElement) { if (!ts.isSupportedExpressionWithTypeArguments(heritageElement)) { @@ -25489,10 +25626,8 @@ var ts; function checkSourceFileWorker(node) { var links = getNodeLinks(node); if (!(links.flags & 1)) { - if (compilerOptions.skipDefaultLibCheck) { - if (node.hasNoDefaultLib) { - return; - } + if (compilerOptions.skipLibCheck && node.isDeclarationFile || compilerOptions.skipDefaultLibCheck && node.hasNoDefaultLib) { + return; } checkGrammarSourceFile(node); potentialThisCollisions.length = 0; @@ -25861,7 +25996,7 @@ var ts; return symbol && getTypeOfSymbol(symbol); } if (ts.isBindingPattern(node)) { - return getTypeForVariableLikeDeclaration(node.parent); + return getTypeForVariableLikeDeclaration(node.parent, true); } if (isInRightSideOfImportOrExportAssignment(node)) { var symbol = getSymbolAtLocation(node); @@ -26300,7 +26435,7 @@ var ts; if (file.moduleAugmentations.length) { (augmentations || (augmentations = [])).push(file.moduleAugmentations); } - if (file.wasReferenced && file.symbol && file.symbol.globalExports) { + if (file.symbol && file.symbol.globalExports) { mergeSymbolTable(globals, file.symbol.globalExports); } }); @@ -26870,7 +27005,6 @@ var ts; if (prop.kind === 193 || name_20.kind === 140) { checkGrammarComputedPropertyName(name_20); - return "continue"; } if (prop.kind === 254 && !inDestructuring && prop.objectAssignmentInitializer) { return { value: grammarErrorOnNode(prop.equalsToken, ts.Diagnostics.can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment) }; @@ -26900,17 +27034,21 @@ var ts; else { ts.Debug.fail("Unexpected syntax kind:" + prop.kind); } - if (!ts.hasProperty(seen, name_20.text)) { - seen[name_20.text] = currentKind; + var effectiveName = ts.getPropertyNameForPropertyNameNode(name_20); + if (effectiveName === undefined) { + return "continue"; + } + if (!ts.hasProperty(seen, effectiveName)) { + seen[effectiveName] = currentKind; } else { - var existingKind = seen[name_20.text]; + var existingKind = seen[effectiveName]; if (currentKind === Property && existingKind === Property) { - return "continue"; + grammarErrorOnNode(name_20, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(name_20)); } else if ((currentKind & GetOrSetAccessor) && (existingKind & GetOrSetAccessor)) { if (existingKind !== GetOrSetAccessor && currentKind !== existingKind) { - seen[name_20.text] = currentKind | existingKind; + seen[effectiveName] = currentKind | existingKind; } else { return { value: grammarErrorOnNode(name_20, ts.Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name) }; @@ -35367,7 +35505,7 @@ var ts; skipTsx: true, traceEnabled: traceEnabled }; - var rootDir = options.typesRoot || (options.configFilePath ? ts.getDirectoryPath(options.configFilePath) : undefined); + var rootDir = options.typesRoot || (options.configFilePath ? ts.getDirectoryPath(options.configFilePath) : (host.getCurrentDirectory && host.getCurrentDirectory())); if (traceEnabled) { if (containingFile === undefined) { if (rootDir === undefined) { @@ -35870,12 +36008,25 @@ var ts; } } } + function getDefaultTypeDirectiveNames(rootPath) { + var localTypes = ts.combinePaths(rootPath, "types"); + var npmTypes = ts.combinePaths(rootPath, "node_modules/@types"); + var result = []; + if (ts.sys.directoryExists(localTypes)) { + result = result.concat(ts.sys.getDirectories(localTypes)); + } + if (ts.sys.directoryExists(npmTypes)) { + result = result.concat(ts.sys.getDirectories(npmTypes)); + } + return result; + } function getDefaultLibLocation() { return ts.getDirectoryPath(ts.normalizePath(ts.sys.getExecutingFilePath())); } var newLine = ts.getNewLineCharacter(options); var realpath = ts.sys.realpath && (function (path) { return ts.sys.realpath(path); }); return { + getDefaultTypeDirectiveNames: getDefaultTypeDirectiveNames, getSourceFile: getSourceFile, getDefaultLibLocation: getDefaultLibLocation, getDefaultLibFileName: function (options) { return ts.combinePaths(getDefaultLibLocation(), ts.getDefaultLibFileName(options)); }, @@ -35943,6 +36094,19 @@ var ts; } return resolutions; } + function getDefaultTypeDirectiveNames(options, rootFiles, host) { + if (options.types) { + return options.types; + } + if (host && host.getDefaultTypeDirectiveNames) { + var commonRoot = computeCommonSourceDirectoryOfFilenames(rootFiles, host.getCurrentDirectory(), function (f) { return host.getCanonicalFileName(f); }); + if (commonRoot) { + return host.getDefaultTypeDirectiveNames(commonRoot); + } + } + return undefined; + } + ts.getDefaultTypeDirectiveNames = getDefaultTypeDirectiveNames; function createProgram(rootNames, options, host, oldProgram) { var program; var files = []; @@ -35978,13 +36142,14 @@ var ts; var filesByName = ts.createFileMap(); var filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? ts.createFileMap(function (fileName) { return fileName.toLowerCase(); }) : undefined; if (!tryReuseStructureFromOldProgram()) { - if (options.types && options.types.length) { - var resolutions = resolveTypeReferenceDirectiveNamesWorker(options.types, undefined); - for (var i = 0; i < options.types.length; i++) { - processTypeReferenceDirective(options.types[i], resolutions[i]); + ts.forEach(rootNames, function (name) { return processRootFile(name, false); }); + var typeReferences = getDefaultTypeDirectiveNames(options, rootNames, host); + if (typeReferences) { + var resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, undefined); + for (var i = 0; i < typeReferences.length; i++) { + processTypeReferenceDirective(typeReferences[i], resolutions[i]); } } - ts.forEach(rootNames, function (name) { return processRootFile(name, false); }); if (!skipDefaultLib) { if (!options.lib) { processRootFile(host.getDefaultLibFileName(options), true); @@ -36561,9 +36726,6 @@ var ts; if (file_1 && options.forceConsistentCasingInFileNames && ts.getNormalizedAbsolutePath(file_1.fileName, currentDirectory) !== ts.getNormalizedAbsolutePath(fileName, currentDirectory)) { reportFileNamesDifferOnlyInCasingError(fileName, file_1.fileName, refFile, refPos, refEnd); } - if (file_1) { - file_1.wasReferenced = file_1.wasReferenced || isReference; - } return file_1; } var file = host.getSourceFile(fileName, options.target, function (hostErrorMessage) { @@ -36576,7 +36738,6 @@ var ts; }); filesByName.set(path, file); if (file) { - file.wasReferenced = file.wasReferenced || isReference; file.path = path; if (host.useCaseSensitiveFileNames()) { var existingFile = filesByNameIgnoreCase.get(path); @@ -36677,17 +36838,7 @@ var ts; !options.noResolve && i < file.imports.length; if (shouldAddFile) { - var importedFile = findSourceFile(resolution.resolvedFileName, ts.toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName), false, false, file, ts.skipTrivia(file.text, file.imports[i].pos), file.imports[i].end); - if (importedFile && resolution.isExternalLibraryImport) { - if (!ts.isExternalModule(importedFile) && importedFile.statements.length) { - var start_5 = ts.getTokenPosOfNode(file.imports[i], file); - fileProcessingDiagnostics.add(ts.createFileDiagnostic(file, start_5, file.imports[i].end - start_5, ts.Diagnostics.Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_the_package_definition, importedFile.fileName)); - } - else if (importedFile.referencedFiles.length) { - var firstRef = importedFile.referencedFiles[0]; - fileProcessingDiagnostics.add(ts.createFileDiagnostic(importedFile, firstRef.pos, firstRef.end - firstRef.pos, ts.Diagnostics.Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_package_author_to_update_the_package_definition)); - } - } + findSourceFile(resolution.resolvedFileName, ts.toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName), false, false, file, ts.skipTrivia(file.text, file.imports[i].pos), file.imports[i].end); } } } @@ -36772,7 +36923,7 @@ var ts; } } else { - programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Substututions_for_pattern_0_should_be_an_array, key)); + programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Substitutions_for_pattern_0_should_be_an_array, key)); } } } @@ -36821,13 +36972,19 @@ var ts; } else if (firstExternalModuleSourceFile && languageVersion < 2 && options.module === ts.ModuleKind.None) { var span = ts.getErrorSpanForNode(firstExternalModuleSourceFile, firstExternalModuleSourceFile.externalModuleIndicator); - programDiagnostics.add(ts.createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_modules_unless_the_module_flag_is_provided_with_a_valid_module_type_Consider_setting_the_module_compiler_option_in_a_tsconfig_json_file)); + programDiagnostics.add(ts.createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none)); } if (options.module === ts.ModuleKind.ES6 && languageVersion < 2) { programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_compile_modules_into_es2015_when_targeting_ES5_or_lower)); } - if (outFile && options.module && !(options.module === ts.ModuleKind.AMD || options.module === ts.ModuleKind.System)) { - programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile")); + if (outFile) { + if (options.module && !(options.module === ts.ModuleKind.AMD || options.module === ts.ModuleKind.System)) { + programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile")); + } + else if (options.module === undefined && firstExternalModuleSourceFile) { + var span = ts.getErrorSpanForNode(firstExternalModuleSourceFile, firstExternalModuleSourceFile.externalModuleIndicator); + programDiagnostics.add(ts.createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system, options.out ? "out" : "outFile")); + } } if (options.outDir || options.sourceRoot || @@ -37517,7 +37674,7 @@ var ts; (function (ts) { var NavigateTo; (function (NavigateTo) { - function getNavigateToItems(program, cancellationToken, searchValue, maxResultCount) { + function getNavigateToItems(program, checker, cancellationToken, searchValue, maxResultCount) { var patternMatcher = ts.createPatternMatcher(searchValue); var rawItems = []; var baseSensitivity = { sensitivity: "base" }; @@ -37550,6 +37707,17 @@ var ts; } } }); + rawItems = ts.filter(rawItems, function (item) { + var decl = item.declaration; + if (decl.kind === 231 || decl.kind === 234 || decl.kind === 229) { + var importer = checker.getSymbolAtLocation(decl.name); + var imported = checker.getAliasedSymbol(importer); + return importer.name !== imported.name; + } + else { + return true; + } + }); rawItems.sort(compareNavigateToItems); if (maxResultCount !== undefined) { rawItems = rawItems.slice(0, maxResultCount); @@ -37892,8 +38060,12 @@ var ts; return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.memberSetAccessorElement); case 153: return createItem(node, "[]", ts.ScriptElementKind.indexSignatureElement); + case 224: + return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.enumElement); case 255: return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.memberVariableElement); + case 222: + return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.interfaceElement); case 151: return createItem(node, "()", ts.ScriptElementKind.callSignatureElement); case 152: @@ -39263,7 +39435,7 @@ var ts; } } function findRightmostChildNodeWithTokens(children, exclusiveStartPosition) { - for (var i = exclusiveStartPosition - 1; i >= 0; --i) { + for (var i = exclusiveStartPosition - 1; i >= 0; i--) { if (nodeHasTokens(children[i])) { return children[i]; } @@ -39889,18 +40061,17 @@ var ts; if (!isStarted) { scanner.scan(); } - var t; var pos = scanner.getStartPos(); while (pos < endPos) { - var t_1 = scanner.getToken(); - if (!ts.isTrivia(t_1)) { + var t = scanner.getToken(); + if (!ts.isTrivia(t)) { break; } scanner.scan(); var item = { pos: pos, end: scanner.getStartPos(), - kind: t_1 + kind: t }; pos = scanner.getStartPos(); if (!leadingTrivia) { @@ -41550,7 +41721,7 @@ var ts; else { parts = []; var startPos = commentRange.pos; - for (var line = startLine; line < endLine; ++line) { + for (var line = startLine; line < endLine; line++) { var endOfLine = ts.getEndLinePosition(line, sourceFile); parts.push({ pos: startPos, end: endOfLine }); startPos = ts.getStartPositionOfLine(line + 1, sourceFile); @@ -41568,7 +41739,7 @@ var ts; startLine++; } var delta = indentation - nonWhitespaceColumnInFirstPart.column; - for (var i = startIndex, len = parts.length; i < len; ++i, ++startLine) { + for (var i = startIndex, len = parts.length; i < len; i++, startLine++) { var startLinePos_1 = ts.getStartPositionOfLine(startLine, sourceFile); var nonWhitespaceCharacterAndColumn = i === 0 ? nonWhitespaceColumnInFirstPart @@ -41584,7 +41755,7 @@ var ts; } } function trimTrailingWhitespacesForLines(line1, line2, range) { - for (var line = line1; line < line2; ++line) { + for (var line = line1; line < line2; line++) { var lineStartPosition = ts.getStartPositionOfLine(line, sourceFile); var lineEndPosition = ts.getEndLinePosition(line, sourceFile); if (range && (ts.isComment(range.kind) || ts.isStringOrRegularExpressionOrTemplateLiteral(range.kind)) && range.pos <= lineEndPosition && range.end > lineEndPosition) { @@ -41627,7 +41798,6 @@ var ts; } } function applyRuleEdits(rule, previousRange, previousStartLine, currentRange, currentStartLine) { - var between; switch (rule.Operation.Action) { case 1: return; @@ -41657,14 +41827,6 @@ var ts; } } } - function isSomeBlock(kind) { - switch (kind) { - case 199: - case 226: - return true; - } - return false; - } function getOpenTokenForList(node, list) { switch (node.kind) { case 148: @@ -41722,7 +41884,7 @@ var ts; internedTabsIndentation = []; } if (internedTabsIndentation[tabs] === undefined) { - internedTabsIndentation[tabs] = tabString = repeat('\t', tabs); + internedTabsIndentation[tabs] = tabString = repeat("\t", tabs); } else { tabString = internedTabsIndentation[tabs]; @@ -41747,7 +41909,7 @@ var ts; } function repeat(value, count) { var s = ""; - for (var i = 0; i < count; ++i) { + for (var i = 0; i < count; i++) { s += value; } return s; @@ -42015,7 +42177,7 @@ var ts; ts.Debug.assert(index >= 0 && index < list.length); var node = list[index]; var lineAndCharacter = getStartLineAndCharacterForNode(node, sourceFile); - for (var i = index - 1; i >= 0; --i) { + for (var i = index - 1; i >= 0; i--) { if (list[i].kind === 24) { continue; } @@ -42034,7 +42196,7 @@ var ts; function findFirstNonWhitespaceCharacterAndColumn(startPos, endPos, sourceFile, options) { var character = 0; var column = 0; - for (var pos = startPos; pos < endPos; ++pos) { + for (var pos = startPos; pos < endPos; pos++) { var ch = sourceFile.text.charCodeAt(pos); if (!ts.isWhiteSpace(ch)) { break; @@ -44005,9 +44167,9 @@ var ts; log("getCompletionData: Get previous token 1: " + (new Date().getTime() - start)); var contextToken = previousToken; if (contextToken && position <= contextToken.end && ts.isWord(contextToken.kind)) { - var start_6 = new Date().getTime(); + var start_5 = new Date().getTime(); contextToken = ts.findPrecedingToken(contextToken.getFullStart(), sourceFile); - log("getCompletionData: Get previous token 2: " + (new Date().getTime() - start_6)); + log("getCompletionData: Get previous token 2: " + (new Date().getTime() - start_5)); } var node = currentToken; var isRightOfDot = false; @@ -44234,9 +44396,9 @@ var ts; || contextToken.kind === 166 || contextToken.kind === 10 || ts.isTemplateLiteralKind(contextToken.kind)) { - var start_7 = contextToken.getStart(); + var start_6 = contextToken.getStart(); var end = contextToken.getEnd(); - if (start_7 < position && position < end) { + if (start_6 < position && position < end) { return true; } if (position === end) { @@ -45314,8 +45476,7 @@ var ts; } function getDocumentHighlights(fileName, position, filesToSearch) { synchronizeHostData(); - filesToSearch = ts.map(filesToSearch, ts.normalizeSlashes); - var sourceFilesToSearch = ts.filter(program.getSourceFiles(), function (f) { return ts.contains(filesToSearch, f.fileName); }); + var sourceFilesToSearch = ts.map(filesToSearch, function (f) { return program.getSourceFile(f); }); var sourceFile = getValidSourceFile(fileName); var node = ts.getTouchingWord(sourceFile, position); if (!node) { @@ -46498,7 +46659,8 @@ var ts; } function getNavigateToItems(searchValue, maxResultCount) { synchronizeHostData(); - return ts.NavigateTo.getNavigateToItems(program, cancellationToken, searchValue, maxResultCount); + var checker = getProgram().getTypeChecker(); + return ts.NavigateTo.getNavigateToItems(program, checker, cancellationToken, searchValue, maxResultCount); } function getEmitOutput(fileName) { synchronizeHostData(); @@ -50961,6 +51123,9 @@ var ts; LanguageServiceShimHostAdapter.prototype.getCurrentDirectory = function () { return this.shimHost.getCurrentDirectory(); }; + LanguageServiceShimHostAdapter.prototype.getDirectories = function (path) { + return this.shimHost.getDirectories(path); + }; LanguageServiceShimHostAdapter.prototype.getDefaultLibFileName = function (options) { return this.shimHost.getDefaultLibFileName(JSON.stringify(options)); }; diff --git a/lib/typescript.d.ts b/lib/typescript.d.ts index 84a06001d14..1ac624055d7 100644 --- a/lib/typescript.d.ts +++ b/lib/typescript.d.ts @@ -261,7 +261,7 @@ declare namespace ts { ModuleDeclaration = 225, ModuleBlock = 226, CaseBlock = 227, - GlobalModuleExportDeclaration = 228, + NamespaceExportDeclaration = 228, ImportEqualsDeclaration = 229, ImportDeclaration = 230, ImportClause = 231, @@ -934,7 +934,7 @@ declare namespace ts { interface NamespaceImport extends Declaration { name: Identifier; } - interface GlobalModuleExportDeclaration extends DeclarationStatement { + interface NamespaceExportDeclaration extends DeclarationStatement { name: Identifier; moduleReference: LiteralLikeNode; } @@ -1329,7 +1329,7 @@ declare namespace ts { FunctionScopedVariableExcludes = 107454, BlockScopedVariableExcludes = 107455, ParameterExcludes = 107455, - PropertyExcludes = 107455, + PropertyExcludes = 0, EnumMemberExcludes = 107455, FunctionExcludes = 106927, ClassExcludes = 899519, @@ -1554,6 +1554,7 @@ declare namespace ts { allowJs?: boolean; noImplicitUseStrict?: boolean; strictNullChecks?: boolean; + skipLibCheck?: boolean; listEmittedFiles?: boolean; lib?: string[]; types?: string[]; @@ -1627,6 +1628,7 @@ declare namespace ts { trace?(s: string): void; directoryExists?(directoryName: string): boolean; realpath?(path: string): string; + getCurrentDirectory?(): string; } interface ResolvedModule { resolvedFileName: string; @@ -1650,6 +1652,7 @@ declare namespace ts { getCancellationToken?(): CancellationToken; getDefaultLibFileName(options: CompilerOptions): string; getDefaultLibLocation?(): string; + getDefaultTypeDirectiveNames?(rootPath: string): string[]; writeFile: WriteFileCallback; getCurrentDirectory(): string; getCanonicalFileName(fileName: string): string; @@ -1693,6 +1696,7 @@ declare namespace ts { createDirectory(path: string): void; getExecutingFilePath(): string; getCurrentDirectory(): string; + getDirectories(path: string): string[]; readDirectory(path: string, extension?: string, exclude?: string[]): string[]; getModifiedTime?(path: string): Date; createHash?(data: string): string; @@ -1812,6 +1816,7 @@ declare namespace ts { function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost; function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; function flattenDiagnosticMessageText(messageText: string | DiagnosticMessageChain, newLine: string): string; + function getDefaultTypeDirectiveNames(options: CompilerOptions, rootFiles: string[], host: CompilerHost): string[]; function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program; } declare namespace ts { @@ -2345,26 +2350,55 @@ declare namespace ts { namespace ScriptElementKind { const unknown: string; const warning: string; + /** predefined type (void) or keyword (class) */ const keyword: string; + /** top level script node */ const scriptElement: string; + /** module foo {} */ const moduleElement: string; + /** class X {} */ const classElement: string; + /** var x = class X {} */ const localClassElement: string; + /** interface Y {} */ const interfaceElement: string; + /** type T = ... */ const typeElement: string; + /** enum E */ const enumElement: string; + /** + * Inside module and script only + * const v = .. + */ const variableElement: string; + /** Inside function */ const localVariableElement: string; + /** + * Inside module and script only + * function f() { } + */ const functionElement: string; + /** Inside function */ const localFunctionElement: string; + /** class X { [public|private]* foo() {} } */ const memberFunctionElement: string; + /** class X { [public|private]* [get|set] foo:number; } */ const memberGetAccessorElement: string; const memberSetAccessorElement: string; + /** + * class X { [public|private]* foo:number; } + * interface Y { foo:number; } + */ const memberVariableElement: string; + /** class X { constructor() { } } */ const constructorImplementationElement: string; + /** interface Y { ():number; } */ const callSignatureElement: string; + /** interface Y { []:number; } */ const indexSignatureElement: string; + /** interface Y { new():Y; } */ const constructSignatureElement: string; + /** function foo(*Y*: string) */ const parameterElement: string; const typeParameterElement: string; const primitiveType: string; diff --git a/lib/typescript.js b/lib/typescript.js index e78eda7b0bb..cf982a3ede9 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -271,7 +271,7 @@ var ts; SyntaxKind[SyntaxKind["ModuleDeclaration"] = 225] = "ModuleDeclaration"; SyntaxKind[SyntaxKind["ModuleBlock"] = 226] = "ModuleBlock"; SyntaxKind[SyntaxKind["CaseBlock"] = 227] = "CaseBlock"; - SyntaxKind[SyntaxKind["GlobalModuleExportDeclaration"] = 228] = "GlobalModuleExportDeclaration"; + SyntaxKind[SyntaxKind["NamespaceExportDeclaration"] = 228] = "NamespaceExportDeclaration"; SyntaxKind[SyntaxKind["ImportEqualsDeclaration"] = 229] = "ImportEqualsDeclaration"; SyntaxKind[SyntaxKind["ImportDeclaration"] = 230] = "ImportDeclaration"; SyntaxKind[SyntaxKind["ImportClause"] = 231] = "ImportClause"; @@ -561,7 +561,7 @@ var ts; // they can not merge with anything in the value space SymbolFlags[SymbolFlags["BlockScopedVariableExcludes"] = 107455] = "BlockScopedVariableExcludes"; SymbolFlags[SymbolFlags["ParameterExcludes"] = 107455] = "ParameterExcludes"; - SymbolFlags[SymbolFlags["PropertyExcludes"] = 107455] = "PropertyExcludes"; + SymbolFlags[SymbolFlags["PropertyExcludes"] = 0] = "PropertyExcludes"; SymbolFlags[SymbolFlags["EnumMemberExcludes"] = 107455] = "EnumMemberExcludes"; SymbolFlags[SymbolFlags["FunctionExcludes"] = 106927] = "FunctionExcludes"; SymbolFlags[SymbolFlags["ClassExcludes"] = 899519] = "ClassExcludes"; @@ -1841,6 +1841,10 @@ var ts; } return result.sort(); } + function getDirectories(path) { + var folder = fso.GetFolder(path); + return getNames(folder.subfolders); + } function readDirectory(path, extension, exclude) { var result = []; exclude = ts.map(exclude, function (s) { return getCanonicalPath(ts.combinePaths(path, s)); }); @@ -1895,6 +1899,7 @@ var ts; getCurrentDirectory: function () { return new ActiveXObject("WScript.Shell").CurrentDirectory; }, + getDirectories: getDirectories, readDirectory: readDirectory, exit: function (exitCode) { try { @@ -2057,6 +2062,9 @@ var ts; function directoryExists(path) { return fileSystemEntryExists(path, 1 /* Directory */); } + function getDirectories(path) { + return ts.filter(_fs.readdirSync(path), function (p) { return fileSystemEntryExists(ts.combinePaths(path, p), 1 /* Directory */); }); + } function readDirectory(path, extension, exclude) { var result = []; exclude = ts.map(exclude, function (s) { return getCanonicalPath(ts.combinePaths(path, s)); }); @@ -2157,6 +2165,7 @@ var ts; getCurrentDirectory: function () { return process.cwd(); }, + getDirectories: getDirectories, readDirectory: readDirectory, getModifiedTime: function (path) { try { @@ -2209,6 +2218,7 @@ var ts; createDirectory: ChakraHost.createDirectory, getExecutingFilePath: function () { return ChakraHost.executingFile; }, getCurrentDirectory: function () { return ChakraHost.currentDirectory; }, + getDirectories: ChakraHost.getDirectories, readDirectory: ChakraHost.readDirectory, exit: ChakraHost.quit, realpath: realpath @@ -2347,7 +2357,7 @@ var ts; or_expected: { code: 1144, category: ts.DiagnosticCategory.Error, key: "or_expected_1144", message: "'{' or ';' expected." }, Declaration_expected: { code: 1146, category: ts.DiagnosticCategory.Error, key: "Declaration_expected_1146", message: "Declaration expected." }, Import_declarations_in_a_namespace_cannot_reference_a_module: { code: 1147, category: ts.DiagnosticCategory.Error, key: "Import_declarations_in_a_namespace_cannot_reference_a_module_1147", message: "Import declarations in a namespace cannot reference a module." }, - Cannot_compile_modules_unless_the_module_flag_is_provided_with_a_valid_module_type_Consider_setting_the_module_compiler_option_in_a_tsconfig_json_file: { code: 1148, category: ts.DiagnosticCategory.Error, key: "Cannot_compile_modules_unless_the_module_flag_is_provided_with_a_valid_module_type_Consider_setting__1148", message: "Cannot compile modules unless the '--module' flag is provided with a valid module type. Consider setting the 'module' compiler option in a 'tsconfig.json' file." }, + Cannot_use_imports_exports_or_module_augmentations_when_module_is_none: { code: 1148, category: ts.DiagnosticCategory.Error, key: "Cannot_use_imports_exports_or_module_augmentations_when_module_is_none_1148", message: "Cannot use imports, exports, or module augmentations when '--module' is 'none'." }, File_name_0_differs_from_already_included_file_name_1_only_in_casing: { code: 1149, category: ts.DiagnosticCategory.Error, key: "File_name_0_differs_from_already_included_file_name_1_only_in_casing_1149", message: "File name '{0}' differs from already included file name '{1}' only in casing" }, new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead: { code: 1150, category: ts.DiagnosticCategory.Error, key: "new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead_1150", message: "'new T[]' cannot be used to create an array. Use 'new Array()' instead." }, const_declarations_must_be_initialized: { code: 1155, category: ts.DiagnosticCategory.Error, key: "const_declarations_must_be_initialized_1155", message: "'const' declarations must be initialized" }, @@ -2717,6 +2727,8 @@ var ts; this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation: { code: 2683, category: ts.DiagnosticCategory.Error, key: "this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_2683", message: "'this' implicitly has type 'any' because it does not have a type annotation." }, The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1: { code: 2684, category: ts.DiagnosticCategory.Error, key: "The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1_2684", message: "The 'this' context of type '{0}' is not assignable to method's 'this' of type '{1}'." }, The_this_types_of_each_signature_are_incompatible: { code: 2685, category: ts.DiagnosticCategory.Error, key: "The_this_types_of_each_signature_are_incompatible_2685", message: "The 'this' types of each signature are incompatible." }, + Identifier_0_must_be_imported_from_a_module: { code: 2686, category: ts.DiagnosticCategory.Error, key: "Identifier_0_must_be_imported_from_a_module_2686", message: "Identifier '{0}' must be imported from a module" }, + All_declarations_of_0_must_have_identical_modifiers: { code: 2687, category: ts.DiagnosticCategory.Error, key: "All_declarations_of_0_must_have_identical_modifiers_2687", message: "All declarations of '{0}' must have identical modifiers." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: ts.DiagnosticCategory.Error, key: "Import_declaration_0_is_using_private_name_1_4000", message: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: ts.DiagnosticCategory.Error, key: "Type_parameter_0_of_exported_class_has_or_is_using_private_name_1_4002", message: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: ts.DiagnosticCategory.Error, key: "Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1_4004", message: "Type parameter '{0}' of exported interface has or is using private name '{1}'." }, @@ -2810,7 +2822,7 @@ var ts; Option_paths_cannot_be_used_without_specifying_baseUrl_option: { code: 5060, category: ts.DiagnosticCategory.Error, key: "Option_paths_cannot_be_used_without_specifying_baseUrl_option_5060", message: "Option 'paths' cannot be used without specifying '--baseUrl' option." }, Pattern_0_can_have_at_most_one_Asterisk_character: { code: 5061, category: ts.DiagnosticCategory.Error, key: "Pattern_0_can_have_at_most_one_Asterisk_character_5061", message: "Pattern '{0}' can have at most one '*' character" }, Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character: { code: 5062, category: ts.DiagnosticCategory.Error, key: "Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character_5062", message: "Substitution '{0}' in pattern '{1}' in can have at most one '*' character" }, - Substututions_for_pattern_0_should_be_an_array: { code: 5063, category: ts.DiagnosticCategory.Error, key: "Substututions_for_pattern_0_should_be_an_array_5063", message: "Substututions for pattern '{0}' should be an array." }, + Substitutions_for_pattern_0_should_be_an_array: { code: 5063, category: ts.DiagnosticCategory.Error, key: "Substitutions_for_pattern_0_should_be_an_array_5063", message: "Substitutions for pattern '{0}' should be an array." }, Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2: { code: 5064, category: ts.DiagnosticCategory.Error, key: "Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2_5064", message: "Substitution '{0}' for pattern '{1}' has incorrect type, expected 'string', got '{2}'." }, Concatenate_and_emit_output_to_single_file: { code: 6001, category: ts.DiagnosticCategory.Message, key: "Concatenate_and_emit_output_to_single_file_6001", message: "Concatenate and emit output to single file." }, Generates_corresponding_d_ts_file: { code: 6002, category: ts.DiagnosticCategory.Message, key: "Generates_corresponding_d_ts_file_6002", message: "Generates corresponding '.d.ts' file." }, @@ -2823,6 +2835,7 @@ var ts; Do_not_emit_comments_to_output: { code: 6009, category: ts.DiagnosticCategory.Message, key: "Do_not_emit_comments_to_output_6009", message: "Do not emit comments to output." }, Do_not_emit_outputs: { code: 6010, category: ts.DiagnosticCategory.Message, key: "Do_not_emit_outputs_6010", message: "Do not emit outputs." }, Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking: { code: 6011, category: ts.DiagnosticCategory.Message, key: "Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011", message: "Allow default imports from modules with no default export. This does not affect code emit, just typechecking." }, + Skip_type_checking_of_declaration_files: { code: 6012, category: ts.DiagnosticCategory.Message, key: "Skip_type_checking_of_declaration_files_6012", message: "Skip type checking of declaration files." }, Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015: { code: 6015, category: ts.DiagnosticCategory.Message, key: "Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015_6015", message: "Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES2015'" }, Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015: { code: 6016, category: ts.DiagnosticCategory.Message, key: "Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015_6016", message: "Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'" }, Print_this_message: { code: 6017, category: ts.DiagnosticCategory.Message, key: "Print_this_message_6017", message: "Print this message." }, @@ -2924,6 +2937,7 @@ var ts; Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set: { code: 6128, category: ts.DiagnosticCategory.Message, key: "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set_6128", message: "======== Resolving type reference directive '{0}', containing file not set, root directory not set. ========" }, The_config_file_0_found_doesn_t_contain_any_source_files: { code: 6129, category: ts.DiagnosticCategory.Error, key: "The_config_file_0_found_doesn_t_contain_any_source_files_6129", message: "The config file '{0}' found doesn't contain any source files." }, Resolving_real_path_for_0_result_1: { code: 6130, category: ts.DiagnosticCategory.Message, key: "Resolving_real_path_for_0_result_1_6130", message: "Resolving real path for '{0}', result '{1}'" }, + Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system: { code: 6131, category: ts.DiagnosticCategory.Error, key: "Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system_6131", message: "Cannot compile modules using option '{0}' unless the '--module' flag is 'amd' or 'system'." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable_0_implicitly_has_an_1_type_7005", message: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter_0_implicitly_has_an_1_type_7006", message: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member_0_implicitly_has_an_1_type_7008", message: "Member '{0}' implicitly has an '{1}' type." }, @@ -6172,7 +6186,7 @@ var ts; // export default ... function isAliasSymbolDeclaration(node) { return node.kind === 229 /* ImportEqualsDeclaration */ || - node.kind === 228 /* GlobalModuleExportDeclaration */ || + node.kind === 228 /* NamespaceExportDeclaration */ || node.kind === 231 /* ImportClause */ && !!node.name || node.kind === 232 /* NamespaceImport */ || node.kind === 234 /* ImportSpecifier */ || @@ -6301,7 +6315,7 @@ var ts; } ts.isWellKnownSymbolSyntactically = isWellKnownSymbolSyntactically; function getPropertyNameForPropertyNameNode(name) { - if (name.kind === 69 /* Identifier */ || name.kind === 9 /* StringLiteral */ || name.kind === 8 /* NumericLiteral */) { + if (name.kind === 69 /* Identifier */ || name.kind === 9 /* StringLiteral */ || name.kind === 8 /* NumericLiteral */ || name.kind === 142 /* Parameter */) { return name.text; } if (name.kind === 140 /* ComputedPropertyName */) { @@ -7773,7 +7787,7 @@ var ts; case 231 /* ImportClause */: return visitNode(cbNode, node.name) || visitNode(cbNode, node.namedBindings); - case 228 /* GlobalModuleExportDeclaration */: + case 228 /* NamespaceExportDeclaration */: return visitNode(cbNode, node.name); case 232 /* NamespaceImport */: return visitNode(cbNode, node.name); @@ -12182,7 +12196,7 @@ var ts; return nextToken() === 39 /* SlashToken */; } function parseGlobalModuleExportDeclaration(fullStart, decorators, modifiers) { - var exportDeclaration = createNode(228 /* GlobalModuleExportDeclaration */, fullStart); + var exportDeclaration = createNode(228 /* NamespaceExportDeclaration */, fullStart); exportDeclaration.decorators = decorators; exportDeclaration.modifiers = modifiers; parseExpected(116 /* AsKeyword */); @@ -15018,10 +15032,10 @@ var ts; case 145 /* PropertyDeclaration */: case 144 /* PropertySignature */: case 266 /* JSDocRecordMember */: - return bindPropertyOrMethodOrAccessor(node, 4 /* Property */ | (node.questionToken ? 536870912 /* Optional */ : 0 /* None */), 107455 /* PropertyExcludes */); + return bindPropertyOrMethodOrAccessor(node, 4 /* Property */ | (node.questionToken ? 536870912 /* Optional */ : 0 /* None */), 0 /* PropertyExcludes */); case 253 /* PropertyAssignment */: case 254 /* ShorthandPropertyAssignment */: - return bindPropertyOrMethodOrAccessor(node, 4 /* Property */, 107455 /* PropertyExcludes */); + return bindPropertyOrMethodOrAccessor(node, 4 /* Property */, 0 /* PropertyExcludes */); case 255 /* EnumMember */: return bindPropertyOrMethodOrAccessor(node, 8 /* EnumMember */, 107455 /* EnumMemberExcludes */); case 247 /* JsxSpreadAttribute */: @@ -15037,7 +15051,7 @@ var ts; // as other properties in the object literal. So we use SymbolFlags.PropertyExcludes // so that it will conflict with any other object literal members with the same // name. - return bindPropertyOrMethodOrAccessor(node, 8192 /* Method */ | (node.questionToken ? 536870912 /* Optional */ : 0 /* None */), ts.isObjectLiteralMethod(node) ? 107455 /* PropertyExcludes */ : 99263 /* MethodExcludes */); + return bindPropertyOrMethodOrAccessor(node, 8192 /* Method */ | (node.questionToken ? 536870912 /* Optional */ : 0 /* None */), ts.isObjectLiteralMethod(node) ? 0 /* PropertyExcludes */ : 99263 /* MethodExcludes */); case 220 /* FunctionDeclaration */: return bindFunctionDeclaration(node); case 148 /* Constructor */: @@ -15081,8 +15095,8 @@ var ts; case 234 /* ImportSpecifier */: case 238 /* ExportSpecifier */: return declareSymbolAndAddToSymbolTable(node, 8388608 /* Alias */, 8388608 /* AliasExcludes */); - case 228 /* GlobalModuleExportDeclaration */: - return bindGlobalModuleExportDeclaration(node); + case 228 /* NamespaceExportDeclaration */: + return bindNamespaceExportDeclaration(node); case 231 /* ImportClause */: return bindImportClause(node); case 236 /* ExportDeclaration */: @@ -15120,14 +15134,14 @@ var ts; } else if (boundExpression.kind === 69 /* Identifier */ && node.kind === 235 /* ExportAssignment */) { // An export default clause with an identifier exports all meanings of that identifier - declareSymbol(container.symbol.exports, container.symbol, node, 8388608 /* Alias */, 107455 /* PropertyExcludes */ | 8388608 /* AliasExcludes */); + declareSymbol(container.symbol.exports, container.symbol, node, 8388608 /* Alias */, 0 /* PropertyExcludes */ | 8388608 /* AliasExcludes */); } else { // An export default clause with an expression exports a value - declareSymbol(container.symbol.exports, container.symbol, node, 4 /* Property */, 107455 /* PropertyExcludes */ | 8388608 /* AliasExcludes */); + declareSymbol(container.symbol.exports, container.symbol, node, 4 /* Property */, 0 /* PropertyExcludes */ | 8388608 /* AliasExcludes */); } } - function bindGlobalModuleExportDeclaration(node) { + function bindNamespaceExportDeclaration(node) { if (node.modifiers && node.modifiers.length) { file.bindDiagnostics.push(ts.createDiagnosticForNode(node, ts.Diagnostics.Modifiers_cannot_appear_here)); } @@ -15186,7 +15200,7 @@ var ts; if (container.kind === 179 /* FunctionExpression */ || container.kind === 220 /* FunctionDeclaration */) { container.symbol.members = container.symbol.members || {}; // It's acceptable for multiple 'this' assignments of the same identifier to occur - declareSymbol(container.symbol.members, container.symbol, node, 4 /* Property */, 107455 /* PropertyExcludes */ & ~4 /* Property */); + declareSymbol(container.symbol.members, container.symbol, node, 4 /* Property */, 0 /* PropertyExcludes */ & ~4 /* Property */); } } function bindPrototypePropertyAssignment(node) { @@ -15209,7 +15223,7 @@ var ts; funcSymbol.members = {}; } // Declare the method/property - declareSymbol(funcSymbol.members, funcSymbol, leftSideOfAssignment, 4 /* Property */, 107455 /* PropertyExcludes */); + declareSymbol(funcSymbol.members, funcSymbol, leftSideOfAssignment, 4 /* Property */, 0 /* PropertyExcludes */); } function bindCallExpression(node) { // We're only inspecting call expressions to detect CommonJS modules, so we can skip @@ -15310,7 +15324,7 @@ var ts; // containing class. if (ts.isParameterPropertyDeclaration(node)) { var classDeclaration = node.parent.parent; - declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4 /* Property */, 107455 /* PropertyExcludes */); + declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4 /* Property */, 0 /* PropertyExcludes */); } } function bindFunctionDeclaration(node) { @@ -15696,7 +15710,7 @@ var ts; if (flags & 1 /* FunctionScopedVariable */) result |= 107454 /* FunctionScopedVariableExcludes */; if (flags & 4 /* Property */) - result |= 107455 /* PropertyExcludes */; + result |= 0 /* PropertyExcludes */; if (flags & 8 /* EnumMember */) result |= 107455 /* EnumMemberExcludes */; if (flags & 16 /* Function */) @@ -15982,6 +15996,7 @@ var ts; var propertyWithInvalidInitializer; var errorLocation = location; var grandparent; + var isInExternalModule = false; loop: while (location) { // Locals of a source file are not in scope (because they get merged into the global symbol table) if (location.locals && !isGlobalSourceFile(location)) { @@ -16024,6 +16039,7 @@ var ts; case 256 /* SourceFile */: if (!ts.isExternalOrCommonJsModule(location)) break; + isInExternalModule = true; case 225 /* ModuleDeclaration */: var moduleExports = getSymbolOfNode(location).exports; if (location.kind === 256 /* SourceFile */ || ts.isAmbientModule(location)) { @@ -16207,6 +16223,13 @@ var ts; checkResolvedBlockScopedVariable(exportOrLocalSymbol, errorLocation); } } + // If we're in an external module, we can't reference symbols created from UMD export declarations + if (result && isInExternalModule) { + var decls = result.declarations; + if (decls && decls.length === 1 && decls[0].kind === 228 /* NamespaceExportDeclaration */) { + error(errorLocation, ts.Diagnostics.Identifier_0_must_be_imported_from_a_module, name); + } + } } return result; } @@ -16409,7 +16432,7 @@ var ts; return getTargetOfExportSpecifier(node); case 235 /* ExportAssignment */: return getTargetOfExportAssignment(node); - case 228 /* GlobalModuleExportDeclaration */: + case 228 /* NamespaceExportDeclaration */: return getTargetOfGlobalModuleExportDeclaration(node); } } @@ -17883,7 +17906,7 @@ var ts; // assigned by contextual typing. function getTypeForBindingElementParent(node) { var symbol = getSymbolOfNode(node); - return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node); + return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node, /*includeOptionality*/ false); } function getTextOfPropertyName(name) { switch (name.kind) { @@ -18009,7 +18032,7 @@ var ts; return strictNullChecks && optional ? addNullableKind(type, 32 /* Undefined */) : type; } // Return the inferred type for a variable, parameter, or property declaration - function getTypeForVariableLikeDeclaration(declaration) { + function getTypeForVariableLikeDeclaration(declaration, includeOptionality) { if (declaration.flags & 134217728 /* JavaScriptFile */) { // If this is a variable in a JavaScript file, then use the JSDoc type (if it has // one as its type), otherwise fallback to the below standard TS codepaths to @@ -18035,7 +18058,7 @@ var ts; } // Use type from type annotation if one is present if (declaration.type) { - return addOptionality(getTypeFromTypeNode(declaration.type), /*optional*/ !!declaration.questionToken); + return addOptionality(getTypeFromTypeNode(declaration.type), /*optional*/ declaration.questionToken && includeOptionality); } if (declaration.kind === 142 /* Parameter */) { var func = declaration.parent; @@ -18056,12 +18079,12 @@ var ts; ? getContextuallyTypedThisType(func) : getContextuallyTypedParameterType(declaration); if (type) { - return addOptionality(type, /*optional*/ !!declaration.questionToken); + return addOptionality(type, /*optional*/ declaration.questionToken && includeOptionality); } } // Use the type of the initializer expression if one is present if (declaration.initializer) { - return addOptionality(checkExpressionCached(declaration.initializer), /*optional*/ !!declaration.questionToken); + return addOptionality(checkExpressionCached(declaration.initializer), /*optional*/ declaration.questionToken && includeOptionality); } // If it is a short-hand property assignment, use the type of the identifier if (declaration.kind === 254 /* ShorthandPropertyAssignment */) { @@ -18155,7 +18178,7 @@ var ts; // binding pattern [x, s = ""]. Because the contextual type is a tuple type, the resulting type of [1, "one"] is the // tuple type [number, string]. Thus, the type inferred for 'x' is number and the type inferred for 's' is string. function getWidenedTypeForVariableLikeDeclaration(declaration, reportErrors) { - var type = getTypeForVariableLikeDeclaration(declaration); + var type = getTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ true); if (type) { if (reportErrors) { reportErrorsFromWidening(declaration, type); @@ -20719,7 +20742,7 @@ var ts; return isIdenticalTo(source, target); } if (!(target.flags & 134217728 /* Never */)) { - if (target.flags & 1 /* Any */) + if (target.flags & 1 /* Any */ || source.flags & 134217728 /* Never */) return -1 /* True */; if (source.flags & 32 /* Undefined */) { if (!strictNullChecks || target.flags & (32 /* Undefined */ | 16 /* Void */) || source === emptyArrayElementType) @@ -20739,7 +20762,7 @@ var ts; if (source.flags & 256 /* StringLiteral */ && target === stringType) return -1 /* True */; if (relation === assignableRelation || relation === comparableRelation) { - if (source.flags & (1 /* Any */ | 134217728 /* Never */)) + if (source.flags & 1 /* Any */) return -1 /* True */; if (source === numberType && target.flags & 128 /* Enum */) return -1 /* True */; @@ -21634,41 +21657,52 @@ var ts; getSignaturesOfType(type, 0 /* Call */).length === 0 && getSignaturesOfType(type, 1 /* Construct */).length === 0; } + function createTransientSymbol(source, type) { + var symbol = createSymbol(source.flags | 67108864 /* Transient */, source.name); + symbol.declarations = source.declarations; + symbol.parent = source.parent; + symbol.type = type; + symbol.target = source; + if (source.valueDeclaration) { + symbol.valueDeclaration = source.valueDeclaration; + } + return symbol; + } + function transformTypeOfMembers(type, f) { + var members = {}; + for (var _i = 0, _a = getPropertiesOfObjectType(type); _i < _a.length; _i++) { + var property = _a[_i]; + var original = getTypeOfSymbol(property); + var updated = f(original); + members[property.name] = updated === original ? property : createTransientSymbol(property, updated); + } + ; + return members; + } + /** + * If the the provided object literal is subject to the excess properties check, + * create a new that is exempt. Recursively mark object literal members as exempt. + * Leave signatures alone since they are not subject to the check. + */ function getRegularTypeOfObjectLiteral(type) { - if (type.flags & 1048576 /* FreshObjectLiteral */) { - var regularType = type.regularType; - if (!regularType) { - regularType = createType(type.flags & ~1048576 /* FreshObjectLiteral */); - regularType.symbol = type.symbol; - regularType.members = type.members; - regularType.properties = type.properties; - regularType.callSignatures = type.callSignatures; - regularType.constructSignatures = type.constructSignatures; - regularType.stringIndexInfo = type.stringIndexInfo; - regularType.numberIndexInfo = type.numberIndexInfo; - type.regularType = regularType; - } + if (!(type.flags & 1048576 /* FreshObjectLiteral */)) { + return type; + } + var regularType = type.regularType; + if (regularType) { return regularType; } - return type; + var resolved = type; + var members = transformTypeOfMembers(type, getRegularTypeOfObjectLiteral); + var regularNew = createAnonymousType(resolved.symbol, members, resolved.callSignatures, resolved.constructSignatures, resolved.stringIndexInfo, resolved.numberIndexInfo); + regularNew.flags = resolved.flags & ~1048576 /* FreshObjectLiteral */; + type.regularType = regularNew; + return regularNew; } function getWidenedTypeOfObjectLiteral(type) { - var properties = getPropertiesOfObjectType(type); - var members = {}; - ts.forEach(properties, function (p) { - var propType = getTypeOfSymbol(p); - var widenedType = getWidenedType(propType); - if (propType !== widenedType) { - var symbol = createSymbol(p.flags | 67108864 /* Transient */, p.name); - symbol.declarations = p.declarations; - symbol.parent = p.parent; - symbol.type = widenedType; - symbol.target = p; - if (p.valueDeclaration) - symbol.valueDeclaration = p.valueDeclaration; - p = symbol; - } - members[p.name] = p; + var members = transformTypeOfMembers(type, function (prop) { + var widened = getWidenedType(prop); + return prop === widened ? prop : widened; }); var stringIndexInfo = getIndexInfoOfType(type, 0 /* String */); var numberIndexInfo = getIndexInfoOfType(type, 1 /* Number */); @@ -21924,11 +21958,10 @@ var ts; inferFromTypes(source, t); } } - // Next, if target is a union type containing a single naked type parameter, make a - // secondary inference to that type parameter. We don't do this for intersection types - // because in a target type like Foo & T we don't know how which parts of the source type - // should be matched by Foo and which should be inferred to T. - if (target.flags & 16384 /* Union */ && typeParameterCount === 1) { + // Next, if target containings a single naked type parameter, make a secondary inference to that type + // parameter. This gives meaningful results for union types in co-variant positions and intersection + // types in contra-variant positions (such as callback parameters). + if (typeParameterCount === 1) { inferiority++; inferFromTypes(source, typeParameter); inferiority--; @@ -23224,7 +23257,7 @@ var ts; } return nodeCheckFlag === 512 /* SuperStatic */ ? getBaseConstructorTypeOfClass(classType) - : baseClassType; + : getTypeWithThisArgument(baseClassType, classType.thisType); function isLegalUsageOfSuperExpression(container) { if (!container) { return false; @@ -25936,7 +25969,7 @@ var ts; var types = void 0; var funcIsGenerator = !!func.asteriskToken; if (funcIsGenerator) { - types = checkAndAggregateYieldOperandTypes(func.body, contextualMapper); + types = checkAndAggregateYieldOperandTypes(func, contextualMapper); if (types.length === 0) { var iterableIteratorAny = createIterableIteratorType(anyType); if (compilerOptions.noImplicitAny) { @@ -25946,8 +25979,7 @@ var ts; } } else { - var hasImplicitReturn = !!(func.flags & 32768 /* HasImplicitReturn */); - types = checkAndAggregateReturnExpressionTypes(func.body, contextualMapper, isAsync, hasImplicitReturn); + types = checkAndAggregateReturnExpressionTypes(func, contextualMapper); if (!types) { return neverType; } @@ -26001,9 +26033,9 @@ var ts; return widenedType; } } - function checkAndAggregateYieldOperandTypes(body, contextualMapper) { + function checkAndAggregateYieldOperandTypes(func, contextualMapper) { var aggregatedTypes = []; - ts.forEachYieldExpression(body, function (yieldExpression) { + ts.forEachYieldExpression(func.body, function (yieldExpression) { var expr = yieldExpression.expression; if (expr) { var type = checkExpressionCached(expr, contextualMapper); @@ -26018,10 +26050,12 @@ var ts; }); return aggregatedTypes; } - function checkAndAggregateReturnExpressionTypes(body, contextualMapper, isAsync, hasImplicitReturn) { + function checkAndAggregateReturnExpressionTypes(func, contextualMapper) { + var isAsync = ts.isAsyncFunctionLike(func); var aggregatedTypes = []; - var hasOmittedExpressions = false; - ts.forEachReturnStatement(body, function (returnStatement) { + var hasReturnWithNoExpression = !!(func.flags & 32768 /* HasImplicitReturn */); + var hasReturnOfTypeNever = false; + ts.forEachReturnStatement(func.body, function (returnStatement) { var expr = returnStatement.expression; if (expr) { var type = checkExpressionCached(expr, contextualMapper); @@ -26030,20 +26064,24 @@ var ts; // Promise/A+ compatible implementation will always assimilate any foreign promise, so the // return type of the body should be unwrapped to its awaited type, which should be wrapped in // the native Promise type by the caller. - type = checkAwaitedType(type, body.parent, ts.Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member); + type = checkAwaitedType(type, func, ts.Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member); } - if (type !== neverType && !ts.contains(aggregatedTypes, type)) { + if (type === neverType) { + hasReturnOfTypeNever = true; + } + else if (!ts.contains(aggregatedTypes, type)) { aggregatedTypes.push(type); } } else { - hasOmittedExpressions = true; + hasReturnWithNoExpression = true; } }); - if (aggregatedTypes.length === 0 && !hasOmittedExpressions && !hasImplicitReturn) { + if (aggregatedTypes.length === 0 && !hasReturnWithNoExpression && (hasReturnOfTypeNever || + func.kind === 179 /* FunctionExpression */ || func.kind === 180 /* ArrowFunction */)) { return undefined; } - if (strictNullChecks && aggregatedTypes.length && (hasOmittedExpressions || hasImplicitReturn)) { + if (strictNullChecks && aggregatedTypes.length && hasReturnWithNoExpression) { if (!ts.contains(aggregatedTypes, undefinedType)) { aggregatedTypes.push(undefinedType); } @@ -26215,8 +26253,14 @@ var ts; if (symbol.flags & 4 /* Property */ && (expr.kind === 172 /* PropertyAccessExpression */ || expr.kind === 173 /* ElementAccessExpression */) && expr.expression.kind === 97 /* ThisKeyword */) { + // Look for if this is the constructor for the class that `symbol` is a property of. var func = ts.getContainingFunction(expr); - return !(func && func.kind === 148 /* Constructor */ && func.parent === symbol.valueDeclaration.parent); + if (!(func && func.kind === 148 /* Constructor */)) + return true; + // If func.parent is a class and symbol is a (readonly) property of that class, or + // if func is a constructor and symbol is a (readonly) parameter property declared in it, + // then symbol is writeable here. + return !(func.parent === symbol.valueDeclaration.parent || func === symbol.valueDeclaration.parent); } return true; } @@ -27148,6 +27192,79 @@ var ts; } } } + function checkClassForDuplicateDeclarations(node) { + var getter = 1, setter = 2, property = getter | setter; + var instanceNames = {}; + var staticNames = {}; + for (var _i = 0, _a = node.members; _i < _a.length; _i++) { + var member = _a[_i]; + if (member.kind === 148 /* Constructor */) { + for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) { + var param = _c[_b]; + if (ts.isParameterPropertyDeclaration(param)) { + addName(instanceNames, param.name, param.name.text, property); + } + } + } + else { + var static = ts.forEach(member.modifiers, function (m) { return m.kind === 113 /* StaticKeyword */; }); + var names = static ? staticNames : instanceNames; + var memberName = member.name && ts.getPropertyNameForPropertyNameNode(member.name); + if (memberName) { + switch (member.kind) { + case 149 /* GetAccessor */: + addName(names, member.name, memberName, getter); + break; + case 150 /* SetAccessor */: + addName(names, member.name, memberName, setter); + break; + case 145 /* PropertyDeclaration */: + addName(names, member.name, memberName, property); + break; + } + } + } + } + function addName(names, location, name, meaning) { + if (ts.hasProperty(names, name)) { + var prev = names[name]; + if (prev & meaning) { + error(location, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(location)); + } + else { + names[name] = prev | meaning; + } + } + else { + names[name] = meaning; + } + } + } + function checkObjectTypeForDuplicateDeclarations(node) { + var names = {}; + for (var _i = 0, _a = node.members; _i < _a.length; _i++) { + var member = _a[_i]; + if (member.kind == 144 /* PropertySignature */) { + var memberName = void 0; + switch (member.name.kind) { + case 9 /* StringLiteral */: + case 8 /* NumericLiteral */: + case 69 /* Identifier */: + memberName = member.name.text; + break; + default: + continue; + } + if (ts.hasProperty(names, memberName)) { + error(member.symbol.valueDeclaration.name, ts.Diagnostics.Duplicate_identifier_0, memberName); + error(member.name, ts.Diagnostics.Duplicate_identifier_0, memberName); + } + else { + names[memberName] = true; + } + } + } + } function checkTypeForDuplicateIndexSignatures(node) { if (node.kind === 222 /* InterfaceDeclaration */) { var nodeSymbol = getSymbolOfNode(node); @@ -27399,6 +27516,7 @@ var ts; var type = getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node); checkIndexConstraints(type); checkTypeForDuplicateIndexSignatures(node); + checkObjectTypeForDuplicateDeclarations(node); } } function checkArrayType(node) { @@ -28444,6 +28562,10 @@ var ts; if (node.initializer) { checkTypeAssignableTo(checkExpressionCached(node.initializer), declarationType, node, /*headMessage*/ undefined); } + if (!areDeclarationFlagsIdentical(node, symbol.valueDeclaration)) { + error(symbol.valueDeclaration.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name)); + error(node.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name)); + } } if (node.kind !== 145 /* PropertyDeclaration */ && node.kind !== 144 /* PropertySignature */) { // We know we don't have a binding pattern or computed name here @@ -28457,6 +28579,18 @@ var ts; checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name); } } + function areDeclarationFlagsIdentical(left, right) { + if (ts.hasQuestionToken(left) !== ts.hasQuestionToken(right)) { + return false; + } + var interestingFlags = 8 /* Private */ | + 16 /* Protected */ | + 256 /* Async */ | + 128 /* Abstract */ | + 64 /* Readonly */ | + 32 /* Static */; + return (left.flags & interestingFlags) === (right.flags & interestingFlags); + } function checkVariableDeclaration(node) { checkGrammarVariableDeclaration(node); return checkVariableLikeDeclaration(node); @@ -29150,6 +29284,7 @@ var ts; var typeWithThis = getTypeWithThisArgument(type); var staticType = getTypeOfSymbol(symbol); checkTypeParameterListsIdentical(node, symbol); + checkClassForDuplicateDeclarations(node); var baseTypeNode = ts.getClassExtendsHeritageClauseElement(node); if (baseTypeNode) { var baseTypes = getBaseTypes(type); @@ -29398,6 +29533,7 @@ var ts; checkIndexConstraints(type); } } + checkObjectTypeForDuplicateDeclarations(node); } ts.forEach(ts.getInterfaceBaseTypeNodes(node), function (heritageElement) { if (!ts.isSupportedExpressionWithTypeArguments(heritageElement)) { @@ -30241,14 +30377,11 @@ var ts; function checkSourceFileWorker(node) { var links = getNodeLinks(node); if (!(links.flags & 1 /* TypeChecked */)) { - // Check whether the file has declared it is the default lib, - // and whether the user has specifically chosen to avoid checking it. - if (compilerOptions.skipDefaultLibCheck) { - // If the user specified '--noLib' and a file has a '/// ', - // then we should treat that file as a default lib. - if (node.hasNoDefaultLib) { - return; - } + // If skipLibCheck is enabled, skip type checking if file is a declaration file. + // If skipDefaultLibCheck is enabled, skip type checking if file contains a + // '/// ' directive. + if (compilerOptions.skipLibCheck && node.isDeclarationFile || compilerOptions.skipDefaultLibCheck && node.hasNoDefaultLib) { + return; } // Grammar checking checkGrammarSourceFile(node); @@ -30665,7 +30798,7 @@ var ts; return symbol && getTypeOfSymbol(symbol); } if (ts.isBindingPattern(node)) { - return getTypeForVariableLikeDeclaration(node.parent); + return getTypeForVariableLikeDeclaration(node.parent, /*includeOptionality*/ true); } if (isInRightSideOfImportOrExportAssignment(node)) { var symbol = getSymbolAtLocation(node); @@ -31204,7 +31337,7 @@ var ts; if (file.moduleAugmentations.length) { (augmentations || (augmentations = [])).push(file.moduleAugmentations); } - if (file.wasReferenced && file.symbol && file.symbol.globalExports) { + if (file.symbol && file.symbol.globalExports) { mergeSymbolTable(globals, file.symbol.globalExports); } }); @@ -31787,7 +31920,6 @@ var ts; name_20.kind === 140 /* ComputedPropertyName */) { // If the name is not a ComputedPropertyName, the grammar checking will skip it checkGrammarComputedPropertyName(name_20); - return "continue"; } if (prop.kind === 254 /* ShorthandPropertyAssignment */ && !inDestructuring && prop.objectAssignmentInitializer) { // having objectAssignmentInitializer is only valid in ObjectAssignmentPattern @@ -31829,17 +31961,21 @@ var ts; else { ts.Debug.fail("Unexpected syntax kind:" + prop.kind); } - if (!ts.hasProperty(seen, name_20.text)) { - seen[name_20.text] = currentKind; + var effectiveName = ts.getPropertyNameForPropertyNameNode(name_20); + if (effectiveName === undefined) { + return "continue"; + } + if (!ts.hasProperty(seen, effectiveName)) { + seen[effectiveName] = currentKind; } else { - var existingKind = seen[name_20.text]; + var existingKind = seen[effectiveName]; if (currentKind === Property && existingKind === Property) { - return "continue"; + grammarErrorOnNode(name_20, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(name_20)); } else if ((currentKind & GetOrSetAccessor) && (existingKind & GetOrSetAccessor)) { if (existingKind !== GetOrSetAccessor && currentKind !== existingKind) { - seen[name_20.text] = currentKind | existingKind; + seen[effectiveName] = currentKind | existingKind; } else { return { value: grammarErrorOnNode(name_20, ts.Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name) }; @@ -41638,8 +41774,8 @@ var ts; skipTsx: true, traceEnabled: traceEnabled }; - // use typesRoot and fallback to directory that contains tsconfig if typesRoot is not set - var rootDir = options.typesRoot || (options.configFilePath ? ts.getDirectoryPath(options.configFilePath) : undefined); + // use typesRoot and fallback to directory that contains tsconfig or current directory if typesRoot is not set + var rootDir = options.typesRoot || (options.configFilePath ? ts.getDirectoryPath(options.configFilePath) : (host.getCurrentDirectory && host.getCurrentDirectory())); if (traceEnabled) { if (containingFile === undefined) { if (rootDir === undefined) { @@ -42229,12 +42365,25 @@ var ts; } } } + function getDefaultTypeDirectiveNames(rootPath) { + var localTypes = ts.combinePaths(rootPath, "types"); + var npmTypes = ts.combinePaths(rootPath, "node_modules/@types"); + var result = []; + if (ts.sys.directoryExists(localTypes)) { + result = result.concat(ts.sys.getDirectories(localTypes)); + } + if (ts.sys.directoryExists(npmTypes)) { + result = result.concat(ts.sys.getDirectories(npmTypes)); + } + return result; + } function getDefaultLibLocation() { return ts.getDirectoryPath(ts.normalizePath(ts.sys.getExecutingFilePath())); } var newLine = ts.getNewLineCharacter(options); var realpath = ts.sys.realpath && (function (path) { return ts.sys.realpath(path); }); return { + getDefaultTypeDirectiveNames: getDefaultTypeDirectiveNames, getSourceFile: getSourceFile, getDefaultLibLocation: getDefaultLibLocation, getDefaultLibFileName: function (options) { return ts.combinePaths(getDefaultLibLocation(), ts.getDefaultLibFileName(options)); }, @@ -42302,6 +42451,21 @@ var ts; } return resolutions; } + function getDefaultTypeDirectiveNames(options, rootFiles, host) { + // Use explicit type list from tsconfig.json + if (options.types) { + return options.types; + } + // or load all types from the automatic type import fields + if (host && host.getDefaultTypeDirectiveNames) { + var commonRoot = computeCommonSourceDirectoryOfFilenames(rootFiles, host.getCurrentDirectory(), function (f) { return host.getCanonicalFileName(f); }); + if (commonRoot) { + return host.getDefaultTypeDirectiveNames(commonRoot); + } + } + return undefined; + } + ts.getDefaultTypeDirectiveNames = getDefaultTypeDirectiveNames; function createProgram(rootNames, options, host, oldProgram) { var program; var files = []; @@ -42340,14 +42504,15 @@ var ts; // used to track cases when two file names differ only in casing var filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? ts.createFileMap(function (fileName) { return fileName.toLowerCase(); }) : undefined; if (!tryReuseStructureFromOldProgram()) { + ts.forEach(rootNames, function (name) { return processRootFile(name, /*isDefaultLib*/ false); }); // load type declarations specified via 'types' argument - if (options.types && options.types.length) { - var resolutions = resolveTypeReferenceDirectiveNamesWorker(options.types, /*containingFile*/ undefined); - for (var i = 0; i < options.types.length; i++) { - processTypeReferenceDirective(options.types[i], resolutions[i]); + var typeReferences = getDefaultTypeDirectiveNames(options, rootNames, host); + if (typeReferences) { + var resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, /*containingFile*/ undefined); + for (var i = 0; i < typeReferences.length; i++) { + processTypeReferenceDirective(typeReferences[i], resolutions[i]); } } - ts.forEach(rootNames, function (name) { return processRootFile(name, /*isDefaultLib*/ false); }); // Do not process the default library if: // - The '--noLib' flag is used. // - A 'no-default-lib' reference comment is encountered in @@ -42999,9 +43164,6 @@ var ts; if (file_1 && options.forceConsistentCasingInFileNames && ts.getNormalizedAbsolutePath(file_1.fileName, currentDirectory) !== ts.getNormalizedAbsolutePath(fileName, currentDirectory)) { reportFileNamesDifferOnlyInCasingError(fileName, file_1.fileName, refFile, refPos, refEnd); } - if (file_1) { - file_1.wasReferenced = file_1.wasReferenced || isReference; - } return file_1; } // We haven't looked for this file, do so now and cache result @@ -43015,7 +43177,6 @@ var ts; }); filesByName.set(path, file); if (file) { - file.wasReferenced = file.wasReferenced || isReference; file.path = path; if (host.useCaseSensitiveFileNames()) { // for case-sensitive file systems check if we've already seen some file with similar filename ignoring case @@ -43129,19 +43290,7 @@ var ts; !options.noResolve && i < file.imports.length; if (shouldAddFile) { - var importedFile = findSourceFile(resolution.resolvedFileName, ts.toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName), /*isDefaultLib*/ false, /*isReference*/ false, file, ts.skipTrivia(file.text, file.imports[i].pos), file.imports[i].end); - if (importedFile && resolution.isExternalLibraryImport) { - // Since currently irrespective of allowJs, we only look for supportedTypeScript extension external module files, - // this check is ok. Otherwise this would be never true for javascript file - if (!ts.isExternalModule(importedFile) && importedFile.statements.length) { - var start_5 = ts.getTokenPosOfNode(file.imports[i], file); - fileProcessingDiagnostics.add(ts.createFileDiagnostic(file, start_5, file.imports[i].end - start_5, ts.Diagnostics.Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_the_package_definition, importedFile.fileName)); - } - else if (importedFile.referencedFiles.length) { - var firstRef = importedFile.referencedFiles[0]; - fileProcessingDiagnostics.add(ts.createFileDiagnostic(importedFile, firstRef.pos, firstRef.end - firstRef.pos, ts.Diagnostics.Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_package_author_to_update_the_package_definition)); - } - } + findSourceFile(resolution.resolvedFileName, ts.toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName), /*isDefaultLib*/ false, /*isReference*/ false, file, ts.skipTrivia(file.text, file.imports[i].pos), file.imports[i].end); } } } @@ -43227,7 +43376,7 @@ var ts; } } else { - programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Substututions_for_pattern_0_should_be_an_array, key)); + programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Substitutions_for_pattern_0_should_be_an_array, key)); } } } @@ -43278,15 +43427,21 @@ var ts; else if (firstExternalModuleSourceFile && languageVersion < 2 /* ES6 */ && options.module === ts.ModuleKind.None) { // We cannot use createDiagnosticFromNode because nodes do not have parents yet var span = ts.getErrorSpanForNode(firstExternalModuleSourceFile, firstExternalModuleSourceFile.externalModuleIndicator); - programDiagnostics.add(ts.createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_modules_unless_the_module_flag_is_provided_with_a_valid_module_type_Consider_setting_the_module_compiler_option_in_a_tsconfig_json_file)); + programDiagnostics.add(ts.createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none)); } // Cannot specify module gen target of es6 when below es6 if (options.module === ts.ModuleKind.ES6 && languageVersion < 2 /* ES6 */) { programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_compile_modules_into_es2015_when_targeting_ES5_or_lower)); } // Cannot specify module gen that isn't amd or system with --out - if (outFile && options.module && !(options.module === ts.ModuleKind.AMD || options.module === ts.ModuleKind.System)) { - programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile")); + if (outFile) { + if (options.module && !(options.module === ts.ModuleKind.AMD || options.module === ts.ModuleKind.System)) { + programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile")); + } + else if (options.module === undefined && firstExternalModuleSourceFile) { + var span = ts.getErrorSpanForNode(firstExternalModuleSourceFile, firstExternalModuleSourceFile.externalModuleIndicator); + programDiagnostics.add(ts.createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system, options.out ? "out" : "outFile")); + } } // there has to be common source directory if user specified --outdir || --sourceRoot // if user specified --mapRoot, there needs to be common source directory if there would be multiple files being emitted @@ -43384,6 +43539,11 @@ var ts; type: "boolean", description: ts.Diagnostics.Print_this_message }, + { + name: "help", + shortName: "?", + type: "boolean" + }, { name: "init", type: "boolean", @@ -43486,6 +43646,11 @@ var ts; name: "skipDefaultLibCheck", type: "boolean" }, + { + name: "skipLibCheck", + type: "boolean", + description: ts.Diagnostics.Skip_type_checking_of_declaration_files + }, { name: "out", type: "string", @@ -44315,7 +44480,7 @@ var ts; (function (ts) { var NavigateTo; (function (NavigateTo) { - function getNavigateToItems(program, cancellationToken, searchValue, maxResultCount) { + function getNavigateToItems(program, checker, cancellationToken, searchValue, maxResultCount) { var patternMatcher = ts.createPatternMatcher(searchValue); var rawItems = []; // This means "compare in a case insensitive manner." @@ -44354,6 +44519,18 @@ var ts; } } }); + // Remove imports when the imported declaration is already in the list and has the same name. + rawItems = ts.filter(rawItems, function (item) { + var decl = item.declaration; + if (decl.kind === 231 /* ImportClause */ || decl.kind === 234 /* ImportSpecifier */ || decl.kind === 229 /* ImportEqualsDeclaration */) { + var importer = checker.getSymbolAtLocation(decl.name); + var imported = checker.getAliasedSymbol(importer); + return importer.name !== imported.name; + } + else { + return true; + } + }); rawItems.sort(compareNavigateToItems); if (maxResultCount !== undefined) { rawItems = rawItems.slice(0, maxResultCount); @@ -44752,8 +44929,12 @@ var ts; return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.memberSetAccessorElement); case 153 /* IndexSignature */: return createItem(node, "[]", ts.ScriptElementKind.indexSignatureElement); + case 224 /* EnumDeclaration */: + return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.enumElement); case 255 /* EnumMember */: return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.memberVariableElement); + case 222 /* InterfaceDeclaration */: + return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.interfaceElement); case 151 /* CallSignature */: return createItem(node, "()", ts.ScriptElementKind.callSignatureElement); case 152 /* ConstructSignature */: @@ -45714,7 +45895,7 @@ var ts; // To do this, the method will back parse the expression starting at the position required. it will try to parse the current expression as a generic type expression, if it did succeed it // will return the generic identifier that started the expression (e.g. "foo" in "foo= 0; --i) { + for (var i = exclusiveStartPosition - 1; i >= 0; i--) { if (nodeHasTokens(children[i])) { return children[i]; } @@ -47337,12 +47518,11 @@ var ts; if (!isStarted) { scanner.scan(); } - var t; var pos = scanner.getStartPos(); // Read leading trivia and token while (pos < endPos) { - var t_1 = scanner.getToken(); - if (!ts.isTrivia(t_1)) { + var t = scanner.getToken(); + if (!ts.isTrivia(t)) { break; } // consume leading trivia @@ -47350,7 +47530,7 @@ var ts; var item = { pos: pos, end: scanner.getStartPos(), - kind: t_1 + kind: t }; pos = scanner.getStartPos(); if (!leadingTrivia) { @@ -47690,6 +47870,7 @@ var ts; })(formatting = ts.formatting || (ts.formatting = {})); })(ts || (ts = {})); /// +/* tslint:disable:no-null-keyword */ /* @internal */ var ts; (function (ts) { @@ -47951,7 +48132,7 @@ var ts; this.SpaceAfterKeywordInControl = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Keywords, 17 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsControlDeclContext), 2 /* Space */)); this.NoSpaceAfterKeywordInControl = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Keywords, 17 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsControlDeclContext), 8 /* Delete */)); // Open Brace braces after function - //TypeScript: Function can have return types, which can be made of tons of different token kinds + // TypeScript: Function can have return types, which can be made of tons of different token kinds this.NewLineBeforeOpenBraceInFunction = new formatting.Rule(formatting.RuleDescriptor.create2(this.FunctionOpenBraceLeftTokenRange, 15 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclContext, Rules.IsBeforeMultilineBlockContext), 4 /* NewLine */), 1 /* CanDeleteNewLines */); // Open Brace braces after TypeScript module/class/interface this.NewLineBeforeOpenBraceInTypeScriptDeclWithBlock = new formatting.Rule(formatting.RuleDescriptor.create2(this.TypeScriptOpenBraceLeftTokenRange, 15 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsTypeScriptDeclWithBlockContext, Rules.IsBeforeMultilineBlockContext), 4 /* NewLine */), 1 /* CanDeleteNewLines */); @@ -48092,17 +48273,17 @@ var ts; case 220 /* FunctionDeclaration */: case 147 /* MethodDeclaration */: case 146 /* MethodSignature */: - //case SyntaxKind.MemberFunctionDeclaration: + // case SyntaxKind.MemberFunctionDeclaration: case 149 /* GetAccessor */: case 150 /* SetAccessor */: - ///case SyntaxKind.MethodSignature: + // case SyntaxKind.MethodSignature: case 151 /* CallSignature */: case 179 /* FunctionExpression */: case 148 /* Constructor */: case 180 /* ArrowFunction */: - //case SyntaxKind.ConstructorDeclaration: - //case SyntaxKind.SimpleArrowFunctionExpression: - //case SyntaxKind.ParenthesizedArrowFunctionExpression: + // case SyntaxKind.ConstructorDeclaration: + // case SyntaxKind.SimpleArrowFunctionExpression: + // case SyntaxKind.ParenthesizedArrowFunctionExpression: case 222 /* InterfaceDeclaration */: return true; } @@ -48254,6 +48435,7 @@ var ts; })(formatting = ts.formatting || (ts.formatting = {})); })(ts || (ts = {})); /// +/* tslint:disable:no-null-keyword */ /* @internal */ var ts; (function (ts) { @@ -48271,9 +48453,9 @@ var ts; }; RulesMap.prototype.Initialize = function (rules) { this.mapRowLength = 138 /* LastToken */ + 1; - this.map = new Array(this.mapRowLength * this.mapRowLength); //new Array(this.mapRowLength * this.mapRowLength); + this.map = new Array(this.mapRowLength * this.mapRowLength); // new Array(this.mapRowLength * this.mapRowLength); // This array is used only during construction of the rulesbucket in the map - var rulesBucketConstructionStateList = new Array(this.map.length); //new Array(this.map.length); + var rulesBucketConstructionStateList = new Array(this.map.length); // new Array(this.map.length); this.FillRules(rules, rulesBucketConstructionStateList); return this.map; }; @@ -48285,7 +48467,7 @@ var ts; }; RulesMap.prototype.GetRuleBucketIndex = function (row, column) { var rulesBucketIndex = (row * this.mapRowLength) + column; - //Debug.Assert(rulesBucketIndex < this.map.Length, "Trying to access an index outside the array."); + // Debug.Assert(rulesBucketIndex < this.map.Length, "Trying to access an index outside the array."); return rulesBucketIndex; }; RulesMap.prototype.FillRule = function (rule, rulesBucketConstructionStateList) { @@ -48537,6 +48719,7 @@ var ts; /// /// /// +/* tslint:disable:no-null-keyword */ /* @internal */ var ts; (function (ts) { @@ -49058,7 +49241,7 @@ var ts; // if there are any tokens that logically belong to node and interleave child nodes // such tokens will be consumed in processChildNode for for the child that follows them ts.forEachChild(node, function (child) { - processChildNode(child, /*inheritedIndentation*/ -1 /* Unknown */, node, nodeDynamicIndentation, nodeStartLine, undecoratedNodeStartLine, /*isListElement*/ false); + processChildNode(child, /*inheritedIndentation*/ -1 /* Unknown */, node, nodeDynamicIndentation, nodeStartLine, undecoratedNodeStartLine, /*isListItem*/ false); }, function (nodes) { processChildNodes(nodes, node, nodeStartLine, nodeDynamicIndentation); }); @@ -49149,7 +49332,7 @@ var ts; var inheritedIndentation = -1 /* Unknown */; for (var i = 0; i < nodes.length; i++) { var child = nodes[i]; - inheritedIndentation = processChildNode(child, inheritedIndentation, node, listDynamicIndentation, startLine, startLine, /*isListElement*/ true, /*isFirstListItem*/ i === 0); + inheritedIndentation = processChildNode(child, inheritedIndentation, node, listDynamicIndentation, startLine, startLine, /*isListItem*/ true, /*isFirstListItem*/ i === 0); } if (listEndToken !== 0 /* Unknown */) { if (formattingScanner.isOnToken()) { @@ -49279,7 +49462,7 @@ var ts; // Handle the case where the next line is moved to be the end of this line. // In this case we don't indent the next line in the next pass. if (currentParent.getStart(sourceFile) === currentItem.pos) { - dynamicIndentation.recomputeIndentation(/*lineAdded*/ false); + dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ false); } } else if (rule.Operation.Action & 4 /* NewLine */ && currentStartLine === previousStartLine) { @@ -49288,7 +49471,7 @@ var ts; // In this case we indent token2 in the next pass but we set // sameLineIndent flag to notify the indenter that the indentation is within the line. if (currentParent.getStart(sourceFile) === currentItem.pos) { - dynamicIndentation.recomputeIndentation(/*lineAdded*/ true); + dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ true); } } // We need to trim trailing whitespace between the tokens if they were on different lines, and no rule was applied to put them on the same line @@ -49336,7 +49519,7 @@ var ts; else { parts = []; var startPos = commentRange.pos; - for (var line = startLine; line < endLine; ++line) { + for (var line = startLine; line < endLine; line++) { var endOfLine = ts.getEndLinePosition(line, sourceFile); parts.push({ pos: startPos, end: endOfLine }); startPos = ts.getStartPositionOfLine(line + 1, sourceFile); @@ -49355,7 +49538,7 @@ var ts; } // shift all parts on the delta size var delta = indentation - nonWhitespaceColumnInFirstPart.column; - for (var i = startIndex, len = parts.length; i < len; ++i, ++startLine) { + for (var i = startIndex, len = parts.length; i < len; i++, startLine++) { var startLinePos_1 = ts.getStartPositionOfLine(startLine, sourceFile); var nonWhitespaceCharacterAndColumn = i === 0 ? nonWhitespaceColumnInFirstPart @@ -49371,7 +49554,7 @@ var ts; } } function trimTrailingWhitespacesForLines(line1, line2, range) { - for (var line = line1; line < line2; ++line) { + for (var line = line1; line < line2; line++) { var lineStartPosition = ts.getStartPositionOfLine(line, sourceFile); var lineEndPosition = ts.getEndLinePosition(line, sourceFile); // do not trim whitespaces in comments or template expression @@ -49422,7 +49605,6 @@ var ts; } } function applyRuleEdits(rule, previousRange, previousStartLine, currentRange, currentStartLine) { - var between; switch (rule.Operation.Action) { case 1 /* Ignore */: // no action required @@ -49459,14 +49641,6 @@ var ts; } } } - function isSomeBlock(kind) { - switch (kind) { - case 199 /* Block */: - case 226 /* ModuleBlock */: - return true; - } - return false; - } function getOpenTokenForList(node, list) { switch (node.kind) { case 148 /* Constructor */: @@ -49525,7 +49699,7 @@ var ts; internedTabsIndentation = []; } if (internedTabsIndentation[tabs] === undefined) { - internedTabsIndentation[tabs] = tabString = repeat('\t', tabs); + internedTabsIndentation[tabs] = tabString = repeat("\t", tabs); } else { tabString = internedTabsIndentation[tabs]; @@ -49550,7 +49724,7 @@ var ts; } function repeat(value, count) { var s = ""; - for (var i = 0; i < count; ++i) { + for (var i = 0; i < count; i++) { s += value; } return s; @@ -49866,7 +50040,7 @@ var ts; // walk toward the start of the list starting from current node and check if the line is the same for all items. // if end line for item [i - 1] differs from the start line for item [i] - find column of the first non-whitespace character on the line of item [i] var lineAndCharacter = getStartLineAndCharacterForNode(node, sourceFile); - for (var i = index - 1; i >= 0; --i) { + for (var i = index - 1; i >= 0; i--) { if (list[i].kind === 24 /* CommaToken */) { continue; } @@ -49893,7 +50067,7 @@ var ts; function findFirstNonWhitespaceCharacterAndColumn(startPos, endPos, sourceFile, options) { var character = 0; var column = 0; - for (var pos = startPos; pos < endPos; ++pos) { + for (var pos = startPos; pos < endPos; pos++) { var ch = sourceFile.text.charCodeAt(pos); if (!ts.isWhiteSpace(ch)) { break; @@ -49987,7 +50161,7 @@ var ts; Function returns true when the parent node should indent the given child by an explicit rule */ function shouldIndentChildNode(parent, child) { - return nodeContentIsAlwaysIndented(parent.kind) || nodeWillIndentChild(parent, child, false); + return nodeContentIsAlwaysIndented(parent.kind) || nodeWillIndentChild(parent, child, /*indentByDefault*/ false); } SmartIndenter.shouldIndentChildNode = shouldIndentChildNode; })(SmartIndenter = formatting.SmartIndenter || (formatting.SmartIndenter = {})); @@ -50809,49 +50983,55 @@ var ts; (function (ScriptElementKind) { ScriptElementKind.unknown = ""; ScriptElementKind.warning = "warning"; - // predefined type (void) or keyword (class) + /** predefined type (void) or keyword (class) */ ScriptElementKind.keyword = "keyword"; - // top level script node + /** top level script node */ ScriptElementKind.scriptElement = "script"; - // module foo {} + /** module foo {} */ ScriptElementKind.moduleElement = "module"; - // class X {} + /** class X {} */ ScriptElementKind.classElement = "class"; - // var x = class X {} + /** var x = class X {} */ ScriptElementKind.localClassElement = "local class"; - // interface Y {} + /** interface Y {} */ ScriptElementKind.interfaceElement = "interface"; - // type T = ... + /** type T = ... */ ScriptElementKind.typeElement = "type"; - // enum E + /** enum E */ ScriptElementKind.enumElement = "enum"; - // Inside module and script only - // const v = .. + /** + * Inside module and script only + * const v = .. + */ ScriptElementKind.variableElement = "var"; - // Inside function + /** Inside function */ ScriptElementKind.localVariableElement = "local var"; - // Inside module and script only - // function f() { } + /** + * Inside module and script only + * function f() { } + */ ScriptElementKind.functionElement = "function"; - // Inside function + /** Inside function */ ScriptElementKind.localFunctionElement = "local function"; - // class X { [public|private]* foo() {} } + /** class X { [public|private]* foo() {} } */ ScriptElementKind.memberFunctionElement = "method"; - // class X { [public|private]* [get|set] foo:number; } + /** class X { [public|private]* [get|set] foo:number; } */ ScriptElementKind.memberGetAccessorElement = "getter"; ScriptElementKind.memberSetAccessorElement = "setter"; - // class X { [public|private]* foo:number; } - // interface Y { foo:number; } + /** + * class X { [public|private]* foo:number; } + * interface Y { foo:number; } + */ ScriptElementKind.memberVariableElement = "property"; - // class X { constructor() { } } + /** class X { constructor() { } } */ ScriptElementKind.constructorImplementationElement = "constructor"; - // interface Y { ():number; } + /** interface Y { ():number; } */ ScriptElementKind.callSignatureElement = "call"; - // interface Y { []:number; } + /** interface Y { []:number; } */ ScriptElementKind.indexSignatureElement = "index"; - // interface Y { new():Y; } + /** interface Y { new():Y; } */ ScriptElementKind.constructSignatureElement = "construct"; - // function foo(*Y*: string) + /** function foo(*Y*: string) */ ScriptElementKind.parameterElement = "parameter"; ScriptElementKind.typeParameterElement = "type parameter"; ScriptElementKind.primitiveType = "primitive type"; @@ -52236,9 +52416,9 @@ var ts; // Check if the caret is at the end of an identifier; this is a partial identifier that we want to complete: e.g. a.toS| // Skip this partial identifier and adjust the contextToken to the token that precedes it. if (contextToken && position <= contextToken.end && ts.isWord(contextToken.kind)) { - var start_6 = new Date().getTime(); + var start_5 = new Date().getTime(); contextToken = ts.findPrecedingToken(contextToken.getFullStart(), sourceFile); - log("getCompletionData: Get previous token 2: " + (new Date().getTime() - start_6)); + log("getCompletionData: Get previous token 2: " + (new Date().getTime() - start_5)); } // Find the node where completion is requested on. // Also determine whether we are trying to complete with members of that node @@ -52518,13 +52698,13 @@ var ts; || contextToken.kind === 166 /* StringLiteralType */ || contextToken.kind === 10 /* RegularExpressionLiteral */ || ts.isTemplateLiteralKind(contextToken.kind)) { - var start_7 = contextToken.getStart(); + var start_6 = contextToken.getStart(); var end = contextToken.getEnd(); // To be "in" one of these literals, the position has to be: // 1. entirely within the token text. // 2. at the end position of an unterminated token. // 3. at the end of a regular expression (due to trailing flags like '/foo/g'). - if (start_7 < position && position < end) { + if (start_6 < position && position < end) { return true; } if (position === end) { @@ -53759,8 +53939,7 @@ var ts; } function getDocumentHighlights(fileName, position, filesToSearch) { synchronizeHostData(); - filesToSearch = ts.map(filesToSearch, ts.normalizeSlashes); - var sourceFilesToSearch = ts.filter(program.getSourceFiles(), function (f) { return ts.contains(filesToSearch, f.fileName); }); + var sourceFilesToSearch = ts.map(filesToSearch, function (f) { return program.getSourceFile(f); }); var sourceFile = getValidSourceFile(fileName); var node = ts.getTouchingWord(sourceFile, position); if (!node) { @@ -55150,7 +55329,8 @@ var ts; /// NavigateTo function getNavigateToItems(searchValue, maxResultCount) { synchronizeHostData(); - return ts.NavigateTo.getNavigateToItems(program, cancellationToken, searchValue, maxResultCount); + var checker = getProgram().getTypeChecker(); + return ts.NavigateTo.getNavigateToItems(program, checker, cancellationToken, searchValue, maxResultCount); } function getEmitOutput(fileName) { synchronizeHostData(); @@ -57559,6 +57739,9 @@ var ts; LanguageServiceShimHostAdapter.prototype.getCurrentDirectory = function () { return this.shimHost.getCurrentDirectory(); }; + LanguageServiceShimHostAdapter.prototype.getDirectories = function (path) { + return this.shimHost.getDirectories(path); + }; LanguageServiceShimHostAdapter.prototype.getDefaultLibFileName = function (options) { return this.shimHost.getDefaultLibFileName(JSON.stringify(options)); }; diff --git a/lib/typescriptServices.d.ts b/lib/typescriptServices.d.ts index cd459201d8b..67530e211bc 100644 --- a/lib/typescriptServices.d.ts +++ b/lib/typescriptServices.d.ts @@ -261,7 +261,7 @@ declare namespace ts { ModuleDeclaration = 225, ModuleBlock = 226, CaseBlock = 227, - GlobalModuleExportDeclaration = 228, + NamespaceExportDeclaration = 228, ImportEqualsDeclaration = 229, ImportDeclaration = 230, ImportClause = 231, @@ -934,7 +934,7 @@ declare namespace ts { interface NamespaceImport extends Declaration { name: Identifier; } - interface GlobalModuleExportDeclaration extends DeclarationStatement { + interface NamespaceExportDeclaration extends DeclarationStatement { name: Identifier; moduleReference: LiteralLikeNode; } @@ -1329,7 +1329,7 @@ declare namespace ts { FunctionScopedVariableExcludes = 107454, BlockScopedVariableExcludes = 107455, ParameterExcludes = 107455, - PropertyExcludes = 107455, + PropertyExcludes = 0, EnumMemberExcludes = 107455, FunctionExcludes = 106927, ClassExcludes = 899519, @@ -1554,6 +1554,7 @@ declare namespace ts { allowJs?: boolean; noImplicitUseStrict?: boolean; strictNullChecks?: boolean; + skipLibCheck?: boolean; listEmittedFiles?: boolean; lib?: string[]; types?: string[]; @@ -1627,6 +1628,7 @@ declare namespace ts { trace?(s: string): void; directoryExists?(directoryName: string): boolean; realpath?(path: string): string; + getCurrentDirectory?(): string; } interface ResolvedModule { resolvedFileName: string; @@ -1650,6 +1652,7 @@ declare namespace ts { getCancellationToken?(): CancellationToken; getDefaultLibFileName(options: CompilerOptions): string; getDefaultLibLocation?(): string; + getDefaultTypeDirectiveNames?(rootPath: string): string[]; writeFile: WriteFileCallback; getCurrentDirectory(): string; getCanonicalFileName(fileName: string): string; @@ -1693,6 +1696,7 @@ declare namespace ts { createDirectory(path: string): void; getExecutingFilePath(): string; getCurrentDirectory(): string; + getDirectories(path: string): string[]; readDirectory(path: string, extension?: string, exclude?: string[]): string[]; getModifiedTime?(path: string): Date; createHash?(data: string): string; @@ -1812,6 +1816,7 @@ declare namespace ts { function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost; function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; function flattenDiagnosticMessageText(messageText: string | DiagnosticMessageChain, newLine: string): string; + function getDefaultTypeDirectiveNames(options: CompilerOptions, rootFiles: string[], host: CompilerHost): string[]; function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program; } declare namespace ts { @@ -2345,26 +2350,55 @@ declare namespace ts { namespace ScriptElementKind { const unknown: string; const warning: string; + /** predefined type (void) or keyword (class) */ const keyword: string; + /** top level script node */ const scriptElement: string; + /** module foo {} */ const moduleElement: string; + /** class X {} */ const classElement: string; + /** var x = class X {} */ const localClassElement: string; + /** interface Y {} */ const interfaceElement: string; + /** type T = ... */ const typeElement: string; + /** enum E */ const enumElement: string; + /** + * Inside module and script only + * const v = .. + */ const variableElement: string; + /** Inside function */ const localVariableElement: string; + /** + * Inside module and script only + * function f() { } + */ const functionElement: string; + /** Inside function */ const localFunctionElement: string; + /** class X { [public|private]* foo() {} } */ const memberFunctionElement: string; + /** class X { [public|private]* [get|set] foo:number; } */ const memberGetAccessorElement: string; const memberSetAccessorElement: string; + /** + * class X { [public|private]* foo:number; } + * interface Y { foo:number; } + */ const memberVariableElement: string; + /** class X { constructor() { } } */ const constructorImplementationElement: string; + /** interface Y { ():number; } */ const callSignatureElement: string; + /** interface Y { []:number; } */ const indexSignatureElement: string; + /** interface Y { new():Y; } */ const constructSignatureElement: string; + /** function foo(*Y*: string) */ const parameterElement: string; const typeParameterElement: string; const primitiveType: string; diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index e78eda7b0bb..cf982a3ede9 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -271,7 +271,7 @@ var ts; SyntaxKind[SyntaxKind["ModuleDeclaration"] = 225] = "ModuleDeclaration"; SyntaxKind[SyntaxKind["ModuleBlock"] = 226] = "ModuleBlock"; SyntaxKind[SyntaxKind["CaseBlock"] = 227] = "CaseBlock"; - SyntaxKind[SyntaxKind["GlobalModuleExportDeclaration"] = 228] = "GlobalModuleExportDeclaration"; + SyntaxKind[SyntaxKind["NamespaceExportDeclaration"] = 228] = "NamespaceExportDeclaration"; SyntaxKind[SyntaxKind["ImportEqualsDeclaration"] = 229] = "ImportEqualsDeclaration"; SyntaxKind[SyntaxKind["ImportDeclaration"] = 230] = "ImportDeclaration"; SyntaxKind[SyntaxKind["ImportClause"] = 231] = "ImportClause"; @@ -561,7 +561,7 @@ var ts; // they can not merge with anything in the value space SymbolFlags[SymbolFlags["BlockScopedVariableExcludes"] = 107455] = "BlockScopedVariableExcludes"; SymbolFlags[SymbolFlags["ParameterExcludes"] = 107455] = "ParameterExcludes"; - SymbolFlags[SymbolFlags["PropertyExcludes"] = 107455] = "PropertyExcludes"; + SymbolFlags[SymbolFlags["PropertyExcludes"] = 0] = "PropertyExcludes"; SymbolFlags[SymbolFlags["EnumMemberExcludes"] = 107455] = "EnumMemberExcludes"; SymbolFlags[SymbolFlags["FunctionExcludes"] = 106927] = "FunctionExcludes"; SymbolFlags[SymbolFlags["ClassExcludes"] = 899519] = "ClassExcludes"; @@ -1841,6 +1841,10 @@ var ts; } return result.sort(); } + function getDirectories(path) { + var folder = fso.GetFolder(path); + return getNames(folder.subfolders); + } function readDirectory(path, extension, exclude) { var result = []; exclude = ts.map(exclude, function (s) { return getCanonicalPath(ts.combinePaths(path, s)); }); @@ -1895,6 +1899,7 @@ var ts; getCurrentDirectory: function () { return new ActiveXObject("WScript.Shell").CurrentDirectory; }, + getDirectories: getDirectories, readDirectory: readDirectory, exit: function (exitCode) { try { @@ -2057,6 +2062,9 @@ var ts; function directoryExists(path) { return fileSystemEntryExists(path, 1 /* Directory */); } + function getDirectories(path) { + return ts.filter(_fs.readdirSync(path), function (p) { return fileSystemEntryExists(ts.combinePaths(path, p), 1 /* Directory */); }); + } function readDirectory(path, extension, exclude) { var result = []; exclude = ts.map(exclude, function (s) { return getCanonicalPath(ts.combinePaths(path, s)); }); @@ -2157,6 +2165,7 @@ var ts; getCurrentDirectory: function () { return process.cwd(); }, + getDirectories: getDirectories, readDirectory: readDirectory, getModifiedTime: function (path) { try { @@ -2209,6 +2218,7 @@ var ts; createDirectory: ChakraHost.createDirectory, getExecutingFilePath: function () { return ChakraHost.executingFile; }, getCurrentDirectory: function () { return ChakraHost.currentDirectory; }, + getDirectories: ChakraHost.getDirectories, readDirectory: ChakraHost.readDirectory, exit: ChakraHost.quit, realpath: realpath @@ -2347,7 +2357,7 @@ var ts; or_expected: { code: 1144, category: ts.DiagnosticCategory.Error, key: "or_expected_1144", message: "'{' or ';' expected." }, Declaration_expected: { code: 1146, category: ts.DiagnosticCategory.Error, key: "Declaration_expected_1146", message: "Declaration expected." }, Import_declarations_in_a_namespace_cannot_reference_a_module: { code: 1147, category: ts.DiagnosticCategory.Error, key: "Import_declarations_in_a_namespace_cannot_reference_a_module_1147", message: "Import declarations in a namespace cannot reference a module." }, - Cannot_compile_modules_unless_the_module_flag_is_provided_with_a_valid_module_type_Consider_setting_the_module_compiler_option_in_a_tsconfig_json_file: { code: 1148, category: ts.DiagnosticCategory.Error, key: "Cannot_compile_modules_unless_the_module_flag_is_provided_with_a_valid_module_type_Consider_setting__1148", message: "Cannot compile modules unless the '--module' flag is provided with a valid module type. Consider setting the 'module' compiler option in a 'tsconfig.json' file." }, + Cannot_use_imports_exports_or_module_augmentations_when_module_is_none: { code: 1148, category: ts.DiagnosticCategory.Error, key: "Cannot_use_imports_exports_or_module_augmentations_when_module_is_none_1148", message: "Cannot use imports, exports, or module augmentations when '--module' is 'none'." }, File_name_0_differs_from_already_included_file_name_1_only_in_casing: { code: 1149, category: ts.DiagnosticCategory.Error, key: "File_name_0_differs_from_already_included_file_name_1_only_in_casing_1149", message: "File name '{0}' differs from already included file name '{1}' only in casing" }, new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead: { code: 1150, category: ts.DiagnosticCategory.Error, key: "new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead_1150", message: "'new T[]' cannot be used to create an array. Use 'new Array()' instead." }, const_declarations_must_be_initialized: { code: 1155, category: ts.DiagnosticCategory.Error, key: "const_declarations_must_be_initialized_1155", message: "'const' declarations must be initialized" }, @@ -2717,6 +2727,8 @@ var ts; this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation: { code: 2683, category: ts.DiagnosticCategory.Error, key: "this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_2683", message: "'this' implicitly has type 'any' because it does not have a type annotation." }, The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1: { code: 2684, category: ts.DiagnosticCategory.Error, key: "The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1_2684", message: "The 'this' context of type '{0}' is not assignable to method's 'this' of type '{1}'." }, The_this_types_of_each_signature_are_incompatible: { code: 2685, category: ts.DiagnosticCategory.Error, key: "The_this_types_of_each_signature_are_incompatible_2685", message: "The 'this' types of each signature are incompatible." }, + Identifier_0_must_be_imported_from_a_module: { code: 2686, category: ts.DiagnosticCategory.Error, key: "Identifier_0_must_be_imported_from_a_module_2686", message: "Identifier '{0}' must be imported from a module" }, + All_declarations_of_0_must_have_identical_modifiers: { code: 2687, category: ts.DiagnosticCategory.Error, key: "All_declarations_of_0_must_have_identical_modifiers_2687", message: "All declarations of '{0}' must have identical modifiers." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: ts.DiagnosticCategory.Error, key: "Import_declaration_0_is_using_private_name_1_4000", message: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: ts.DiagnosticCategory.Error, key: "Type_parameter_0_of_exported_class_has_or_is_using_private_name_1_4002", message: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: ts.DiagnosticCategory.Error, key: "Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1_4004", message: "Type parameter '{0}' of exported interface has or is using private name '{1}'." }, @@ -2810,7 +2822,7 @@ var ts; Option_paths_cannot_be_used_without_specifying_baseUrl_option: { code: 5060, category: ts.DiagnosticCategory.Error, key: "Option_paths_cannot_be_used_without_specifying_baseUrl_option_5060", message: "Option 'paths' cannot be used without specifying '--baseUrl' option." }, Pattern_0_can_have_at_most_one_Asterisk_character: { code: 5061, category: ts.DiagnosticCategory.Error, key: "Pattern_0_can_have_at_most_one_Asterisk_character_5061", message: "Pattern '{0}' can have at most one '*' character" }, Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character: { code: 5062, category: ts.DiagnosticCategory.Error, key: "Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character_5062", message: "Substitution '{0}' in pattern '{1}' in can have at most one '*' character" }, - Substututions_for_pattern_0_should_be_an_array: { code: 5063, category: ts.DiagnosticCategory.Error, key: "Substututions_for_pattern_0_should_be_an_array_5063", message: "Substututions for pattern '{0}' should be an array." }, + Substitutions_for_pattern_0_should_be_an_array: { code: 5063, category: ts.DiagnosticCategory.Error, key: "Substitutions_for_pattern_0_should_be_an_array_5063", message: "Substitutions for pattern '{0}' should be an array." }, Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2: { code: 5064, category: ts.DiagnosticCategory.Error, key: "Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2_5064", message: "Substitution '{0}' for pattern '{1}' has incorrect type, expected 'string', got '{2}'." }, Concatenate_and_emit_output_to_single_file: { code: 6001, category: ts.DiagnosticCategory.Message, key: "Concatenate_and_emit_output_to_single_file_6001", message: "Concatenate and emit output to single file." }, Generates_corresponding_d_ts_file: { code: 6002, category: ts.DiagnosticCategory.Message, key: "Generates_corresponding_d_ts_file_6002", message: "Generates corresponding '.d.ts' file." }, @@ -2823,6 +2835,7 @@ var ts; Do_not_emit_comments_to_output: { code: 6009, category: ts.DiagnosticCategory.Message, key: "Do_not_emit_comments_to_output_6009", message: "Do not emit comments to output." }, Do_not_emit_outputs: { code: 6010, category: ts.DiagnosticCategory.Message, key: "Do_not_emit_outputs_6010", message: "Do not emit outputs." }, Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking: { code: 6011, category: ts.DiagnosticCategory.Message, key: "Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011", message: "Allow default imports from modules with no default export. This does not affect code emit, just typechecking." }, + Skip_type_checking_of_declaration_files: { code: 6012, category: ts.DiagnosticCategory.Message, key: "Skip_type_checking_of_declaration_files_6012", message: "Skip type checking of declaration files." }, Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015: { code: 6015, category: ts.DiagnosticCategory.Message, key: "Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015_6015", message: "Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES2015'" }, Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015: { code: 6016, category: ts.DiagnosticCategory.Message, key: "Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015_6016", message: "Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'" }, Print_this_message: { code: 6017, category: ts.DiagnosticCategory.Message, key: "Print_this_message_6017", message: "Print this message." }, @@ -2924,6 +2937,7 @@ var ts; Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set: { code: 6128, category: ts.DiagnosticCategory.Message, key: "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set_6128", message: "======== Resolving type reference directive '{0}', containing file not set, root directory not set. ========" }, The_config_file_0_found_doesn_t_contain_any_source_files: { code: 6129, category: ts.DiagnosticCategory.Error, key: "The_config_file_0_found_doesn_t_contain_any_source_files_6129", message: "The config file '{0}' found doesn't contain any source files." }, Resolving_real_path_for_0_result_1: { code: 6130, category: ts.DiagnosticCategory.Message, key: "Resolving_real_path_for_0_result_1_6130", message: "Resolving real path for '{0}', result '{1}'" }, + Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system: { code: 6131, category: ts.DiagnosticCategory.Error, key: "Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system_6131", message: "Cannot compile modules using option '{0}' unless the '--module' flag is 'amd' or 'system'." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable_0_implicitly_has_an_1_type_7005", message: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter_0_implicitly_has_an_1_type_7006", message: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member_0_implicitly_has_an_1_type_7008", message: "Member '{0}' implicitly has an '{1}' type." }, @@ -6172,7 +6186,7 @@ var ts; // export default ... function isAliasSymbolDeclaration(node) { return node.kind === 229 /* ImportEqualsDeclaration */ || - node.kind === 228 /* GlobalModuleExportDeclaration */ || + node.kind === 228 /* NamespaceExportDeclaration */ || node.kind === 231 /* ImportClause */ && !!node.name || node.kind === 232 /* NamespaceImport */ || node.kind === 234 /* ImportSpecifier */ || @@ -6301,7 +6315,7 @@ var ts; } ts.isWellKnownSymbolSyntactically = isWellKnownSymbolSyntactically; function getPropertyNameForPropertyNameNode(name) { - if (name.kind === 69 /* Identifier */ || name.kind === 9 /* StringLiteral */ || name.kind === 8 /* NumericLiteral */) { + if (name.kind === 69 /* Identifier */ || name.kind === 9 /* StringLiteral */ || name.kind === 8 /* NumericLiteral */ || name.kind === 142 /* Parameter */) { return name.text; } if (name.kind === 140 /* ComputedPropertyName */) { @@ -7773,7 +7787,7 @@ var ts; case 231 /* ImportClause */: return visitNode(cbNode, node.name) || visitNode(cbNode, node.namedBindings); - case 228 /* GlobalModuleExportDeclaration */: + case 228 /* NamespaceExportDeclaration */: return visitNode(cbNode, node.name); case 232 /* NamespaceImport */: return visitNode(cbNode, node.name); @@ -12182,7 +12196,7 @@ var ts; return nextToken() === 39 /* SlashToken */; } function parseGlobalModuleExportDeclaration(fullStart, decorators, modifiers) { - var exportDeclaration = createNode(228 /* GlobalModuleExportDeclaration */, fullStart); + var exportDeclaration = createNode(228 /* NamespaceExportDeclaration */, fullStart); exportDeclaration.decorators = decorators; exportDeclaration.modifiers = modifiers; parseExpected(116 /* AsKeyword */); @@ -15018,10 +15032,10 @@ var ts; case 145 /* PropertyDeclaration */: case 144 /* PropertySignature */: case 266 /* JSDocRecordMember */: - return bindPropertyOrMethodOrAccessor(node, 4 /* Property */ | (node.questionToken ? 536870912 /* Optional */ : 0 /* None */), 107455 /* PropertyExcludes */); + return bindPropertyOrMethodOrAccessor(node, 4 /* Property */ | (node.questionToken ? 536870912 /* Optional */ : 0 /* None */), 0 /* PropertyExcludes */); case 253 /* PropertyAssignment */: case 254 /* ShorthandPropertyAssignment */: - return bindPropertyOrMethodOrAccessor(node, 4 /* Property */, 107455 /* PropertyExcludes */); + return bindPropertyOrMethodOrAccessor(node, 4 /* Property */, 0 /* PropertyExcludes */); case 255 /* EnumMember */: return bindPropertyOrMethodOrAccessor(node, 8 /* EnumMember */, 107455 /* EnumMemberExcludes */); case 247 /* JsxSpreadAttribute */: @@ -15037,7 +15051,7 @@ var ts; // as other properties in the object literal. So we use SymbolFlags.PropertyExcludes // so that it will conflict with any other object literal members with the same // name. - return bindPropertyOrMethodOrAccessor(node, 8192 /* Method */ | (node.questionToken ? 536870912 /* Optional */ : 0 /* None */), ts.isObjectLiteralMethod(node) ? 107455 /* PropertyExcludes */ : 99263 /* MethodExcludes */); + return bindPropertyOrMethodOrAccessor(node, 8192 /* Method */ | (node.questionToken ? 536870912 /* Optional */ : 0 /* None */), ts.isObjectLiteralMethod(node) ? 0 /* PropertyExcludes */ : 99263 /* MethodExcludes */); case 220 /* FunctionDeclaration */: return bindFunctionDeclaration(node); case 148 /* Constructor */: @@ -15081,8 +15095,8 @@ var ts; case 234 /* ImportSpecifier */: case 238 /* ExportSpecifier */: return declareSymbolAndAddToSymbolTable(node, 8388608 /* Alias */, 8388608 /* AliasExcludes */); - case 228 /* GlobalModuleExportDeclaration */: - return bindGlobalModuleExportDeclaration(node); + case 228 /* NamespaceExportDeclaration */: + return bindNamespaceExportDeclaration(node); case 231 /* ImportClause */: return bindImportClause(node); case 236 /* ExportDeclaration */: @@ -15120,14 +15134,14 @@ var ts; } else if (boundExpression.kind === 69 /* Identifier */ && node.kind === 235 /* ExportAssignment */) { // An export default clause with an identifier exports all meanings of that identifier - declareSymbol(container.symbol.exports, container.symbol, node, 8388608 /* Alias */, 107455 /* PropertyExcludes */ | 8388608 /* AliasExcludes */); + declareSymbol(container.symbol.exports, container.symbol, node, 8388608 /* Alias */, 0 /* PropertyExcludes */ | 8388608 /* AliasExcludes */); } else { // An export default clause with an expression exports a value - declareSymbol(container.symbol.exports, container.symbol, node, 4 /* Property */, 107455 /* PropertyExcludes */ | 8388608 /* AliasExcludes */); + declareSymbol(container.symbol.exports, container.symbol, node, 4 /* Property */, 0 /* PropertyExcludes */ | 8388608 /* AliasExcludes */); } } - function bindGlobalModuleExportDeclaration(node) { + function bindNamespaceExportDeclaration(node) { if (node.modifiers && node.modifiers.length) { file.bindDiagnostics.push(ts.createDiagnosticForNode(node, ts.Diagnostics.Modifiers_cannot_appear_here)); } @@ -15186,7 +15200,7 @@ var ts; if (container.kind === 179 /* FunctionExpression */ || container.kind === 220 /* FunctionDeclaration */) { container.symbol.members = container.symbol.members || {}; // It's acceptable for multiple 'this' assignments of the same identifier to occur - declareSymbol(container.symbol.members, container.symbol, node, 4 /* Property */, 107455 /* PropertyExcludes */ & ~4 /* Property */); + declareSymbol(container.symbol.members, container.symbol, node, 4 /* Property */, 0 /* PropertyExcludes */ & ~4 /* Property */); } } function bindPrototypePropertyAssignment(node) { @@ -15209,7 +15223,7 @@ var ts; funcSymbol.members = {}; } // Declare the method/property - declareSymbol(funcSymbol.members, funcSymbol, leftSideOfAssignment, 4 /* Property */, 107455 /* PropertyExcludes */); + declareSymbol(funcSymbol.members, funcSymbol, leftSideOfAssignment, 4 /* Property */, 0 /* PropertyExcludes */); } function bindCallExpression(node) { // We're only inspecting call expressions to detect CommonJS modules, so we can skip @@ -15310,7 +15324,7 @@ var ts; // containing class. if (ts.isParameterPropertyDeclaration(node)) { var classDeclaration = node.parent.parent; - declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4 /* Property */, 107455 /* PropertyExcludes */); + declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4 /* Property */, 0 /* PropertyExcludes */); } } function bindFunctionDeclaration(node) { @@ -15696,7 +15710,7 @@ var ts; if (flags & 1 /* FunctionScopedVariable */) result |= 107454 /* FunctionScopedVariableExcludes */; if (flags & 4 /* Property */) - result |= 107455 /* PropertyExcludes */; + result |= 0 /* PropertyExcludes */; if (flags & 8 /* EnumMember */) result |= 107455 /* EnumMemberExcludes */; if (flags & 16 /* Function */) @@ -15982,6 +15996,7 @@ var ts; var propertyWithInvalidInitializer; var errorLocation = location; var grandparent; + var isInExternalModule = false; loop: while (location) { // Locals of a source file are not in scope (because they get merged into the global symbol table) if (location.locals && !isGlobalSourceFile(location)) { @@ -16024,6 +16039,7 @@ var ts; case 256 /* SourceFile */: if (!ts.isExternalOrCommonJsModule(location)) break; + isInExternalModule = true; case 225 /* ModuleDeclaration */: var moduleExports = getSymbolOfNode(location).exports; if (location.kind === 256 /* SourceFile */ || ts.isAmbientModule(location)) { @@ -16207,6 +16223,13 @@ var ts; checkResolvedBlockScopedVariable(exportOrLocalSymbol, errorLocation); } } + // If we're in an external module, we can't reference symbols created from UMD export declarations + if (result && isInExternalModule) { + var decls = result.declarations; + if (decls && decls.length === 1 && decls[0].kind === 228 /* NamespaceExportDeclaration */) { + error(errorLocation, ts.Diagnostics.Identifier_0_must_be_imported_from_a_module, name); + } + } } return result; } @@ -16409,7 +16432,7 @@ var ts; return getTargetOfExportSpecifier(node); case 235 /* ExportAssignment */: return getTargetOfExportAssignment(node); - case 228 /* GlobalModuleExportDeclaration */: + case 228 /* NamespaceExportDeclaration */: return getTargetOfGlobalModuleExportDeclaration(node); } } @@ -17883,7 +17906,7 @@ var ts; // assigned by contextual typing. function getTypeForBindingElementParent(node) { var symbol = getSymbolOfNode(node); - return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node); + return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node, /*includeOptionality*/ false); } function getTextOfPropertyName(name) { switch (name.kind) { @@ -18009,7 +18032,7 @@ var ts; return strictNullChecks && optional ? addNullableKind(type, 32 /* Undefined */) : type; } // Return the inferred type for a variable, parameter, or property declaration - function getTypeForVariableLikeDeclaration(declaration) { + function getTypeForVariableLikeDeclaration(declaration, includeOptionality) { if (declaration.flags & 134217728 /* JavaScriptFile */) { // If this is a variable in a JavaScript file, then use the JSDoc type (if it has // one as its type), otherwise fallback to the below standard TS codepaths to @@ -18035,7 +18058,7 @@ var ts; } // Use type from type annotation if one is present if (declaration.type) { - return addOptionality(getTypeFromTypeNode(declaration.type), /*optional*/ !!declaration.questionToken); + return addOptionality(getTypeFromTypeNode(declaration.type), /*optional*/ declaration.questionToken && includeOptionality); } if (declaration.kind === 142 /* Parameter */) { var func = declaration.parent; @@ -18056,12 +18079,12 @@ var ts; ? getContextuallyTypedThisType(func) : getContextuallyTypedParameterType(declaration); if (type) { - return addOptionality(type, /*optional*/ !!declaration.questionToken); + return addOptionality(type, /*optional*/ declaration.questionToken && includeOptionality); } } // Use the type of the initializer expression if one is present if (declaration.initializer) { - return addOptionality(checkExpressionCached(declaration.initializer), /*optional*/ !!declaration.questionToken); + return addOptionality(checkExpressionCached(declaration.initializer), /*optional*/ declaration.questionToken && includeOptionality); } // If it is a short-hand property assignment, use the type of the identifier if (declaration.kind === 254 /* ShorthandPropertyAssignment */) { @@ -18155,7 +18178,7 @@ var ts; // binding pattern [x, s = ""]. Because the contextual type is a tuple type, the resulting type of [1, "one"] is the // tuple type [number, string]. Thus, the type inferred for 'x' is number and the type inferred for 's' is string. function getWidenedTypeForVariableLikeDeclaration(declaration, reportErrors) { - var type = getTypeForVariableLikeDeclaration(declaration); + var type = getTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ true); if (type) { if (reportErrors) { reportErrorsFromWidening(declaration, type); @@ -20719,7 +20742,7 @@ var ts; return isIdenticalTo(source, target); } if (!(target.flags & 134217728 /* Never */)) { - if (target.flags & 1 /* Any */) + if (target.flags & 1 /* Any */ || source.flags & 134217728 /* Never */) return -1 /* True */; if (source.flags & 32 /* Undefined */) { if (!strictNullChecks || target.flags & (32 /* Undefined */ | 16 /* Void */) || source === emptyArrayElementType) @@ -20739,7 +20762,7 @@ var ts; if (source.flags & 256 /* StringLiteral */ && target === stringType) return -1 /* True */; if (relation === assignableRelation || relation === comparableRelation) { - if (source.flags & (1 /* Any */ | 134217728 /* Never */)) + if (source.flags & 1 /* Any */) return -1 /* True */; if (source === numberType && target.flags & 128 /* Enum */) return -1 /* True */; @@ -21634,41 +21657,52 @@ var ts; getSignaturesOfType(type, 0 /* Call */).length === 0 && getSignaturesOfType(type, 1 /* Construct */).length === 0; } + function createTransientSymbol(source, type) { + var symbol = createSymbol(source.flags | 67108864 /* Transient */, source.name); + symbol.declarations = source.declarations; + symbol.parent = source.parent; + symbol.type = type; + symbol.target = source; + if (source.valueDeclaration) { + symbol.valueDeclaration = source.valueDeclaration; + } + return symbol; + } + function transformTypeOfMembers(type, f) { + var members = {}; + for (var _i = 0, _a = getPropertiesOfObjectType(type); _i < _a.length; _i++) { + var property = _a[_i]; + var original = getTypeOfSymbol(property); + var updated = f(original); + members[property.name] = updated === original ? property : createTransientSymbol(property, updated); + } + ; + return members; + } + /** + * If the the provided object literal is subject to the excess properties check, + * create a new that is exempt. Recursively mark object literal members as exempt. + * Leave signatures alone since they are not subject to the check. + */ function getRegularTypeOfObjectLiteral(type) { - if (type.flags & 1048576 /* FreshObjectLiteral */) { - var regularType = type.regularType; - if (!regularType) { - regularType = createType(type.flags & ~1048576 /* FreshObjectLiteral */); - regularType.symbol = type.symbol; - regularType.members = type.members; - regularType.properties = type.properties; - regularType.callSignatures = type.callSignatures; - regularType.constructSignatures = type.constructSignatures; - regularType.stringIndexInfo = type.stringIndexInfo; - regularType.numberIndexInfo = type.numberIndexInfo; - type.regularType = regularType; - } + if (!(type.flags & 1048576 /* FreshObjectLiteral */)) { + return type; + } + var regularType = type.regularType; + if (regularType) { return regularType; } - return type; + var resolved = type; + var members = transformTypeOfMembers(type, getRegularTypeOfObjectLiteral); + var regularNew = createAnonymousType(resolved.symbol, members, resolved.callSignatures, resolved.constructSignatures, resolved.stringIndexInfo, resolved.numberIndexInfo); + regularNew.flags = resolved.flags & ~1048576 /* FreshObjectLiteral */; + type.regularType = regularNew; + return regularNew; } function getWidenedTypeOfObjectLiteral(type) { - var properties = getPropertiesOfObjectType(type); - var members = {}; - ts.forEach(properties, function (p) { - var propType = getTypeOfSymbol(p); - var widenedType = getWidenedType(propType); - if (propType !== widenedType) { - var symbol = createSymbol(p.flags | 67108864 /* Transient */, p.name); - symbol.declarations = p.declarations; - symbol.parent = p.parent; - symbol.type = widenedType; - symbol.target = p; - if (p.valueDeclaration) - symbol.valueDeclaration = p.valueDeclaration; - p = symbol; - } - members[p.name] = p; + var members = transformTypeOfMembers(type, function (prop) { + var widened = getWidenedType(prop); + return prop === widened ? prop : widened; }); var stringIndexInfo = getIndexInfoOfType(type, 0 /* String */); var numberIndexInfo = getIndexInfoOfType(type, 1 /* Number */); @@ -21924,11 +21958,10 @@ var ts; inferFromTypes(source, t); } } - // Next, if target is a union type containing a single naked type parameter, make a - // secondary inference to that type parameter. We don't do this for intersection types - // because in a target type like Foo & T we don't know how which parts of the source type - // should be matched by Foo and which should be inferred to T. - if (target.flags & 16384 /* Union */ && typeParameterCount === 1) { + // Next, if target containings a single naked type parameter, make a secondary inference to that type + // parameter. This gives meaningful results for union types in co-variant positions and intersection + // types in contra-variant positions (such as callback parameters). + if (typeParameterCount === 1) { inferiority++; inferFromTypes(source, typeParameter); inferiority--; @@ -23224,7 +23257,7 @@ var ts; } return nodeCheckFlag === 512 /* SuperStatic */ ? getBaseConstructorTypeOfClass(classType) - : baseClassType; + : getTypeWithThisArgument(baseClassType, classType.thisType); function isLegalUsageOfSuperExpression(container) { if (!container) { return false; @@ -25936,7 +25969,7 @@ var ts; var types = void 0; var funcIsGenerator = !!func.asteriskToken; if (funcIsGenerator) { - types = checkAndAggregateYieldOperandTypes(func.body, contextualMapper); + types = checkAndAggregateYieldOperandTypes(func, contextualMapper); if (types.length === 0) { var iterableIteratorAny = createIterableIteratorType(anyType); if (compilerOptions.noImplicitAny) { @@ -25946,8 +25979,7 @@ var ts; } } else { - var hasImplicitReturn = !!(func.flags & 32768 /* HasImplicitReturn */); - types = checkAndAggregateReturnExpressionTypes(func.body, contextualMapper, isAsync, hasImplicitReturn); + types = checkAndAggregateReturnExpressionTypes(func, contextualMapper); if (!types) { return neverType; } @@ -26001,9 +26033,9 @@ var ts; return widenedType; } } - function checkAndAggregateYieldOperandTypes(body, contextualMapper) { + function checkAndAggregateYieldOperandTypes(func, contextualMapper) { var aggregatedTypes = []; - ts.forEachYieldExpression(body, function (yieldExpression) { + ts.forEachYieldExpression(func.body, function (yieldExpression) { var expr = yieldExpression.expression; if (expr) { var type = checkExpressionCached(expr, contextualMapper); @@ -26018,10 +26050,12 @@ var ts; }); return aggregatedTypes; } - function checkAndAggregateReturnExpressionTypes(body, contextualMapper, isAsync, hasImplicitReturn) { + function checkAndAggregateReturnExpressionTypes(func, contextualMapper) { + var isAsync = ts.isAsyncFunctionLike(func); var aggregatedTypes = []; - var hasOmittedExpressions = false; - ts.forEachReturnStatement(body, function (returnStatement) { + var hasReturnWithNoExpression = !!(func.flags & 32768 /* HasImplicitReturn */); + var hasReturnOfTypeNever = false; + ts.forEachReturnStatement(func.body, function (returnStatement) { var expr = returnStatement.expression; if (expr) { var type = checkExpressionCached(expr, contextualMapper); @@ -26030,20 +26064,24 @@ var ts; // Promise/A+ compatible implementation will always assimilate any foreign promise, so the // return type of the body should be unwrapped to its awaited type, which should be wrapped in // the native Promise type by the caller. - type = checkAwaitedType(type, body.parent, ts.Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member); + type = checkAwaitedType(type, func, ts.Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member); } - if (type !== neverType && !ts.contains(aggregatedTypes, type)) { + if (type === neverType) { + hasReturnOfTypeNever = true; + } + else if (!ts.contains(aggregatedTypes, type)) { aggregatedTypes.push(type); } } else { - hasOmittedExpressions = true; + hasReturnWithNoExpression = true; } }); - if (aggregatedTypes.length === 0 && !hasOmittedExpressions && !hasImplicitReturn) { + if (aggregatedTypes.length === 0 && !hasReturnWithNoExpression && (hasReturnOfTypeNever || + func.kind === 179 /* FunctionExpression */ || func.kind === 180 /* ArrowFunction */)) { return undefined; } - if (strictNullChecks && aggregatedTypes.length && (hasOmittedExpressions || hasImplicitReturn)) { + if (strictNullChecks && aggregatedTypes.length && hasReturnWithNoExpression) { if (!ts.contains(aggregatedTypes, undefinedType)) { aggregatedTypes.push(undefinedType); } @@ -26215,8 +26253,14 @@ var ts; if (symbol.flags & 4 /* Property */ && (expr.kind === 172 /* PropertyAccessExpression */ || expr.kind === 173 /* ElementAccessExpression */) && expr.expression.kind === 97 /* ThisKeyword */) { + // Look for if this is the constructor for the class that `symbol` is a property of. var func = ts.getContainingFunction(expr); - return !(func && func.kind === 148 /* Constructor */ && func.parent === symbol.valueDeclaration.parent); + if (!(func && func.kind === 148 /* Constructor */)) + return true; + // If func.parent is a class and symbol is a (readonly) property of that class, or + // if func is a constructor and symbol is a (readonly) parameter property declared in it, + // then symbol is writeable here. + return !(func.parent === symbol.valueDeclaration.parent || func === symbol.valueDeclaration.parent); } return true; } @@ -27148,6 +27192,79 @@ var ts; } } } + function checkClassForDuplicateDeclarations(node) { + var getter = 1, setter = 2, property = getter | setter; + var instanceNames = {}; + var staticNames = {}; + for (var _i = 0, _a = node.members; _i < _a.length; _i++) { + var member = _a[_i]; + if (member.kind === 148 /* Constructor */) { + for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) { + var param = _c[_b]; + if (ts.isParameterPropertyDeclaration(param)) { + addName(instanceNames, param.name, param.name.text, property); + } + } + } + else { + var static = ts.forEach(member.modifiers, function (m) { return m.kind === 113 /* StaticKeyword */; }); + var names = static ? staticNames : instanceNames; + var memberName = member.name && ts.getPropertyNameForPropertyNameNode(member.name); + if (memberName) { + switch (member.kind) { + case 149 /* GetAccessor */: + addName(names, member.name, memberName, getter); + break; + case 150 /* SetAccessor */: + addName(names, member.name, memberName, setter); + break; + case 145 /* PropertyDeclaration */: + addName(names, member.name, memberName, property); + break; + } + } + } + } + function addName(names, location, name, meaning) { + if (ts.hasProperty(names, name)) { + var prev = names[name]; + if (prev & meaning) { + error(location, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(location)); + } + else { + names[name] = prev | meaning; + } + } + else { + names[name] = meaning; + } + } + } + function checkObjectTypeForDuplicateDeclarations(node) { + var names = {}; + for (var _i = 0, _a = node.members; _i < _a.length; _i++) { + var member = _a[_i]; + if (member.kind == 144 /* PropertySignature */) { + var memberName = void 0; + switch (member.name.kind) { + case 9 /* StringLiteral */: + case 8 /* NumericLiteral */: + case 69 /* Identifier */: + memberName = member.name.text; + break; + default: + continue; + } + if (ts.hasProperty(names, memberName)) { + error(member.symbol.valueDeclaration.name, ts.Diagnostics.Duplicate_identifier_0, memberName); + error(member.name, ts.Diagnostics.Duplicate_identifier_0, memberName); + } + else { + names[memberName] = true; + } + } + } + } function checkTypeForDuplicateIndexSignatures(node) { if (node.kind === 222 /* InterfaceDeclaration */) { var nodeSymbol = getSymbolOfNode(node); @@ -27399,6 +27516,7 @@ var ts; var type = getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node); checkIndexConstraints(type); checkTypeForDuplicateIndexSignatures(node); + checkObjectTypeForDuplicateDeclarations(node); } } function checkArrayType(node) { @@ -28444,6 +28562,10 @@ var ts; if (node.initializer) { checkTypeAssignableTo(checkExpressionCached(node.initializer), declarationType, node, /*headMessage*/ undefined); } + if (!areDeclarationFlagsIdentical(node, symbol.valueDeclaration)) { + error(symbol.valueDeclaration.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name)); + error(node.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name)); + } } if (node.kind !== 145 /* PropertyDeclaration */ && node.kind !== 144 /* PropertySignature */) { // We know we don't have a binding pattern or computed name here @@ -28457,6 +28579,18 @@ var ts; checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name); } } + function areDeclarationFlagsIdentical(left, right) { + if (ts.hasQuestionToken(left) !== ts.hasQuestionToken(right)) { + return false; + } + var interestingFlags = 8 /* Private */ | + 16 /* Protected */ | + 256 /* Async */ | + 128 /* Abstract */ | + 64 /* Readonly */ | + 32 /* Static */; + return (left.flags & interestingFlags) === (right.flags & interestingFlags); + } function checkVariableDeclaration(node) { checkGrammarVariableDeclaration(node); return checkVariableLikeDeclaration(node); @@ -29150,6 +29284,7 @@ var ts; var typeWithThis = getTypeWithThisArgument(type); var staticType = getTypeOfSymbol(symbol); checkTypeParameterListsIdentical(node, symbol); + checkClassForDuplicateDeclarations(node); var baseTypeNode = ts.getClassExtendsHeritageClauseElement(node); if (baseTypeNode) { var baseTypes = getBaseTypes(type); @@ -29398,6 +29533,7 @@ var ts; checkIndexConstraints(type); } } + checkObjectTypeForDuplicateDeclarations(node); } ts.forEach(ts.getInterfaceBaseTypeNodes(node), function (heritageElement) { if (!ts.isSupportedExpressionWithTypeArguments(heritageElement)) { @@ -30241,14 +30377,11 @@ var ts; function checkSourceFileWorker(node) { var links = getNodeLinks(node); if (!(links.flags & 1 /* TypeChecked */)) { - // Check whether the file has declared it is the default lib, - // and whether the user has specifically chosen to avoid checking it. - if (compilerOptions.skipDefaultLibCheck) { - // If the user specified '--noLib' and a file has a '/// ', - // then we should treat that file as a default lib. - if (node.hasNoDefaultLib) { - return; - } + // If skipLibCheck is enabled, skip type checking if file is a declaration file. + // If skipDefaultLibCheck is enabled, skip type checking if file contains a + // '/// ' directive. + if (compilerOptions.skipLibCheck && node.isDeclarationFile || compilerOptions.skipDefaultLibCheck && node.hasNoDefaultLib) { + return; } // Grammar checking checkGrammarSourceFile(node); @@ -30665,7 +30798,7 @@ var ts; return symbol && getTypeOfSymbol(symbol); } if (ts.isBindingPattern(node)) { - return getTypeForVariableLikeDeclaration(node.parent); + return getTypeForVariableLikeDeclaration(node.parent, /*includeOptionality*/ true); } if (isInRightSideOfImportOrExportAssignment(node)) { var symbol = getSymbolAtLocation(node); @@ -31204,7 +31337,7 @@ var ts; if (file.moduleAugmentations.length) { (augmentations || (augmentations = [])).push(file.moduleAugmentations); } - if (file.wasReferenced && file.symbol && file.symbol.globalExports) { + if (file.symbol && file.symbol.globalExports) { mergeSymbolTable(globals, file.symbol.globalExports); } }); @@ -31787,7 +31920,6 @@ var ts; name_20.kind === 140 /* ComputedPropertyName */) { // If the name is not a ComputedPropertyName, the grammar checking will skip it checkGrammarComputedPropertyName(name_20); - return "continue"; } if (prop.kind === 254 /* ShorthandPropertyAssignment */ && !inDestructuring && prop.objectAssignmentInitializer) { // having objectAssignmentInitializer is only valid in ObjectAssignmentPattern @@ -31829,17 +31961,21 @@ var ts; else { ts.Debug.fail("Unexpected syntax kind:" + prop.kind); } - if (!ts.hasProperty(seen, name_20.text)) { - seen[name_20.text] = currentKind; + var effectiveName = ts.getPropertyNameForPropertyNameNode(name_20); + if (effectiveName === undefined) { + return "continue"; + } + if (!ts.hasProperty(seen, effectiveName)) { + seen[effectiveName] = currentKind; } else { - var existingKind = seen[name_20.text]; + var existingKind = seen[effectiveName]; if (currentKind === Property && existingKind === Property) { - return "continue"; + grammarErrorOnNode(name_20, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(name_20)); } else if ((currentKind & GetOrSetAccessor) && (existingKind & GetOrSetAccessor)) { if (existingKind !== GetOrSetAccessor && currentKind !== existingKind) { - seen[name_20.text] = currentKind | existingKind; + seen[effectiveName] = currentKind | existingKind; } else { return { value: grammarErrorOnNode(name_20, ts.Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name) }; @@ -41638,8 +41774,8 @@ var ts; skipTsx: true, traceEnabled: traceEnabled }; - // use typesRoot and fallback to directory that contains tsconfig if typesRoot is not set - var rootDir = options.typesRoot || (options.configFilePath ? ts.getDirectoryPath(options.configFilePath) : undefined); + // use typesRoot and fallback to directory that contains tsconfig or current directory if typesRoot is not set + var rootDir = options.typesRoot || (options.configFilePath ? ts.getDirectoryPath(options.configFilePath) : (host.getCurrentDirectory && host.getCurrentDirectory())); if (traceEnabled) { if (containingFile === undefined) { if (rootDir === undefined) { @@ -42229,12 +42365,25 @@ var ts; } } } + function getDefaultTypeDirectiveNames(rootPath) { + var localTypes = ts.combinePaths(rootPath, "types"); + var npmTypes = ts.combinePaths(rootPath, "node_modules/@types"); + var result = []; + if (ts.sys.directoryExists(localTypes)) { + result = result.concat(ts.sys.getDirectories(localTypes)); + } + if (ts.sys.directoryExists(npmTypes)) { + result = result.concat(ts.sys.getDirectories(npmTypes)); + } + return result; + } function getDefaultLibLocation() { return ts.getDirectoryPath(ts.normalizePath(ts.sys.getExecutingFilePath())); } var newLine = ts.getNewLineCharacter(options); var realpath = ts.sys.realpath && (function (path) { return ts.sys.realpath(path); }); return { + getDefaultTypeDirectiveNames: getDefaultTypeDirectiveNames, getSourceFile: getSourceFile, getDefaultLibLocation: getDefaultLibLocation, getDefaultLibFileName: function (options) { return ts.combinePaths(getDefaultLibLocation(), ts.getDefaultLibFileName(options)); }, @@ -42302,6 +42451,21 @@ var ts; } return resolutions; } + function getDefaultTypeDirectiveNames(options, rootFiles, host) { + // Use explicit type list from tsconfig.json + if (options.types) { + return options.types; + } + // or load all types from the automatic type import fields + if (host && host.getDefaultTypeDirectiveNames) { + var commonRoot = computeCommonSourceDirectoryOfFilenames(rootFiles, host.getCurrentDirectory(), function (f) { return host.getCanonicalFileName(f); }); + if (commonRoot) { + return host.getDefaultTypeDirectiveNames(commonRoot); + } + } + return undefined; + } + ts.getDefaultTypeDirectiveNames = getDefaultTypeDirectiveNames; function createProgram(rootNames, options, host, oldProgram) { var program; var files = []; @@ -42340,14 +42504,15 @@ var ts; // used to track cases when two file names differ only in casing var filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? ts.createFileMap(function (fileName) { return fileName.toLowerCase(); }) : undefined; if (!tryReuseStructureFromOldProgram()) { + ts.forEach(rootNames, function (name) { return processRootFile(name, /*isDefaultLib*/ false); }); // load type declarations specified via 'types' argument - if (options.types && options.types.length) { - var resolutions = resolveTypeReferenceDirectiveNamesWorker(options.types, /*containingFile*/ undefined); - for (var i = 0; i < options.types.length; i++) { - processTypeReferenceDirective(options.types[i], resolutions[i]); + var typeReferences = getDefaultTypeDirectiveNames(options, rootNames, host); + if (typeReferences) { + var resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, /*containingFile*/ undefined); + for (var i = 0; i < typeReferences.length; i++) { + processTypeReferenceDirective(typeReferences[i], resolutions[i]); } } - ts.forEach(rootNames, function (name) { return processRootFile(name, /*isDefaultLib*/ false); }); // Do not process the default library if: // - The '--noLib' flag is used. // - A 'no-default-lib' reference comment is encountered in @@ -42999,9 +43164,6 @@ var ts; if (file_1 && options.forceConsistentCasingInFileNames && ts.getNormalizedAbsolutePath(file_1.fileName, currentDirectory) !== ts.getNormalizedAbsolutePath(fileName, currentDirectory)) { reportFileNamesDifferOnlyInCasingError(fileName, file_1.fileName, refFile, refPos, refEnd); } - if (file_1) { - file_1.wasReferenced = file_1.wasReferenced || isReference; - } return file_1; } // We haven't looked for this file, do so now and cache result @@ -43015,7 +43177,6 @@ var ts; }); filesByName.set(path, file); if (file) { - file.wasReferenced = file.wasReferenced || isReference; file.path = path; if (host.useCaseSensitiveFileNames()) { // for case-sensitive file systems check if we've already seen some file with similar filename ignoring case @@ -43129,19 +43290,7 @@ var ts; !options.noResolve && i < file.imports.length; if (shouldAddFile) { - var importedFile = findSourceFile(resolution.resolvedFileName, ts.toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName), /*isDefaultLib*/ false, /*isReference*/ false, file, ts.skipTrivia(file.text, file.imports[i].pos), file.imports[i].end); - if (importedFile && resolution.isExternalLibraryImport) { - // Since currently irrespective of allowJs, we only look for supportedTypeScript extension external module files, - // this check is ok. Otherwise this would be never true for javascript file - if (!ts.isExternalModule(importedFile) && importedFile.statements.length) { - var start_5 = ts.getTokenPosOfNode(file.imports[i], file); - fileProcessingDiagnostics.add(ts.createFileDiagnostic(file, start_5, file.imports[i].end - start_5, ts.Diagnostics.Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_the_package_definition, importedFile.fileName)); - } - else if (importedFile.referencedFiles.length) { - var firstRef = importedFile.referencedFiles[0]; - fileProcessingDiagnostics.add(ts.createFileDiagnostic(importedFile, firstRef.pos, firstRef.end - firstRef.pos, ts.Diagnostics.Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_package_author_to_update_the_package_definition)); - } - } + findSourceFile(resolution.resolvedFileName, ts.toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName), /*isDefaultLib*/ false, /*isReference*/ false, file, ts.skipTrivia(file.text, file.imports[i].pos), file.imports[i].end); } } } @@ -43227,7 +43376,7 @@ var ts; } } else { - programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Substututions_for_pattern_0_should_be_an_array, key)); + programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Substitutions_for_pattern_0_should_be_an_array, key)); } } } @@ -43278,15 +43427,21 @@ var ts; else if (firstExternalModuleSourceFile && languageVersion < 2 /* ES6 */ && options.module === ts.ModuleKind.None) { // We cannot use createDiagnosticFromNode because nodes do not have parents yet var span = ts.getErrorSpanForNode(firstExternalModuleSourceFile, firstExternalModuleSourceFile.externalModuleIndicator); - programDiagnostics.add(ts.createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_modules_unless_the_module_flag_is_provided_with_a_valid_module_type_Consider_setting_the_module_compiler_option_in_a_tsconfig_json_file)); + programDiagnostics.add(ts.createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none)); } // Cannot specify module gen target of es6 when below es6 if (options.module === ts.ModuleKind.ES6 && languageVersion < 2 /* ES6 */) { programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_compile_modules_into_es2015_when_targeting_ES5_or_lower)); } // Cannot specify module gen that isn't amd or system with --out - if (outFile && options.module && !(options.module === ts.ModuleKind.AMD || options.module === ts.ModuleKind.System)) { - programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile")); + if (outFile) { + if (options.module && !(options.module === ts.ModuleKind.AMD || options.module === ts.ModuleKind.System)) { + programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile")); + } + else if (options.module === undefined && firstExternalModuleSourceFile) { + var span = ts.getErrorSpanForNode(firstExternalModuleSourceFile, firstExternalModuleSourceFile.externalModuleIndicator); + programDiagnostics.add(ts.createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system, options.out ? "out" : "outFile")); + } } // there has to be common source directory if user specified --outdir || --sourceRoot // if user specified --mapRoot, there needs to be common source directory if there would be multiple files being emitted @@ -43384,6 +43539,11 @@ var ts; type: "boolean", description: ts.Diagnostics.Print_this_message }, + { + name: "help", + shortName: "?", + type: "boolean" + }, { name: "init", type: "boolean", @@ -43486,6 +43646,11 @@ var ts; name: "skipDefaultLibCheck", type: "boolean" }, + { + name: "skipLibCheck", + type: "boolean", + description: ts.Diagnostics.Skip_type_checking_of_declaration_files + }, { name: "out", type: "string", @@ -44315,7 +44480,7 @@ var ts; (function (ts) { var NavigateTo; (function (NavigateTo) { - function getNavigateToItems(program, cancellationToken, searchValue, maxResultCount) { + function getNavigateToItems(program, checker, cancellationToken, searchValue, maxResultCount) { var patternMatcher = ts.createPatternMatcher(searchValue); var rawItems = []; // This means "compare in a case insensitive manner." @@ -44354,6 +44519,18 @@ var ts; } } }); + // Remove imports when the imported declaration is already in the list and has the same name. + rawItems = ts.filter(rawItems, function (item) { + var decl = item.declaration; + if (decl.kind === 231 /* ImportClause */ || decl.kind === 234 /* ImportSpecifier */ || decl.kind === 229 /* ImportEqualsDeclaration */) { + var importer = checker.getSymbolAtLocation(decl.name); + var imported = checker.getAliasedSymbol(importer); + return importer.name !== imported.name; + } + else { + return true; + } + }); rawItems.sort(compareNavigateToItems); if (maxResultCount !== undefined) { rawItems = rawItems.slice(0, maxResultCount); @@ -44752,8 +44929,12 @@ var ts; return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.memberSetAccessorElement); case 153 /* IndexSignature */: return createItem(node, "[]", ts.ScriptElementKind.indexSignatureElement); + case 224 /* EnumDeclaration */: + return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.enumElement); case 255 /* EnumMember */: return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.memberVariableElement); + case 222 /* InterfaceDeclaration */: + return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.interfaceElement); case 151 /* CallSignature */: return createItem(node, "()", ts.ScriptElementKind.callSignatureElement); case 152 /* ConstructSignature */: @@ -45714,7 +45895,7 @@ var ts; // To do this, the method will back parse the expression starting at the position required. it will try to parse the current expression as a generic type expression, if it did succeed it // will return the generic identifier that started the expression (e.g. "foo" in "foo= 0; --i) { + for (var i = exclusiveStartPosition - 1; i >= 0; i--) { if (nodeHasTokens(children[i])) { return children[i]; } @@ -47337,12 +47518,11 @@ var ts; if (!isStarted) { scanner.scan(); } - var t; var pos = scanner.getStartPos(); // Read leading trivia and token while (pos < endPos) { - var t_1 = scanner.getToken(); - if (!ts.isTrivia(t_1)) { + var t = scanner.getToken(); + if (!ts.isTrivia(t)) { break; } // consume leading trivia @@ -47350,7 +47530,7 @@ var ts; var item = { pos: pos, end: scanner.getStartPos(), - kind: t_1 + kind: t }; pos = scanner.getStartPos(); if (!leadingTrivia) { @@ -47690,6 +47870,7 @@ var ts; })(formatting = ts.formatting || (ts.formatting = {})); })(ts || (ts = {})); /// +/* tslint:disable:no-null-keyword */ /* @internal */ var ts; (function (ts) { @@ -47951,7 +48132,7 @@ var ts; this.SpaceAfterKeywordInControl = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Keywords, 17 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsControlDeclContext), 2 /* Space */)); this.NoSpaceAfterKeywordInControl = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Keywords, 17 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsControlDeclContext), 8 /* Delete */)); // Open Brace braces after function - //TypeScript: Function can have return types, which can be made of tons of different token kinds + // TypeScript: Function can have return types, which can be made of tons of different token kinds this.NewLineBeforeOpenBraceInFunction = new formatting.Rule(formatting.RuleDescriptor.create2(this.FunctionOpenBraceLeftTokenRange, 15 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclContext, Rules.IsBeforeMultilineBlockContext), 4 /* NewLine */), 1 /* CanDeleteNewLines */); // Open Brace braces after TypeScript module/class/interface this.NewLineBeforeOpenBraceInTypeScriptDeclWithBlock = new formatting.Rule(formatting.RuleDescriptor.create2(this.TypeScriptOpenBraceLeftTokenRange, 15 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsTypeScriptDeclWithBlockContext, Rules.IsBeforeMultilineBlockContext), 4 /* NewLine */), 1 /* CanDeleteNewLines */); @@ -48092,17 +48273,17 @@ var ts; case 220 /* FunctionDeclaration */: case 147 /* MethodDeclaration */: case 146 /* MethodSignature */: - //case SyntaxKind.MemberFunctionDeclaration: + // case SyntaxKind.MemberFunctionDeclaration: case 149 /* GetAccessor */: case 150 /* SetAccessor */: - ///case SyntaxKind.MethodSignature: + // case SyntaxKind.MethodSignature: case 151 /* CallSignature */: case 179 /* FunctionExpression */: case 148 /* Constructor */: case 180 /* ArrowFunction */: - //case SyntaxKind.ConstructorDeclaration: - //case SyntaxKind.SimpleArrowFunctionExpression: - //case SyntaxKind.ParenthesizedArrowFunctionExpression: + // case SyntaxKind.ConstructorDeclaration: + // case SyntaxKind.SimpleArrowFunctionExpression: + // case SyntaxKind.ParenthesizedArrowFunctionExpression: case 222 /* InterfaceDeclaration */: return true; } @@ -48254,6 +48435,7 @@ var ts; })(formatting = ts.formatting || (ts.formatting = {})); })(ts || (ts = {})); /// +/* tslint:disable:no-null-keyword */ /* @internal */ var ts; (function (ts) { @@ -48271,9 +48453,9 @@ var ts; }; RulesMap.prototype.Initialize = function (rules) { this.mapRowLength = 138 /* LastToken */ + 1; - this.map = new Array(this.mapRowLength * this.mapRowLength); //new Array(this.mapRowLength * this.mapRowLength); + this.map = new Array(this.mapRowLength * this.mapRowLength); // new Array(this.mapRowLength * this.mapRowLength); // This array is used only during construction of the rulesbucket in the map - var rulesBucketConstructionStateList = new Array(this.map.length); //new Array(this.map.length); + var rulesBucketConstructionStateList = new Array(this.map.length); // new Array(this.map.length); this.FillRules(rules, rulesBucketConstructionStateList); return this.map; }; @@ -48285,7 +48467,7 @@ var ts; }; RulesMap.prototype.GetRuleBucketIndex = function (row, column) { var rulesBucketIndex = (row * this.mapRowLength) + column; - //Debug.Assert(rulesBucketIndex < this.map.Length, "Trying to access an index outside the array."); + // Debug.Assert(rulesBucketIndex < this.map.Length, "Trying to access an index outside the array."); return rulesBucketIndex; }; RulesMap.prototype.FillRule = function (rule, rulesBucketConstructionStateList) { @@ -48537,6 +48719,7 @@ var ts; /// /// /// +/* tslint:disable:no-null-keyword */ /* @internal */ var ts; (function (ts) { @@ -49058,7 +49241,7 @@ var ts; // if there are any tokens that logically belong to node and interleave child nodes // such tokens will be consumed in processChildNode for for the child that follows them ts.forEachChild(node, function (child) { - processChildNode(child, /*inheritedIndentation*/ -1 /* Unknown */, node, nodeDynamicIndentation, nodeStartLine, undecoratedNodeStartLine, /*isListElement*/ false); + processChildNode(child, /*inheritedIndentation*/ -1 /* Unknown */, node, nodeDynamicIndentation, nodeStartLine, undecoratedNodeStartLine, /*isListItem*/ false); }, function (nodes) { processChildNodes(nodes, node, nodeStartLine, nodeDynamicIndentation); }); @@ -49149,7 +49332,7 @@ var ts; var inheritedIndentation = -1 /* Unknown */; for (var i = 0; i < nodes.length; i++) { var child = nodes[i]; - inheritedIndentation = processChildNode(child, inheritedIndentation, node, listDynamicIndentation, startLine, startLine, /*isListElement*/ true, /*isFirstListItem*/ i === 0); + inheritedIndentation = processChildNode(child, inheritedIndentation, node, listDynamicIndentation, startLine, startLine, /*isListItem*/ true, /*isFirstListItem*/ i === 0); } if (listEndToken !== 0 /* Unknown */) { if (formattingScanner.isOnToken()) { @@ -49279,7 +49462,7 @@ var ts; // Handle the case where the next line is moved to be the end of this line. // In this case we don't indent the next line in the next pass. if (currentParent.getStart(sourceFile) === currentItem.pos) { - dynamicIndentation.recomputeIndentation(/*lineAdded*/ false); + dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ false); } } else if (rule.Operation.Action & 4 /* NewLine */ && currentStartLine === previousStartLine) { @@ -49288,7 +49471,7 @@ var ts; // In this case we indent token2 in the next pass but we set // sameLineIndent flag to notify the indenter that the indentation is within the line. if (currentParent.getStart(sourceFile) === currentItem.pos) { - dynamicIndentation.recomputeIndentation(/*lineAdded*/ true); + dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ true); } } // We need to trim trailing whitespace between the tokens if they were on different lines, and no rule was applied to put them on the same line @@ -49336,7 +49519,7 @@ var ts; else { parts = []; var startPos = commentRange.pos; - for (var line = startLine; line < endLine; ++line) { + for (var line = startLine; line < endLine; line++) { var endOfLine = ts.getEndLinePosition(line, sourceFile); parts.push({ pos: startPos, end: endOfLine }); startPos = ts.getStartPositionOfLine(line + 1, sourceFile); @@ -49355,7 +49538,7 @@ var ts; } // shift all parts on the delta size var delta = indentation - nonWhitespaceColumnInFirstPart.column; - for (var i = startIndex, len = parts.length; i < len; ++i, ++startLine) { + for (var i = startIndex, len = parts.length; i < len; i++, startLine++) { var startLinePos_1 = ts.getStartPositionOfLine(startLine, sourceFile); var nonWhitespaceCharacterAndColumn = i === 0 ? nonWhitespaceColumnInFirstPart @@ -49371,7 +49554,7 @@ var ts; } } function trimTrailingWhitespacesForLines(line1, line2, range) { - for (var line = line1; line < line2; ++line) { + for (var line = line1; line < line2; line++) { var lineStartPosition = ts.getStartPositionOfLine(line, sourceFile); var lineEndPosition = ts.getEndLinePosition(line, sourceFile); // do not trim whitespaces in comments or template expression @@ -49422,7 +49605,6 @@ var ts; } } function applyRuleEdits(rule, previousRange, previousStartLine, currentRange, currentStartLine) { - var between; switch (rule.Operation.Action) { case 1 /* Ignore */: // no action required @@ -49459,14 +49641,6 @@ var ts; } } } - function isSomeBlock(kind) { - switch (kind) { - case 199 /* Block */: - case 226 /* ModuleBlock */: - return true; - } - return false; - } function getOpenTokenForList(node, list) { switch (node.kind) { case 148 /* Constructor */: @@ -49525,7 +49699,7 @@ var ts; internedTabsIndentation = []; } if (internedTabsIndentation[tabs] === undefined) { - internedTabsIndentation[tabs] = tabString = repeat('\t', tabs); + internedTabsIndentation[tabs] = tabString = repeat("\t", tabs); } else { tabString = internedTabsIndentation[tabs]; @@ -49550,7 +49724,7 @@ var ts; } function repeat(value, count) { var s = ""; - for (var i = 0; i < count; ++i) { + for (var i = 0; i < count; i++) { s += value; } return s; @@ -49866,7 +50040,7 @@ var ts; // walk toward the start of the list starting from current node and check if the line is the same for all items. // if end line for item [i - 1] differs from the start line for item [i] - find column of the first non-whitespace character on the line of item [i] var lineAndCharacter = getStartLineAndCharacterForNode(node, sourceFile); - for (var i = index - 1; i >= 0; --i) { + for (var i = index - 1; i >= 0; i--) { if (list[i].kind === 24 /* CommaToken */) { continue; } @@ -49893,7 +50067,7 @@ var ts; function findFirstNonWhitespaceCharacterAndColumn(startPos, endPos, sourceFile, options) { var character = 0; var column = 0; - for (var pos = startPos; pos < endPos; ++pos) { + for (var pos = startPos; pos < endPos; pos++) { var ch = sourceFile.text.charCodeAt(pos); if (!ts.isWhiteSpace(ch)) { break; @@ -49987,7 +50161,7 @@ var ts; Function returns true when the parent node should indent the given child by an explicit rule */ function shouldIndentChildNode(parent, child) { - return nodeContentIsAlwaysIndented(parent.kind) || nodeWillIndentChild(parent, child, false); + return nodeContentIsAlwaysIndented(parent.kind) || nodeWillIndentChild(parent, child, /*indentByDefault*/ false); } SmartIndenter.shouldIndentChildNode = shouldIndentChildNode; })(SmartIndenter = formatting.SmartIndenter || (formatting.SmartIndenter = {})); @@ -50809,49 +50983,55 @@ var ts; (function (ScriptElementKind) { ScriptElementKind.unknown = ""; ScriptElementKind.warning = "warning"; - // predefined type (void) or keyword (class) + /** predefined type (void) or keyword (class) */ ScriptElementKind.keyword = "keyword"; - // top level script node + /** top level script node */ ScriptElementKind.scriptElement = "script"; - // module foo {} + /** module foo {} */ ScriptElementKind.moduleElement = "module"; - // class X {} + /** class X {} */ ScriptElementKind.classElement = "class"; - // var x = class X {} + /** var x = class X {} */ ScriptElementKind.localClassElement = "local class"; - // interface Y {} + /** interface Y {} */ ScriptElementKind.interfaceElement = "interface"; - // type T = ... + /** type T = ... */ ScriptElementKind.typeElement = "type"; - // enum E + /** enum E */ ScriptElementKind.enumElement = "enum"; - // Inside module and script only - // const v = .. + /** + * Inside module and script only + * const v = .. + */ ScriptElementKind.variableElement = "var"; - // Inside function + /** Inside function */ ScriptElementKind.localVariableElement = "local var"; - // Inside module and script only - // function f() { } + /** + * Inside module and script only + * function f() { } + */ ScriptElementKind.functionElement = "function"; - // Inside function + /** Inside function */ ScriptElementKind.localFunctionElement = "local function"; - // class X { [public|private]* foo() {} } + /** class X { [public|private]* foo() {} } */ ScriptElementKind.memberFunctionElement = "method"; - // class X { [public|private]* [get|set] foo:number; } + /** class X { [public|private]* [get|set] foo:number; } */ ScriptElementKind.memberGetAccessorElement = "getter"; ScriptElementKind.memberSetAccessorElement = "setter"; - // class X { [public|private]* foo:number; } - // interface Y { foo:number; } + /** + * class X { [public|private]* foo:number; } + * interface Y { foo:number; } + */ ScriptElementKind.memberVariableElement = "property"; - // class X { constructor() { } } + /** class X { constructor() { } } */ ScriptElementKind.constructorImplementationElement = "constructor"; - // interface Y { ():number; } + /** interface Y { ():number; } */ ScriptElementKind.callSignatureElement = "call"; - // interface Y { []:number; } + /** interface Y { []:number; } */ ScriptElementKind.indexSignatureElement = "index"; - // interface Y { new():Y; } + /** interface Y { new():Y; } */ ScriptElementKind.constructSignatureElement = "construct"; - // function foo(*Y*: string) + /** function foo(*Y*: string) */ ScriptElementKind.parameterElement = "parameter"; ScriptElementKind.typeParameterElement = "type parameter"; ScriptElementKind.primitiveType = "primitive type"; @@ -52236,9 +52416,9 @@ var ts; // Check if the caret is at the end of an identifier; this is a partial identifier that we want to complete: e.g. a.toS| // Skip this partial identifier and adjust the contextToken to the token that precedes it. if (contextToken && position <= contextToken.end && ts.isWord(contextToken.kind)) { - var start_6 = new Date().getTime(); + var start_5 = new Date().getTime(); contextToken = ts.findPrecedingToken(contextToken.getFullStart(), sourceFile); - log("getCompletionData: Get previous token 2: " + (new Date().getTime() - start_6)); + log("getCompletionData: Get previous token 2: " + (new Date().getTime() - start_5)); } // Find the node where completion is requested on. // Also determine whether we are trying to complete with members of that node @@ -52518,13 +52698,13 @@ var ts; || contextToken.kind === 166 /* StringLiteralType */ || contextToken.kind === 10 /* RegularExpressionLiteral */ || ts.isTemplateLiteralKind(contextToken.kind)) { - var start_7 = contextToken.getStart(); + var start_6 = contextToken.getStart(); var end = contextToken.getEnd(); // To be "in" one of these literals, the position has to be: // 1. entirely within the token text. // 2. at the end position of an unterminated token. // 3. at the end of a regular expression (due to trailing flags like '/foo/g'). - if (start_7 < position && position < end) { + if (start_6 < position && position < end) { return true; } if (position === end) { @@ -53759,8 +53939,7 @@ var ts; } function getDocumentHighlights(fileName, position, filesToSearch) { synchronizeHostData(); - filesToSearch = ts.map(filesToSearch, ts.normalizeSlashes); - var sourceFilesToSearch = ts.filter(program.getSourceFiles(), function (f) { return ts.contains(filesToSearch, f.fileName); }); + var sourceFilesToSearch = ts.map(filesToSearch, function (f) { return program.getSourceFile(f); }); var sourceFile = getValidSourceFile(fileName); var node = ts.getTouchingWord(sourceFile, position); if (!node) { @@ -55150,7 +55329,8 @@ var ts; /// NavigateTo function getNavigateToItems(searchValue, maxResultCount) { synchronizeHostData(); - return ts.NavigateTo.getNavigateToItems(program, cancellationToken, searchValue, maxResultCount); + var checker = getProgram().getTypeChecker(); + return ts.NavigateTo.getNavigateToItems(program, checker, cancellationToken, searchValue, maxResultCount); } function getEmitOutput(fileName) { synchronizeHostData(); @@ -57559,6 +57739,9 @@ var ts; LanguageServiceShimHostAdapter.prototype.getCurrentDirectory = function () { return this.shimHost.getCurrentDirectory(); }; + LanguageServiceShimHostAdapter.prototype.getDirectories = function (path) { + return this.shimHost.getDirectories(path); + }; LanguageServiceShimHostAdapter.prototype.getDefaultLibFileName = function (options) { return this.shimHost.getDefaultLibFileName(JSON.stringify(options)); }; diff --git a/scripts/tslint/booleanTriviaRule.ts b/scripts/tslint/booleanTriviaRule.ts index 756728a1a11..b626b7560a6 100644 --- a/scripts/tslint/booleanTriviaRule.ts +++ b/scripts/tslint/booleanTriviaRule.ts @@ -18,7 +18,7 @@ class BooleanTriviaWalker extends Lint.RuleWalker { visitCallExpression(node: ts.CallExpression) { super.visitCallExpression(node); - if (node.arguments) { + if (node.arguments && node.arguments.some(arg => arg.kind === ts.SyntaxKind.TrueKeyword || arg.kind === ts.SyntaxKind.FalseKeyword)) { const targetCallSignature = this.checker.getResolvedSignature(node); if (!!targetCallSignature) { const targetParameters = targetCallSignature.getParameters(); diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 0c01488b609..b01c2e6efc3 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -75,12 +75,14 @@ namespace ts { // Blocks (when not parented by functions), Catch clauses, For/For-in/For-of statements... IsBlockScopedContainer = 1 << 1, - HasLocals = 1 << 2, + // The current node is the container of a control flow path. The current control flow should + // be saved and restored, and a new control flow initialized within the container. + IsControlFlowContainer = 1 << 2, - // If the current node is a container that also container that also contains locals. Examples: - // - // Functions, Methods, Modules, Source-files. - IsContainerWithLocals = IsContainer | HasLocals + IsFunctionLike = 1 << 3, + IsFunctionExpression = 1 << 4, + HasLocals = 1 << 5, + IsInterface = 1 << 6, } const binder = createBinder(); @@ -101,22 +103,19 @@ namespace ts { let lastContainer: Node; let seenThisKeyword: boolean; - // state used by reachability checks - let hasExplicitReturn: boolean; + // state used by control flow analysis let currentFlow: FlowNode; let currentBreakTarget: FlowLabel; let currentContinueTarget: FlowLabel; + let currentReturnTarget: FlowLabel; let currentTrueTarget: FlowLabel; let currentFalseTarget: FlowLabel; let preSwitchCaseFlow: FlowNode; let activeLabels: ActiveLabel[]; + let hasExplicitReturn: boolean; // state used for emit helpers - let hasClassExtends: boolean; - let hasAsyncFunctions: boolean; - let hasDecorators: boolean; - let hasParameterDecorators: boolean; - let hasJsxSpreadAttribute: boolean; + let emitFlags: NodeFlags; // If this file is an external module, then it is automatically in strict-mode according to // ES6. If it is not an external module, then we'll determine if it is in strict mode or @@ -159,19 +158,16 @@ namespace ts { blockScopeContainer = undefined; lastContainer = undefined; seenThisKeyword = false; - hasExplicitReturn = false; currentFlow = undefined; currentBreakTarget = undefined; currentContinueTarget = undefined; + currentReturnTarget = undefined; currentTrueTarget = undefined; currentFalseTarget = undefined; activeLabels = undefined; - hasClassExtends = false; - hasAsyncFunctions = false; - hasDecorators = false; - hasParameterDecorators = false; + hasExplicitReturn = false; + emitFlags = NodeFlags.None; subtreeTransformFlags = TransformFlags.None; - hasJsxSpreadAttribute = false; } return bindSourceFile; @@ -271,6 +267,18 @@ namespace ts { let functionType = node.parent; let index = indexOf(functionType.parameters, node); return "p" + index; + case SyntaxKind.JSDocTypedefTag: + const parentNode = node.parent && node.parent.parent; + let nameFromParentNode: string; + if (parentNode && parentNode.kind === SyntaxKind.VariableStatement) { + if ((parentNode).declarationList.declarations.length > 0) { + const nameIdentifier = (parentNode).declarationList.declarations[0].name; + if (nameIdentifier.kind === SyntaxKind.Identifier) { + nameFromParentNode = (nameIdentifier).text; + } + } + } + return nameFromParentNode; } } @@ -404,17 +412,13 @@ namespace ts { // All container nodes are kept on a linked list in declaration order. This list is used by // the getLocalNameOfContainer function in the type checker to validate that the local name // used for a container is unique. - function bindChildren(node: Node) { + function bindContainer(node: Node, containerFlags: ContainerFlags) { // Before we recurse into a node's children, we first save the existing parent, container // and block-container. Then after we pop out of processing the children, we restore // these saved values. - const saveParent = parent; const saveContainer = container; const savedBlockScopeContainer = blockScopeContainer; - // This node will now be set as the parent of all of its children as we recurse into them. - parent = node; - // Depending on what kind of node this is, we may have to adjust the current container // and block-container. If the current node is a container, then it is automatically // considered the current block-container as well. Also, for containers that we know @@ -432,115 +436,107 @@ namespace ts { // reusing a node from a previous compilation, that node may have had 'locals' created // for it. We must clear this so we don't accidentally move any stale data forward from // a previous compilation. - const containerFlags = getContainerFlags(node); if (containerFlags & ContainerFlags.IsContainer) { container = blockScopeContainer = node; - if (containerFlags & ContainerFlags.HasLocals) { container.locals = {}; } - addToContainerChain(container); } else if (containerFlags & ContainerFlags.IsBlockScopedContainer) { blockScopeContainer = node; blockScopeContainer.locals = undefined; } - - let savedHasExplicitReturn: boolean; - let savedCurrentFlow: FlowNode; - let savedBreakTarget: FlowLabel; - let savedContinueTarget: FlowLabel; - let savedActiveLabels: ActiveLabel[]; - - const kind = node.kind; - let flags = node.flags; - - // reset all reachability check related flags on node (for incremental scenarios) - flags &= ~NodeFlags.ReachabilityCheckFlags; - - // reset all emit helper flags on node (for incremental scenarios) - flags &= ~NodeFlags.EmitHelperFlags; - - if (kind === SyntaxKind.InterfaceDeclaration) { - seenThisKeyword = false; - } - - const saveState = kind === SyntaxKind.SourceFile || kind === SyntaxKind.ModuleBlock || isFunctionLikeKind(kind); - if (saveState) { - savedHasExplicitReturn = hasExplicitReturn; - savedCurrentFlow = currentFlow; - savedBreakTarget = currentBreakTarget; - savedContinueTarget = currentContinueTarget; - savedActiveLabels = activeLabels; - - hasExplicitReturn = false; - currentFlow = { flags: FlowFlags.Start }; + if (containerFlags & ContainerFlags.IsControlFlowContainer) { + const saveCurrentFlow = currentFlow; + const saveBreakTarget = currentBreakTarget; + const saveContinueTarget = currentContinueTarget; + const saveReturnTarget = currentReturnTarget; + const saveActiveLabels = activeLabels; + const saveHasExplicitReturn = hasExplicitReturn; + const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !!getImmediatelyInvokedFunctionExpression(node); + // An IIFE is considered part of the containing control flow. Return statements behave + // similarly to break statements that exit to a label just past the statement body. + if (isIIFE) { + currentReturnTarget = createBranchLabel(); + } + else { + currentFlow = { flags: FlowFlags.Start }; + if (containerFlags & ContainerFlags.IsFunctionExpression) { + (currentFlow).container = node; + } + currentReturnTarget = undefined; + } currentBreakTarget = undefined; currentContinueTarget = undefined; activeLabels = undefined; - } - - if (isInJavaScriptFile(node) && node.jsDocComment) { - bind(node.jsDocComment); - } - - bindReachableStatement(node); - - if (!(currentFlow.flags & FlowFlags.Unreachable) && isFunctionLikeKind(kind) && nodeIsPresent((node).body)) { - flags |= NodeFlags.HasImplicitReturn; - if (hasExplicitReturn) { - flags |= NodeFlags.HasExplicitReturn; + hasExplicitReturn = false; + bindChildren(node); + // Reset all reachability check related flags on node (for incremental scenarios) + // Reset all emit helper flags on node (for incremental scenarios) + node.flags &= ~NodeFlags.ReachabilityAndEmitFlags; + if (!(currentFlow.flags & FlowFlags.Unreachable) && containerFlags & ContainerFlags.IsFunctionLike && nodeIsPresent((node).body)) { + node.flags |= NodeFlags.HasImplicitReturn; + if (hasExplicitReturn) node.flags |= NodeFlags.HasExplicitReturn; } + if (node.kind === SyntaxKind.SourceFile) { + node.flags |= emitFlags; + } + if (isIIFE) { + addAntecedent(currentReturnTarget, currentFlow); + currentFlow = finishFlowLabel(currentReturnTarget); + } + else { + currentFlow = saveCurrentFlow; + } + currentBreakTarget = saveBreakTarget; + currentContinueTarget = saveContinueTarget; + currentReturnTarget = saveReturnTarget; + activeLabels = saveActiveLabels; + hasExplicitReturn = saveHasExplicitReturn; } - - if (kind === SyntaxKind.InterfaceDeclaration) { - flags = seenThisKeyword ? flags | NodeFlags.ContainsThis : flags & ~NodeFlags.ContainsThis; + else if (containerFlags & ContainerFlags.IsInterface) { + seenThisKeyword = false; + bindChildren(node); + node.flags = seenThisKeyword ? node.flags | NodeFlags.ContainsThis : node.flags & ~NodeFlags.ContainsThis; } - - if (kind === SyntaxKind.SourceFile) { - if (hasClassExtends) { - flags |= NodeFlags.HasClassExtends; - } - if (hasDecorators) { - flags |= NodeFlags.HasDecorators; - } - if (hasParameterDecorators) { - flags |= NodeFlags.HasParamDecorators; - } - if (hasAsyncFunctions) { - flags |= NodeFlags.HasAsyncFunctions; - } - if (hasJsxSpreadAttribute) { - flags |= NodeFlags.HasJsxSpreadAttribute; - } + else { + bindChildren(node); } - - node.flags = flags; - - if (saveState) { - hasExplicitReturn = savedHasExplicitReturn; - currentFlow = savedCurrentFlow; - currentBreakTarget = savedBreakTarget; - currentContinueTarget = savedContinueTarget; - activeLabels = savedActiveLabels; - } - container = saveContainer; - parent = saveParent; blockScopeContainer = savedBlockScopeContainer; } + + function bindChildren(node: Node): void { + if (skipTransformFlagAggregation) { + bindChildrenWorker(node); + } + else if (node.transformFlags & TransformFlags.HasComputedFlags) { + skipTransformFlagAggregation = true; + bindChildrenWorker(node); + skipTransformFlagAggregation = false; + } + else { + const savedSubtreeTransformFlags = subtreeTransformFlags; + subtreeTransformFlags = 0; + bindChildrenWorker(node); + subtreeTransformFlags = savedSubtreeTransformFlags | computeTransformFlagsForNode(node, subtreeTransformFlags); + } + } - /** - * Returns true if node and its subnodes were successfully traversed. - * Returning false means that node was not examined and caller needs to dive into the node himself. - */ - function bindReachableStatement(node: Node): void { + function bindChildrenWorker(node: Node): void { + // Binding of JsDocComment should be done before the current block scope container changes. + // because the scope of JsDocComment should not be affected by whether the current node is a + // container or not. + if (isInJavaScriptFile(node) && node.jsDocComments) { + for (const jsDocComment of node.jsDocComments) { + bind(jsDocComment); + } + } if (checkUnreachable(node)) { forEachChild(node, bind); return; } - switch (node.kind) { case SyntaxKind.WhileStatement: bindWhileStatement(node); @@ -593,6 +589,9 @@ namespace ts { case SyntaxKind.VariableDeclaration: bindVariableDeclarationFlow(node); break; + case SyntaxKind.CallExpression: + bindCallExpressionFlow(node); + break; default: forEachChild(node, bind); break; @@ -852,6 +851,9 @@ namespace ts { bind(node.expression); if (node.kind === SyntaxKind.ReturnStatement) { hasExplicitReturn = true; + if (currentReturnTarget) { + addAntecedent(currentReturnTarget, currentFlow); + } } currentFlow = unreachableFlow; } @@ -916,8 +918,8 @@ namespace ts { preSwitchCaseFlow = currentFlow; bind(node.caseBlock); addAntecedent(postSwitchLabel, currentFlow); - const hasDefault = forEach(node.caseBlock.clauses, c => c.kind === SyntaxKind.DefaultClause); - if (!hasDefault) { + const hasNonEmptyDefault = forEach(node.caseBlock.clauses, c => c.kind === SyntaxKind.DefaultClause && c.statements.length); + if (!hasNonEmptyDefault) { addAntecedent(postSwitchLabel, preSwitchCaseFlow); } currentBreakTarget = saveBreakTarget; @@ -1102,35 +1104,65 @@ namespace ts { } } + function bindCallExpressionFlow(node: CallExpression) { + // If the target of the call expression is a function expression or arrow function we have + // an immediately invoked function expression (IIFE). Initialize the flowNode property to + // the current control flow (which includes evaluation of the IIFE arguments). + let expr: Expression = node.expression; + while (expr.kind === SyntaxKind.ParenthesizedExpression) { + expr = (expr).expression; + } + if (expr.kind === SyntaxKind.FunctionExpression || expr.kind === SyntaxKind.ArrowFunction) { + forEach(node.typeArguments, bind); + forEach(node.arguments, bind); + bind(node.expression); + } + else { + forEachChild(node, bind); + } + } + function getContainerFlags(node: Node): ContainerFlags { switch (node.kind) { case SyntaxKind.ClassExpression: case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: case SyntaxKind.EnumDeclaration: case SyntaxKind.ObjectLiteralExpression: case SyntaxKind.TypeLiteral: + case SyntaxKind.JSDocTypeLiteral: case SyntaxKind.JSDocRecordType: return ContainerFlags.IsContainer; + case SyntaxKind.InterfaceDeclaration: + return ContainerFlags.IsContainer | ContainerFlags.IsInterface; + + case SyntaxKind.JSDocFunctionType: + case SyntaxKind.ModuleDeclaration: + case SyntaxKind.TypeAliasDeclaration: + return ContainerFlags.IsContainer | ContainerFlags.HasLocals; + + case SyntaxKind.SourceFile: + return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals; + + case SyntaxKind.Constructor: + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.MethodSignature: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: case SyntaxKind.CallSignature: case SyntaxKind.ConstructSignature: case SyntaxKind.IndexSignature: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.Constructor: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: case SyntaxKind.FunctionType: - case SyntaxKind.JSDocFunctionType: case SyntaxKind.ConstructorType: + return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals | ContainerFlags.IsFunctionLike; + case SyntaxKind.FunctionExpression: case SyntaxKind.ArrowFunction: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.SourceFile: - case SyntaxKind.TypeAliasDeclaration: - return ContainerFlags.IsContainerWithLocals; + return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals | ContainerFlags.IsFunctionLike | ContainerFlags.IsFunctionExpression; + + case SyntaxKind.ModuleBlock: + return ContainerFlags.IsControlFlowContainer; case SyntaxKind.CatchClause: case SyntaxKind.ForStatement: @@ -1198,6 +1230,7 @@ namespace ts { case SyntaxKind.ObjectLiteralExpression: case SyntaxKind.InterfaceDeclaration: case SyntaxKind.JSDocRecordType: + case SyntaxKind.JSDocTypeLiteral: // Interface/Object-types always have their children added to the 'members' of // their container. They are only accessible through an instance of their // container, and are never in scope otherwise (even inside the body of the @@ -1226,7 +1259,7 @@ namespace ts { // their container in the tree. To accomplish this, we simply add their declared // symbol to the 'locals' of the container. These symbols can then be found as // the type checker walks up the containers, checking them for matching names. - return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); + return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes); } } @@ -1564,15 +1597,9 @@ namespace ts { if (!node) { return; } - node.parent = parent; - - const savedInStrictMode = inStrictMode; - if (!savedInStrictMode) { - updateStrictMode(node); - } - - // First we bind declaration nodes to a symbol if possible. We'll both create a symbol + const saveInStrictMode = inStrictMode; + // First we bind declaration nodes to a symbol if possible. We'll both create a symbol // and then potentially add the symbol to an appropriate symbol table. Possible // destination symbol tables are: // @@ -1580,60 +1607,43 @@ namespace ts { // 2) The 'members' table of the current container's symbol. // 3) The 'locals' table of the current container. // - // However, not all symbols will end up in any of these tables. 'Anonymous' symbols + // However, not all symbols will end up in any of these tables. 'Anonymous' symbols // (like TypeLiterals for example) will not be put in any table. bindWorker(node); - - // Then we recurse into the children of the node to bind them as well. For certain - // symbols we do specialized work when we recurse. For example, we'll keep track of - // the current 'container' node when it changes. This helps us know which symbol table - // a local should go into for example. - if (skipTransformFlagAggregation) { - bindChildren(node); + // Then we recurse into the children of the node to bind them as well. For certain + // symbols we do specialized work when we recurse. For example, we'll keep track of + // the current 'container' node when it changes. This helps us know which symbol table + // a local should go into for example. Since terminal nodes are known not to have + // children, as an optimization we don't process those. + if (node.kind > SyntaxKind.LastToken) { + const saveParent = parent; + parent = node; + const containerFlags = getContainerFlags(node); + if (containerFlags === ContainerFlags.None) { + bindChildren(node); + } + else { + bindContainer(node, containerFlags); + } + parent = saveParent; } - else if (node.transformFlags & TransformFlags.HasComputedFlags) { - skipTransformFlagAggregation = true; - bindChildren(node); - skipTransformFlagAggregation = false; - } - else { - const savedSubtreeTransformFlags = subtreeTransformFlags; - subtreeTransformFlags = 0; - bindChildren(node); - subtreeTransformFlags = savedSubtreeTransformFlags | computeTransformFlagsForNode(node, subtreeTransformFlags); - } - - inStrictMode = savedInStrictMode; - } - - function updateStrictMode(node: Node) { - switch (node.kind) { - case SyntaxKind.SourceFile: - case SyntaxKind.ModuleBlock: - updateStrictModeStatementList((node).statements); - return; - case SyntaxKind.Block: - if (isFunctionLike(node.parent)) { - updateStrictModeStatementList((node).statements); - } - return; - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - // All classes are automatically in strict mode in ES6. - inStrictMode = true; - return; + else if (!skipTransformFlagAggregation && (node.transformFlags & TransformFlags.HasComputedFlags) === 0) { + subtreeTransformFlags |= computeTransformFlagsForNode(node, 0); } + inStrictMode = saveInStrictMode; } function updateStrictModeStatementList(statements: NodeArray) { - for (const statement of statements) { - if (!isPrologueDirective(statement)) { - return; - } + if (!inStrictMode) { + for (const statement of statements) { + if (!isPrologueDirective(statement)) { + return; + } - if (isUseStrictPrologueDirective(statement)) { - inStrictMode = true; - return; + if (isUseStrictPrologueDirective(statement)) { + inStrictMode = true; + return; + } } } } @@ -1713,6 +1723,8 @@ namespace ts { case SyntaxKind.PropertySignature: case SyntaxKind.JSDocRecordMember: return bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property | ((node).questionToken ? SymbolFlags.Optional : SymbolFlags.None), SymbolFlags.PropertyExcludes); + case SyntaxKind.JSDocPropertyTag: + return bindJSDocProperty(node); case SyntaxKind.PropertyAssignment: case SyntaxKind.ShorthandPropertyAssignment: return bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property, SymbolFlags.PropertyExcludes); @@ -1720,7 +1732,7 @@ namespace ts { return bindPropertyOrMethodOrAccessor(node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes); case SyntaxKind.JsxSpreadAttribute: - hasJsxSpreadAttribute = true; + emitFlags |= NodeFlags.HasJsxSpreadAttribute; return; case SyntaxKind.CallSignature: @@ -1748,6 +1760,7 @@ namespace ts { case SyntaxKind.JSDocFunctionType: return bindFunctionOrConstructorType(node); case SyntaxKind.TypeLiteral: + case SyntaxKind.JSDocTypeLiteral: case SyntaxKind.JSDocRecordType: return bindAnonymousDeclaration(node, SymbolFlags.TypeLiteral, "__type"); case SyntaxKind.ObjectLiteralExpression: @@ -1765,9 +1778,12 @@ namespace ts { // Members of classes, interfaces, and modules case SyntaxKind.ClassExpression: case SyntaxKind.ClassDeclaration: + // All classes are automatically in strict mode in ES6. + inStrictMode = true; return bindClassLikeDeclaration(node); case SyntaxKind.InterfaceDeclaration: return bindBlockScopedDeclaration(node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes); + case SyntaxKind.JSDocTypedefTag: case SyntaxKind.TypeAliasDeclaration: return bindBlockScopedDeclaration(node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes); case SyntaxKind.EnumDeclaration: @@ -1790,7 +1806,15 @@ namespace ts { case SyntaxKind.ExportAssignment: return bindExportAssignment(node); case SyntaxKind.SourceFile: + updateStrictModeStatementList((node).statements); return bindSourceFileIfExternalModule(); + case SyntaxKind.Block: + if (!isFunctionLike(node.parent)) { + return; + } + // Fall through + case SyntaxKind.ModuleBlock: + return updateStrictModeStatementList((node).statements); } } @@ -1897,12 +1921,20 @@ namespace ts { } function bindThisPropertyAssignment(node: BinaryExpression) { - // Declare a 'member' in case it turns out the container was an ES5 class - if (container.kind === SyntaxKind.FunctionExpression || container.kind === SyntaxKind.FunctionDeclaration) { - container.symbol.members = container.symbol.members || {}; - // It's acceptable for multiple 'this' assignments of the same identifier to occur - declareSymbol(container.symbol.members, container.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes & ~SymbolFlags.Property); + // Declare a 'member' in case it turns out the container was an ES5 class or ES6 constructor + let assignee: Node; + if (container.kind === SyntaxKind.FunctionDeclaration || container.kind === SyntaxKind.FunctionDeclaration) { + assignee = container; } + else if (container.kind === SyntaxKind.Constructor) { + assignee = container.parent; + } + else { + return; + } + assignee.symbol.members = assignee.symbol.members || {}; + // It's acceptable for multiple 'this' assignments of the same identifier to occur + declareSymbol(assignee.symbol.members, assignee.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes & ~SymbolFlags.Property); } function bindPrototypePropertyAssignment(node: BinaryExpression) { @@ -1944,10 +1976,10 @@ namespace ts { function bindClassLikeDeclaration(node: ClassLikeDeclaration) { if (!isDeclarationFile(file) && !isInAmbientContext(node)) { if (getClassExtendsHeritageClauseElement(node) !== undefined) { - hasClassExtends = true; + emitFlags |= NodeFlags.HasClassExtends; } if (nodeIsDecorated(node)) { - hasDecorators = true; + emitFlags |= NodeFlags.HasDecorators; } } @@ -2023,8 +2055,7 @@ namespace ts { if (!isDeclarationFile(file) && !isInAmbientContext(node) && nodeIsDecorated(node)) { - hasDecorators = true; - hasParameterDecorators = true; + emitFlags |= (NodeFlags.HasDecorators | NodeFlags.HasParamDecorators); } if (inStrictMode) { @@ -2044,14 +2075,14 @@ namespace ts { // containing class. if (isParameterPropertyDeclaration(node)) { const classDeclaration = node.parent.parent; - declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes); + declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, SymbolFlags.Property | (node.questionToken ? SymbolFlags.Optional : SymbolFlags.None), SymbolFlags.PropertyExcludes); } } function bindFunctionDeclaration(node: FunctionDeclaration) { if (!isDeclarationFile(file) && !isInAmbientContext(node)) { if (isAsyncFunctionLike(node)) { - hasAsyncFunctions = true; + emitFlags |= NodeFlags.HasAsyncFunctions; } } @@ -2068,10 +2099,12 @@ namespace ts { function bindFunctionExpression(node: FunctionExpression) { if (!isDeclarationFile(file) && !isInAmbientContext(node)) { if (isAsyncFunctionLike(node)) { - hasAsyncFunctions = true; + emitFlags |= NodeFlags.HasAsyncFunctions; } } - + if (currentFlow) { + node.flowNode = currentFlow; + } checkStrictModeFunctionName(node); const bindingName = (node).name ? (node).name.text : "__function"; return bindAnonymousDeclaration(node, SymbolFlags.Function, bindingName); @@ -2080,10 +2113,10 @@ namespace ts { function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { if (!isDeclarationFile(file) && !isInAmbientContext(node)) { if (isAsyncFunctionLike(node)) { - hasAsyncFunctions = true; + emitFlags |= NodeFlags.HasAsyncFunctions; } if (nodeIsDecorated(node)) { - hasDecorators = true; + emitFlags |= NodeFlags.HasDecorators; } } @@ -2092,6 +2125,10 @@ namespace ts { : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); } + function bindJSDocProperty(node: JSDocPropertyTag) { + return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Property, SymbolFlags.PropertyExcludes); + } + // reachability checks function shouldReportErrorOnModuleDeclaration(node: ModuleDeclaration): boolean { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 98e2a63a6c9..585e4b90dd5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1178,11 +1178,7 @@ namespace ts { } // This function is only for imports with entity names - function getSymbolOfPartOfRightHandSideOfImportEquals(entityName: EntityName, importDeclaration?: ImportEqualsDeclaration): Symbol { - if (!importDeclaration) { - importDeclaration = getAncestor(entityName, SyntaxKind.ImportEqualsDeclaration); - Debug.assert(importDeclaration !== undefined); - } + function getSymbolOfPartOfRightHandSideOfImportEquals(entityName: EntityName, importDeclaration: ImportEqualsDeclaration, dontResolveAlias?: boolean): Symbol { // There are three things we might try to look for. In the following examples, // the search term is enclosed in |...|: // @@ -1194,13 +1190,13 @@ namespace ts { } // Check for case 1 and 3 in the above example if (entityName.kind === SyntaxKind.Identifier || entityName.parent.kind === SyntaxKind.QualifiedName) { - return resolveEntityName(entityName, SymbolFlags.Namespace); + return resolveEntityName(entityName, SymbolFlags.Namespace, /*ignoreErrors*/ false, dontResolveAlias); } else { // Case 2 in above example // entityName.kind could be a QualifiedName or a Missing identifier Debug.assert(entityName.parent.kind === SyntaxKind.ImportEqualsDeclaration); - return resolveEntityName(entityName, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace); + return resolveEntityName(entityName, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace, /*ignoreErrors*/ false, dontResolveAlias); } } @@ -1209,7 +1205,7 @@ namespace ts { } // Resolves a qualified name and any involved aliases - function resolveEntityName(name: EntityName | Expression, meaning: SymbolFlags, ignoreErrors?: boolean, location?: Node): Symbol { + function resolveEntityName(name: EntityName | Expression, meaning: SymbolFlags, ignoreErrors?: boolean, dontResolveAlias?: boolean, location?: Node): Symbol { if (nodeIsMissing(name)) { return undefined; } @@ -1227,7 +1223,7 @@ namespace ts { const left = name.kind === SyntaxKind.QualifiedName ? (name).left : (name).expression; const right = name.kind === SyntaxKind.QualifiedName ? (name).right : (name).name; - const namespace = resolveEntityName(left, SymbolFlags.Namespace, ignoreErrors, location); + const namespace = resolveEntityName(left, SymbolFlags.Namespace, ignoreErrors, dontResolveAlias, location); if (!namespace || namespace === unknownSymbol || nodeIsMissing(right)) { return undefined; } @@ -1243,7 +1239,7 @@ namespace ts { Debug.fail("Unknown entity name kind."); } Debug.assert((symbol.flags & SymbolFlags.Instantiated) === 0, "Should never get an instantiated symbol here."); - return symbol.flags & meaning ? symbol : resolveAlias(symbol); + return (symbol.flags & meaning) || dontResolveAlias ? symbol : resolveAlias(symbol); } function resolveExternalModuleName(location: Node, moduleReferenceExpression: Expression): Symbol { @@ -3583,8 +3579,22 @@ namespace ts { if (!pushTypeResolution(symbol, TypeSystemPropertyName.DeclaredType)) { return unknownType; } - const declaration = getDeclarationOfKind(symbol, SyntaxKind.TypeAliasDeclaration); - let type = getTypeFromTypeNode(declaration.type); + + let type: Type; + let declaration: JSDocTypedefTag | TypeAliasDeclaration = getDeclarationOfKind(symbol, SyntaxKind.JSDocTypedefTag); + if (declaration) { + if (declaration.jsDocTypeLiteral) { + type = getTypeFromTypeNode(declaration.jsDocTypeLiteral); + } + else { + type = getTypeFromTypeNode(declaration.typeExpression.type); + } + } + else { + declaration = getDeclarationOfKind(symbol, SyntaxKind.TypeAliasDeclaration); + type = getTypeFromTypeNode(declaration.type); + } + if (popTypeResolution()) { links.typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); if (links.typeParameters) { @@ -5255,6 +5265,7 @@ namespace ts { case SyntaxKind.FunctionType: case SyntaxKind.ConstructorType: case SyntaxKind.TypeLiteral: + case SyntaxKind.JSDocTypeLiteral: case SyntaxKind.JSDocFunctionType: case SyntaxKind.JSDocRecordType: return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node); @@ -6032,9 +6043,10 @@ namespace ts { function isKnownProperty(type: Type, name: string): boolean { if (type.flags & TypeFlags.ObjectType) { const resolved = resolveStructuredTypeMembers(type); - if ((relation === assignableRelation || relation === comparableRelation) && - (type === globalObjectType || isEmptyObjectType(resolved)) || - resolved.stringIndexInfo || resolved.numberIndexInfo || getPropertyOfType(type, name)) { + if ((relation === assignableRelation || relation === comparableRelation) && (type === globalObjectType || isEmptyObjectType(resolved)) || + resolved.stringIndexInfo || + (resolved.numberIndexInfo && isNumericLiteralName(name)) || + getPropertyOfType(type, name)) { return true; } } @@ -7646,7 +7658,7 @@ namespace ts { getInitialTypeOfBindingElement(node); } - function getFlowTypeOfReference(reference: Node, declaredType: Type, assumeInitialized: boolean) { + function getFlowTypeOfReference(reference: Node, declaredType: Type, assumeInitialized: boolean, includeOuterFunctions: boolean) { let key: string; if (!reference.flowNode || assumeInitialized && !(declaredType.flags & TypeFlags.Narrowable)) { return declaredType; @@ -7692,15 +7704,21 @@ namespace ts { getTypeAtFlowBranchLabel(flow) : getTypeAtFlowLoopLabel(flow); } - else if (flow.flags & FlowFlags.Unreachable) { + else if (flow.flags & FlowFlags.Start) { + // Check if we should continue with the control flow of the containing function. + const container = (flow).container; + if (container && includeOuterFunctions) { + flow = container.flowNode; + continue; + } + // At the top of the flow we have the initial type. + type = initialType; + } + else { // Unreachable code errors are reported in the binding phase. Here we // simply return the declared type to reduce follow-on errors. type = declaredType; } - else { - // At the top of the flow we have the initial type. - type = initialType; - } if (flow.flags & FlowFlags.Shared) { // Record visited node and the associated type in the cache. visitedFlowNodes[visitedFlowCount] = flow; @@ -8069,6 +8087,17 @@ namespace ts { return expression; } + function isDeclarationIncludedInFlow(reference: Node, declaration: Declaration, includeOuterFunctions: boolean) { + const declarationContainer = getContainingFunctionOrModule(declaration); + let container = getContainingFunctionOrModule(reference); + while (container !== declarationContainer && + (container.kind === SyntaxKind.FunctionExpression || container.kind === SyntaxKind.ArrowFunction) && + (includeOuterFunctions || getImmediatelyInvokedFunctionExpression(container))) { + container = getContainingFunctionOrModule(container); + } + return container === declarationContainer; + } + function checkIdentifier(node: Identifier): Type { const symbol = getResolvedSymbol(node); @@ -8125,10 +8154,11 @@ namespace ts { return type; } const declaration = localOrExportSymbol.valueDeclaration; + const includeOuterFunctions = isReadonlySymbol(localOrExportSymbol); const assumeInitialized = !strictNullChecks || (type.flags & TypeFlags.Any) !== 0 || !declaration || getRootDeclaration(declaration).kind === SyntaxKind.Parameter || isInAmbientContext(declaration) || - getContainingFunctionOrModule(declaration) !== getContainingFunctionOrModule(node); - const flowType = getFlowTypeOfReference(node, type, assumeInitialized); + !isDeclarationIncludedInFlow(node, declaration, includeOuterFunctions); + const flowType = getFlowTypeOfReference(node, type, assumeInitialized, includeOuterFunctions); if (!assumeInitialized && !(getNullableKind(type) & TypeFlags.Undefined) && getNullableKind(flowType) & TypeFlags.Undefined) { error(node, Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol)); // Return the declared type to reduce follow-on errors @@ -8377,7 +8407,7 @@ namespace ts { if (isClassLike(container.parent)) { const symbol = getSymbolOfNode(container.parent); const type = hasModifier(container, ModifierFlags.Static) ? getTypeOfSymbol(symbol) : (getDeclaredTypeOfSymbol(symbol)).thisType; - return getFlowTypeOfReference(node, type, /*assumeInitialized*/ true); + return getFlowTypeOfReference(node, type, /*assumeInitialized*/ true, /*includeOuterFunctions*/ true); } if (isInJavaScriptFile(node)) { @@ -8662,20 +8692,6 @@ namespace ts { return undefined; } - function getImmediatelyInvokedFunctionExpression(func: FunctionExpression | MethodDeclaration) { - if (isFunctionExpressionOrArrowFunction(func)) { - let prev: Node = func; - let parent: Node = func.parent; - while (parent.kind === SyntaxKind.ParenthesizedExpression) { - prev = parent; - parent = parent.parent; - } - if (parent.kind === SyntaxKind.CallExpression && (parent as CallExpression).expression === prev) { - return parent as CallExpression; - } - } - } - // In a variable, parameter or property declaration with a type annotation, // the contextual type of an initializer expression is the type of the variable, parameter or property. // Otherwise, in a parameter declaration of a contextually typed function expression, @@ -9956,9 +9972,9 @@ namespace ts { } const apparentType = getApparentType(getWidenedType(type)); - if (apparentType === unknownType) { - // handle cases when type is Type parameter with invalid constraint - return unknownType; + if (apparentType === unknownType || (type.flags & TypeFlags.TypeParameter && isTypeAny(apparentType))) { + // handle cases when type is Type parameter with invalid or any constraint + return apparentType; } const prop = getPropertyOfType(apparentType, right.text); if (!prop) { @@ -9993,7 +10009,7 @@ namespace ts { return propType; } } - return getFlowTypeOfReference(node, propType, /*assumeInitialized*/ true); + return getFlowTypeOfReference(node, propType, /*assumeInitialized*/ true, /*includeOuterFunctions*/ false); } function isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: string): boolean { @@ -11149,7 +11165,9 @@ namespace ts { // types are provided for the argument expressions, and the result is always of type Any. // We exclude union types because we may have a union of function types that happen to have // no common signatures. - if (isTypeAny(funcType) || (!callSignatures.length && !constructSignatures.length && !(funcType.flags & TypeFlags.Union) && isTypeAssignableTo(funcType, globalFunctionType))) { + if (isTypeAny(funcType) || + (isTypeAny(apparentType) && funcType.flags & TypeFlags.TypeParameter) || + (!callSignatures.length && !constructSignatures.length && !(funcType.flags & TypeFlags.Union) && isTypeAssignableTo(funcType, globalFunctionType))) { // The unknownType indicates that an error already occurred (and was reported). No // need to report another error in this case. if (funcType !== unknownType && node.typeArguments) { @@ -14529,6 +14547,12 @@ namespace ts { } function areDeclarationFlagsIdentical(left: Declaration, right: Declaration) { + if ((left.kind === SyntaxKind.Parameter && right.kind === SyntaxKind.VariableDeclaration) || + (left.kind === SyntaxKind.VariableDeclaration && right.kind === SyntaxKind.Parameter)) { + // Differences in optionality between parameters and variables are allowed. + return true; + } + if (hasQuestionToken(left) !== hasQuestionToken(right)) { return false; } @@ -16721,7 +16745,7 @@ namespace ts { node = node.parent; } - return node.parent && node.parent.kind === SyntaxKind.TypeReference; + return node.parent && (node.parent.kind === SyntaxKind.TypeReference || node.parent.kind === SyntaxKind.JSDocTypeReference) ; } function isHeritageClauseElementIdentifier(entityName: Node): boolean { @@ -16796,7 +16820,9 @@ namespace ts { if (entityName.kind !== SyntaxKind.PropertyAccessExpression) { if (isInRightSideOfImportOrExportAssignment(entityName)) { // Since we already checked for ExportAssignment, this really could only be an Import - return getSymbolOfPartOfRightHandSideOfImportEquals(entityName); + const importEqualsDeclaration = getAncestor(entityName, SyntaxKind.ImportEqualsDeclaration); + Debug.assert(importEqualsDeclaration !== undefined); + return getSymbolOfPartOfRightHandSideOfImportEquals(entityName, importEqualsDeclaration, /*dontResolveAlias*/ true); } } @@ -16855,7 +16881,7 @@ namespace ts { } } else if (isTypeReferenceIdentifier(entityName)) { - let meaning = entityName.parent.kind === SyntaxKind.TypeReference ? SymbolFlags.Type : SymbolFlags.Namespace; + let meaning = (entityName.parent.kind === SyntaxKind.TypeReference || entityName.parent.kind === SyntaxKind.JSDocTypeReference) ? SymbolFlags.Type : SymbolFlags.Namespace; // Include aliases in the meaning, this ensures that we do not follow aliases to where they point and instead // return the alias symbol. meaning |= SymbolFlags.Alias; @@ -16892,9 +16918,7 @@ namespace ts { if (node.kind === SyntaxKind.Identifier) { if (isInRightSideOfImportOrExportAssignment(node)) { - return node.parent.kind === SyntaxKind.ExportAssignment - ? getSymbolOfEntityNameOrPropertyAccessExpression(node) - : getSymbolOfPartOfRightHandSideOfImportEquals(node); + return getSymbolOfEntityNameOrPropertyAccessExpression(node); } else if (node.parent.kind === SyntaxKind.BindingElement && node.parent.parent.kind === SyntaxKind.ObjectBindingPattern && @@ -17425,14 +17449,14 @@ namespace ts { function getTypeReferenceSerializationKind(typeName: EntityName, location?: Node): TypeReferenceSerializationKind { // Resolve the symbol as a value to ensure the type can be reached at runtime during emit. - const valueSymbol = resolveEntityName(typeName, SymbolFlags.Value, /*ignoreErrors*/ true, location); + const valueSymbol = resolveEntityName(typeName, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location); const constructorType = valueSymbol ? getTypeOfSymbol(valueSymbol) : undefined; if (constructorType && isConstructorType(constructorType)) { return TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue; } // Resolve the symbol as a type so that we can provide a more useful hint for the type serializer. - const typeSymbol = resolveEntityName(typeName, SymbolFlags.Type, /*ignoreErrors*/ true, location); + const typeSymbol = resolveEntityName(typeName, SymbolFlags.Type, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location); // We might not be able to resolve type symbol so use unknown type in that case (eg error case) if (!typeSymbol) { return TypeReferenceSerializationKind.ObjectType; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 02d67c749bb..852b3ff9895 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -819,6 +819,10 @@ "category": "Error", "code": 1252 }, + "'{0}' tag cannot be used independently as a top level JSDoc tag.": { + "category": "Error", + "code": 1253 + }, "'with' statements are not allowed in an async function block.": { "category": "Error", "code": 1300 diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 8d190dc84a0..7e4410f3be7 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -5339,17 +5339,17 @@ const _super = (function (geti, seti) { // // TypeScript | Javascript // --------------------------------|------------------------------------ - // @dec | let C_1; - // class C { | let C = C_1 = class C { - // static x() { return C.y; } | static x() { return C_1.y; } - // static y = 1; | } + // @dec | let C_1 = class C { + // class C { | static x() { return C_1.y; } + // static x() { return C.y; } | } + // static y = 1; | let C = C_1; // } | C.y = 1; // | C = C_1 = __decorate([dec], C); // --------------------------------|------------------------------------ - // @dec | let C_1; - // export class C { | export let C = C_1 = class C { - // static x() { return C.y; } | static x() { return C_1.y; } - // static y = 1; | } + // @dec | let C_1 = class C { + // export class C { | static x() { return C_1.y; } + // static x() { return C.y; } | } + // static y = 1; | export let C = C_1; // } | C.y = 1; // | C = C_1 = __decorate([dec], C); // --------------------------------------------------------------------- @@ -5378,10 +5378,10 @@ const _super = (function (geti, seti) { // // TypeScript | Javascript // --------------------------------|------------------------------------ - // @dec | let C_1; - // export default class C { | let C = C_1 = class C { - // static x() { return C.y; } | static x() { return C_1.y; } - // static y = 1; | } + // @dec | let C_1 = class C { + // export default class C { | static x() { return C_1.y; } + // static x() { return C.y; } | }; + // static y = 1; | let C = C_1; // } | C.y = 1; // | C = C_1 = __decorate([dec], C); // | export default C; @@ -5395,20 +5395,20 @@ const _super = (function (geti, seti) { if (isDecorated && resolver.getNodeCheckFlags(node) & NodeCheckFlags.DecoratedClassWithSelfReference) { decoratedClassAlias = unescapeIdentifier(makeUniqueName(node.name ? node.name.text : "default")); decoratedClassAliases[getNodeId(node)] = decoratedClassAlias; - write(`let ${decoratedClassAlias};`); - writeLine(); } - if (isES6ExportedDeclaration(node) && !hasModifier(node, ModifierFlags.Default)) { + if (isES6ExportedDeclaration(node) && !hasModifier(node, ModifierFlags.Default) && decoratedClassAlias === undefined) { write("export "); } if (!isHoistedDeclarationInSystemModule) { write("let "); } - emitDeclarationName(node); if (decoratedClassAlias !== undefined) { - write(` = ${decoratedClassAlias}`); + write(`${decoratedClassAlias}`); + } + else { + emitDeclarationName(node); } write(" = "); @@ -5470,6 +5470,16 @@ const _super = (function (geti, seti) { emitToken(SyntaxKind.CloseBraceToken, node.members.end); if (rewriteAsClassExpression) { + if (decoratedClassAlias !== undefined) { + write(";"); + writeLine(); + if (isES6ExportedDeclaration(node) && !hasModifier(node, ModifierFlags.Default)) { + write("export "); + } + write("let "); + emitDeclarationName(node); + write(` = ${decoratedClassAlias}`); + } decoratedClassAliases[getNodeId(node)] = undefined; write(";"); } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 1b1e5d05ca2..0edd67341e6 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -402,6 +402,15 @@ namespace ts { return visitNode(cbNode, (node).typeExpression); case SyntaxKind.JSDocTemplateTag: return visitNodes(cbNodes, (node).typeParameters); + case SyntaxKind.JSDocTypedefTag: + return visitNode(cbNode, (node).typeExpression) || + visitNode(cbNode, (node).name) || + visitNode(cbNode, (node).jsDocTypeLiteral); + case SyntaxKind.JSDocTypeLiteral: + return visitNodes(cbNodes, (node).jsDocPropertyTags); + case SyntaxKind.JSDocPropertyTag: + return visitNode(cbNode, (node).typeExpression) || + visitNode(cbNode, (node).name); case SyntaxKind.PartiallyEmittedExpression: return visitNode(cbNode, (node).expression); } @@ -631,9 +640,14 @@ namespace ts { if (comments) { for (const comment of comments) { const jsDocComment = JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos); - if (jsDocComment) { - node.jsDocComment = jsDocComment; + if (!jsDocComment) { + continue; } + + if (!node.jsDocComments) { + node.jsDocComments = []; + } + node.jsDocComments.push(jsDocComment); } } } @@ -661,6 +675,13 @@ namespace ts { const saveParent = parent; parent = n; forEachChild(n, visitNode); + if (n.jsDocComments) { + for (const jsDocComment of n.jsDocComments) { + jsDocComment.parent = n; + parent = jsDocComment; + forEachChild(jsDocComment, visitNode); + } + } parent = saveParent; } } @@ -3393,8 +3414,8 @@ namespace ts { if (sourceFile.languageVariant !== LanguageVariant.JSX) { return false; } - // We are in JSX context and the token is part of JSXElement. - // Fall through + // We are in JSX context and the token is part of JSXElement. + // Fall through default: return true; } @@ -4095,9 +4116,9 @@ namespace ts { const isAsync = !!(getModifierFlags(node) & ModifierFlags.Async); node.name = isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) : - isGenerator ? doInYieldContext(parseOptionalIdentifier) : - isAsync ? doInAwaitContext(parseOptionalIdentifier) : - parseOptionalIdentifier(); + isGenerator ? doInYieldContext(parseOptionalIdentifier) : + isAsync ? doInAwaitContext(parseOptionalIdentifier) : + parseOptionalIdentifier(); fillSignature(SyntaxKind.ColonToken, /*yieldContext*/ isGenerator, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ false, node); node.body = parseFunctionBlock(/*allowYield*/ isGenerator, /*allowAwait*/ isAsync, /*ignoreMissingOpenBrace*/ false); @@ -5886,7 +5907,7 @@ namespace ts { } function checkForEmptyTypeArgumentList(typeArguments: NodeArray) { - if (parseDiagnostics.length === 0 && typeArguments && typeArguments.length === 0) { + if (parseDiagnostics.length === 0 && typeArguments && typeArguments.length === 0) { const start = typeArguments.pos - "<".length; const end = skipTrivia(sourceText, typeArguments.end) + ">".length; return parseErrorAtPosition(start, end - start, Diagnostics.Type_argument_list_cannot_be_empty); @@ -6045,7 +6066,6 @@ namespace ts { Debug.assert(end <= content.length); let tags: NodeArray; - let result: JSDocComment; // Check for /** (JSDoc opening part) @@ -6152,6 +6172,8 @@ namespace ts { return handleTemplateTag(atToken, tagName); case "type": return handleTypeTag(atToken, tagName); + case "typedef": + return handleTypedefTag(atToken, tagName); } } @@ -6259,6 +6281,122 @@ namespace ts { return finishNode(result); } + function handlePropertyTag(atToken: Node, tagName: Identifier): JSDocPropertyTag { + const typeExpression = tryParseTypeExpression(); + skipWhitespace(); + const name = parseJSDocIdentifierName(); + if (!name) { + parseErrorAtPosition(scanner.getStartPos(), /*length*/ 0, Diagnostics.Identifier_expected); + return undefined; + } + + const result = createNode(SyntaxKind.JSDocPropertyTag, atToken.pos); + result.atToken = atToken; + result.tagName = tagName; + result.name = name; + result.typeExpression = typeExpression; + return finishNode(result); + } + + function handleTypedefTag(atToken: Node, tagName: Identifier): JSDocTypedefTag { + const typeExpression = tryParseTypeExpression(); + skipWhitespace(); + + const typedefTag = createNode(SyntaxKind.JSDocTypedefTag, atToken.pos); + typedefTag.atToken = atToken; + typedefTag.tagName = tagName; + typedefTag.name = parseJSDocIdentifierName(); + typedefTag.typeExpression = typeExpression; + + if (typeExpression) { + if (typeExpression.type.kind === SyntaxKind.JSDocTypeReference) { + const jsDocTypeReference = typeExpression.type; + if (jsDocTypeReference.name.kind === SyntaxKind.Identifier) { + const name = jsDocTypeReference.name; + if (name.text === "Object") { + typedefTag.jsDocTypeLiteral = scanChildTags(); + } + } + } + if (!typedefTag.jsDocTypeLiteral) { + typedefTag.jsDocTypeLiteral = typeExpression.type; + } + } + else { + typedefTag.jsDocTypeLiteral = scanChildTags(); + } + + return finishNode(typedefTag); + + function scanChildTags(): JSDocTypeLiteral { + const jsDocTypeLiteral = createNode(SyntaxKind.JSDocTypeLiteral, scanner.getStartPos()); + let resumePos = scanner.getStartPos(); + let canParseTag = true; + let seenAsterisk = false; + let parentTagTerminated = false; + + while (token !== SyntaxKind.EndOfFileToken && !parentTagTerminated) { + nextJSDocToken(); + switch (token) { + case SyntaxKind.AtToken: + if (canParseTag) { + parentTagTerminated = !tryParseChildTag(jsDocTypeLiteral); + } + seenAsterisk = false; + break; + case SyntaxKind.NewLineTrivia: + resumePos = scanner.getStartPos() - 1; + canParseTag = true; + seenAsterisk = false; + break; + case SyntaxKind.AsteriskToken: + if (seenAsterisk) { + canParseTag = false; + } + seenAsterisk = true; + break; + case SyntaxKind.Identifier: + canParseTag = false; + case SyntaxKind.EndOfFileToken: + break; + } + } + scanner.setTextPos(resumePos); + return finishNode(jsDocTypeLiteral); + } + } + + function tryParseChildTag(parentTag: JSDocTypeLiteral): boolean { + Debug.assert(token === SyntaxKind.AtToken); + const atToken = createNode(SyntaxKind.AtToken, scanner.getStartPos()); + atToken.end = scanner.getTextPos(); + nextJSDocToken(); + + const tagName = parseJSDocIdentifierName(); + if (!tagName) { + return false; + } + + switch (tagName.text) { + case "type": + if (parentTag.jsDocTypeTag) { + // already has a @type tag, terminate the parent tag now. + return false; + } + parentTag.jsDocTypeTag = handleTypeTag(atToken, tagName); + return true; + case "prop": + case "property": + if (!parentTag.jsDocPropertyTags) { + parentTag.jsDocPropertyTags = >[]; + } + const propertyTag = handlePropertyTag(atToken, tagName); + parentTag.jsDocPropertyTags.push(propertyTag); + return true; + } + return false; + } + function handleTemplateTag(atToken: Node, tagName: Identifier): JSDocTemplateTag { if (forEach(tags, t => t.kind === SyntaxKind.JSDocTemplateTag)) { parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.text); @@ -6427,10 +6565,6 @@ namespace ts { node._children = undefined; } - if (node.jsDocComment) { - node.jsDocComment = undefined; - } - node.pos += delta; node.end += delta; @@ -6439,6 +6573,11 @@ namespace ts { } forEachChild(node, visitNode, visitArray); + if (node.jsDocComments) { + for (const jsDocComment of node.jsDocComments) { + forEachChild(jsDocComment, visitNode, visitArray); + } + } checkNodePositions(node, aggressiveChecks); } diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index ec3b1234adf..7f8fc2e6e5e 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -434,7 +434,7 @@ namespace ts { } /* @internal */ - export function skipTrivia(text: string, pos: number, stopAfterLineBreak?: boolean): number { + export function skipTrivia(text: string, pos: number, stopAfterLineBreak?: boolean, stopAtComments = false): number { if (positionIsSynthesized(pos)) { return pos; } @@ -460,6 +460,9 @@ namespace ts { pos++; continue; case CharacterCodes.slash: + if (stopAtComments) { + break; + } if (text.charCodeAt(pos + 1) === CharacterCodes.slash) { pos += 2; while (pos < text.length) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index db10d3fc8c4..84a09bdbb36 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -343,6 +343,9 @@ namespace ts { JSDocReturnTag, JSDocTypeTag, JSDocTemplateTag, + JSDocTypedefTag, + JSDocPropertyTag, + JSDocTypeLiteral, // Synthesized list SyntaxList, @@ -377,6 +380,10 @@ namespace ts { FirstBinaryOperator = LessThanToken, LastBinaryOperator = CaretEqualsToken, FirstNode = QualifiedName, + FirstJSDocNode = JSDocTypeExpression, + LastJSDocNode = JSDocTypeLiteral, + FirstJSDocTagNode = JSDocComment, + LastJSDocTagNode = JSDocTypeLiteral } export const enum NodeFlags { @@ -409,6 +416,7 @@ namespace ts { ReachabilityCheckFlags = HasImplicitReturn | HasExplicitReturn, EmitHelperFlags = HasClassExtends | HasDecorators | HasParamDecorators | HasAsyncFunctions, + ReachabilityAndEmitFlags = ReachabilityCheckFlags | EmitHelperFlags, // Parsing context flags ContextFlags = DisallowInContext | YieldContext | DecoratorContext | AwaitContext | JavaScriptFile, @@ -468,7 +476,7 @@ namespace ts { parent?: Node; // Parent node (initialized by binding) /* @internal */ original?: Node; // The original node if this is an updated node. /* @internal */ startsOnNewLine?: boolean; // Whether a synthesized node should start on a new line (used by transforms). - /* @internal */ jsDocComment?: JSDocComment; // JSDoc for the node, if it has any. Only for .js files. + /* @internal */ jsDocComments?: JSDocComment[]; // JSDoc for the node, if it has any. Only for .js files. /* @internal */ symbol?: Symbol; // Symbol declared by node (initialized by binding) /* @internal */ locals?: SymbolTable; // Locals associated with node (initialized by binding) /* @internal */ nextContainer?: Node; // Next container in declaration order (initialized by binding) @@ -650,6 +658,7 @@ namespace ts { // SyntaxKind.PropertyAssignment // SyntaxKind.ShorthandPropertyAssignment // SyntaxKind.EnumMember + // SyntaxKind.JSDocPropertyTag export interface VariableLikeDeclaration extends Declaration { propertyName?: PropertyName; dotDotDotToken?: Node; @@ -1578,6 +1587,25 @@ namespace ts { typeExpression: JSDocTypeExpression; } + // @kind(SyntaxKind.JSDocTypedefTag) + export interface JSDocTypedefTag extends JSDocTag, Declaration { + name?: Identifier; + typeExpression?: JSDocTypeExpression; + jsDocTypeLiteral?: JSDocTypeLiteral; + } + + // @kind(SyntaxKind.JSDocPropertyTag) + export interface JSDocPropertyTag extends JSDocTag, TypeElement { + name: Identifier; + typeExpression: JSDocTypeExpression; + } + + // @kind(SyntaxKind.JSDocTypeLiteral) + export interface JSDocTypeLiteral extends JSDocType { + jsDocPropertyTags?: NodeArray; + jsDocTypeTag?: JSDocTypeTag; + } + // @kind(SyntaxKind.JSDocParameterTag) export interface JSDocParameterTag extends JSDocTag { preParameterName?: Identifier; @@ -1605,6 +1633,13 @@ namespace ts { id?: number; // Node id used by flow type cache in checker } + // FlowStart represents the start of a control flow. For a function expression or arrow + // function, the container property references the function (which in turn has a flowNode + // property for the containing control flow). + export interface FlowStart extends FlowNode { + container?: FunctionExpression | ArrowFunction; + } + // FlowLabel represents a junction with multiple possible preceding control flows. export interface FlowLabel extends FlowNode { antecedents: FlowNode[]; @@ -3056,4 +3091,9 @@ namespace ts { /* @internal */ reattachFileDiagnostics(newFile: SourceFile): void; } + + // SyntaxKind.SyntaxList + export interface SyntaxList extends Node { + _children: Node[]; + } } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index cb326f1def4..2da5e71c25a 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -285,16 +285,36 @@ namespace ts { return !nodeIsMissing(node); } - export function getTokenPosOfNode(node: Node, sourceFile?: SourceFile): number { + export function getTokenPosOfNode(node: Node, sourceFile?: SourceFile, includeJsDocComment?: 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)) { return node.pos; } + if (isJSDocNode(node)) { + return skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos, /*stopAfterLineBreak*/ false, /*stopAtComments*/ true); + } + + if (includeJsDocComment && node.jsDocComments && node.jsDocComments.length > 0) { + return getTokenPosOfNode(node.jsDocComments[0]); + } + + // For a syntax list, it is possible that one of its children has JSDocComment nodes, while + // the syntax list itself considers them as normal trivia. Therefore if we simply skip + // trivia for the list, we may have skipped the JSDocComment as well. So we should process its + // first child to determine the actual position of its first token. + if (node.kind === SyntaxKind.SyntaxList && (node)._children.length > 0) { + return getTokenPosOfNode((node)._children[0], sourceFile, includeJsDocComment); + } + return skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos); } + export function isJSDocNode(node: Node) { + return node.kind >= SyntaxKind.FirstJSDocNode && node.kind <= SyntaxKind.LastJSDocNode; + } + export function getNonDecoratorTokenPosOfNode(node: Node, sourceFile?: SourceFile): number { if (nodeIsMissing(node) || !node.decorators) { return getTokenPosOfNode(node, sourceFile); @@ -1070,6 +1090,20 @@ namespace ts { } } + export function getImmediatelyInvokedFunctionExpression(func: Node): CallExpression { + if (func.kind === SyntaxKind.FunctionExpression || func.kind === SyntaxKind.ArrowFunction) { + let prev = func; + let parent = func.parent; + while (parent.kind === SyntaxKind.ParenthesizedExpression) { + prev = parent; + parent = parent.parent; + } + if (parent.kind === SyntaxKind.CallExpression && (parent as CallExpression).expression === prev) { + return parent as CallExpression; + } + } + } + /** * Determines whether a node is a property or element access expression for super. */ @@ -1437,21 +1471,23 @@ namespace ts { return undefined; } - const jsDocComment = getJSDocComment(node, checkParentVariableStatement); - if (!jsDocComment) { + const jsDocComments = getJSDocComments(node, checkParentVariableStatement); + if (!jsDocComments) { return undefined; } - for (const tag of jsDocComment.tags) { - if (tag.kind === kind) { - return tag; + for (const jsDocComment of jsDocComments) { + for (const tag of jsDocComment.tags) { + if (tag.kind === kind) { + return tag; + } } } } - function getJSDocComment(node: Node, checkParentVariableStatement: boolean): JSDocComment { - if (node.jsDocComment) { - return node.jsDocComment; + function getJSDocComments(node: Node, checkParentVariableStatement: boolean): JSDocComment[] { + if (node.jsDocComments) { + return node.jsDocComments; } // Try to recognize this pattern when node is initializer of variable declaration and JSDoc comments are on containing variable statement. // /** @@ -1467,7 +1503,7 @@ namespace ts { const variableStatementNode = isInitializerOfVariableDeclarationInStatement ? node.parent.parent.parent : undefined; if (variableStatementNode) { - return variableStatementNode.jsDocComment; + return variableStatementNode.jsDocComments; } // Also recognize when the node is the RHS of an assignment expression @@ -1478,12 +1514,12 @@ namespace ts { (parent as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken && parent.parent.kind === SyntaxKind.ExpressionStatement; if (isSourceOfAssignmentExpressionStatement) { - return parent.parent.jsDocComment; + return parent.parent.jsDocComments; } const isPropertyAssignmentExpression = parent && parent.kind === SyntaxKind.PropertyAssignment; if (isPropertyAssignmentExpression) { - return parent.jsDocComment; + return parent.jsDocComments; } } @@ -1508,14 +1544,16 @@ namespace ts { // annotation. const parameterName = (parameter.name).text; - const jsDocComment = getJSDocComment(parameter.parent, /*checkParentVariableStatement*/ true); - if (jsDocComment) { - for (const tag of jsDocComment.tags) { - if (tag.kind === SyntaxKind.JSDocParameterTag) { - const parameterTag = tag; - const name = parameterTag.preParameterName || parameterTag.postParameterName; - if (name.text === parameterName) { - return parameterTag; + const jsDocComments = getJSDocComments(parameter.parent, /*checkParentVariableStatement*/ true); + if (jsDocComments) { + for (const jsDocComment of jsDocComments) { + for (const tag of jsDocComment.tags) { + if (tag.kind === SyntaxKind.JSDocParameterTag) { + const parameterTag = tag; + const name = parameterTag.preParameterName || parameterTag.postParameterName; + if (name.text === parameterName) { + return parameterTag; + } } } } @@ -3752,7 +3790,8 @@ namespace ts { || kind === SyntaxKind.ShorthandPropertyAssignment || kind === SyntaxKind.TypeAliasDeclaration || kind === SyntaxKind.TypeParameter - || kind === SyntaxKind.VariableDeclaration; + || kind === SyntaxKind.VariableDeclaration + || kind === SyntaxKind.JSDocTypedefTag; } function isDeclarationStatementKind(kind: SyntaxKind) { diff --git a/src/harness/compilerRunner.ts b/src/harness/compilerRunner.ts index cc256e5bb6d..6a440a3e73e 100644 --- a/src/harness/compilerRunner.ts +++ b/src/harness/compilerRunner.ts @@ -1,6 +1,7 @@ /// /// /// +// In harness baselines, null is different than undefined. See `generateActual` in `harness.ts`. /* tslint:disable:no-null-keyword */ const enum CompilerTestType { @@ -11,7 +12,7 @@ const enum CompilerTestType { class CompilerBaselineRunner extends RunnerBase { private basePath = "tests/cases"; - private testSuiteName: string; + private testSuiteName: TestRunnerKind; private errors: boolean; private emit: boolean; private decl: boolean; @@ -40,6 +41,14 @@ class CompilerBaselineRunner extends RunnerBase { this.basePath += "/" + this.testSuiteName; } + public kind() { + return this.testSuiteName; + } + + public enumerateTestFiles() { + return this.enumerateFiles(this.basePath, /\.tsx?$/, { recursive: true }); + } + private makeUnitName(name: string, root: string) { return ts.isRootedDiskPath(name) ? name : ts.combinePaths(root, name); }; @@ -390,7 +399,7 @@ class CompilerBaselineRunner extends RunnerBase { // this will set up a series of describe/it blocks to run between the setup and cleanup phases if (this.tests.length === 0) { - const testFiles = this.enumerateFiles(this.basePath, /\.tsx?$/, { recursive: true }); + const testFiles = this.enumerateTestFiles(); testFiles.forEach(fn => { fn = fn.replace(/\\/g, "/"); this.checkTestCodeOutput(fn); diff --git a/src/harness/external/chai.d.ts b/src/harness/external/chai.d.ts index 814de75e7b2..59cf2834b27 100644 --- a/src/harness/external/chai.d.ts +++ b/src/harness/external/chai.d.ts @@ -169,7 +169,6 @@ declare module chai { function notEqual(actual: any, expected: any, message?: string): void; function isTrue(value: any, message?: string): void; function isFalse(value: any, message?: string): void; - function isNull(value: any, message?: string): void; - function isNotNull(value: any, message?: string): void; + function isOk(actual: any, message?: string): void; } } \ No newline at end of file diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 0cb557855d4..0abb1482043 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -18,7 +18,6 @@ /// /// /// -/* tslint:disable:no-null-keyword */ namespace FourSlash { ts.disableIncrementalParsing = false; @@ -198,7 +197,7 @@ namespace FourSlash { public lastKnownMarker: string = ""; // The file that's currently 'opened' - public activeFile: FourSlashFile = null; + public activeFile: FourSlashFile; // Whether or not we should format on keystrokes public enableFormatting = true; @@ -922,7 +921,7 @@ namespace FourSlash { public verifyCurrentParameterIsletiable(isVariable: boolean) { const signature = this.getActiveSignatureHelpItem(); - assert.isNotNull(signature); + assert.isOk(signature); assert.equal(isVariable, signature.isVariadic); } @@ -1487,6 +1486,12 @@ namespace FourSlash { this.fixCaretPosition(); } + public formatOnType(pos: number, key: string) { + const edits = this.languageService.getFormattingEditsAfterKeystroke(this.activeFile.fileName, pos, key, this.formatCodeOptions); + this.currentCaretPosition += this.applyEdits(this.activeFile.fileName, edits, /*isFormattingEdit*/ true); + this.fixCaretPosition(); + } + private updateMarkersForEdit(fileName: string, minChar: number, limChar: number, text: string) { for (let i = 0; i < this.testData.markers.length; i++) { const marker = this.testData.markers[i]; @@ -1911,7 +1916,7 @@ namespace FourSlash { public verifyNavigationItemsCount(expected: number, searchValue: string, matchKind?: string) { const items = this.languageService.getNavigateToItems(searchValue); let actual = 0; - let item: ts.NavigateToItem = null; + let item: ts.NavigateToItem; // Count only the match that match the same MatchKind for (let i = 0; i < items.length; i++) { @@ -1960,69 +1965,23 @@ namespace FourSlash { } } - public verifyNavigationBarCount(expected: number) { + public verifyNavigationBar(json: any) { const items = this.languageService.getNavigationBarItems(this.activeFile.fileName); - const actual = this.getNavigationBarItemsCount(items); - - if (expected !== actual) { - this.raiseError(`verifyNavigationBarCount failed - found: ${actual} navigation items, expected: ${expected}.`); - } - } - - private getNavigationBarItemsCount(items: ts.NavigationBarItem[]) { - let result = 0; - if (items) { - for (let i = 0, n = items.length; i < n; i++) { - result++; - result += this.getNavigationBarItemsCount(items[i].childItems); - } + if (JSON.stringify(items, replacer) !== JSON.stringify(json)) { + this.raiseError(`verifyNavigationBar failed - expected: ${JSON.stringify(json, undefined, 2)}, got: ${JSON.stringify(items, replacer, 2)}`); } - return result; - } - - public verifyNavigationBarContains(name: string, kind: string, fileName?: string, parentName?: string, isAdditionalSpan?: boolean, markerPosition?: number) { - fileName = fileName || this.activeFile.fileName; - const items = this.languageService.getNavigationBarItems(fileName); - - if (!items || items.length === 0) { - this.raiseError("verifyNavigationBarContains failed - found 0 navigation items, expected at least one."); - } - - if (this.navigationBarItemsContains(items, name, kind, parentName)) { - return; - } - - const missingItem = { name, kind, parentName }; - this.raiseError(`verifyNavigationBarContains failed - could not find the item: ${JSON.stringify(missingItem, undefined, 2)} in the returned list: (${JSON.stringify(items, undefined, 2)})`); - } - - private navigationBarItemsContains(items: ts.NavigationBarItem[], name: string, kind: string, parentName?: string) { - function recur(items: ts.NavigationBarItem[], curParentName: string) { - for (let i = 0; i < items.length; i++) { - const item = items[i]; - if (item && item.text === name && item.kind === kind && (!parentName || curParentName === parentName)) { - return true; - } - if (recur(item.childItems, item.text)) { - return true; - } - } - return false; - } - return recur(items, ""); - } - - public verifyNavigationBarChildItem(parent: string, name: string, kind: string) { - const items = this.languageService.getNavigationBarItems(this.activeFile.fileName); - - for (let i = 0; i < items.length; i++) { - const item = items[i]; - if (item.text === parent) { - if (this.navigationBarItemsContains(item.childItems, name, kind)) - return; - const missingItem = { name, kind }; - this.raiseError(`verifyNavigationBarChildItem failed - could not find the item: ${JSON.stringify(missingItem)} in the children list: (${JSON.stringify(item.childItems, undefined, 2)})`); + // Make the data easier to read. + function replacer(key: string, value: any) { + switch (key) { + case "spans": + // We won't ever check this. + return undefined; + case "childItems": + return value.length === 0 ? undefined : value; + default: + // Omit falsy values, those are presumed to be the default. + return value || undefined; } } } @@ -2183,7 +2142,7 @@ namespace FourSlash { } private findFile(indexOrName: any) { - let result: FourSlashFile = null; + let result: FourSlashFile; if (typeof indexOrName === "number") { const index = indexOrName; if (index >= this.testData.files.length) { @@ -2352,10 +2311,16 @@ ${code} const ranges: Range[] = []; // Stuff related to the subfile we're parsing - let currentFileContent: string = null; + let currentFileContent: string = undefined; let currentFileName = fileName; let currentFileOptions: { [s: string]: string } = {}; + function resetLocalData() { + currentFileContent = undefined; + currentFileOptions = {}; + currentFileName = fileName; + } + for (let i = 0; i < lines.length; i++) { let line = lines[i]; const lineLength = line.length; @@ -2368,7 +2333,7 @@ ${code} // Subfile content line // Append to the current subfile content, inserting a newline needed - if (currentFileContent === null) { + if (currentFileContent === undefined) { currentFileContent = ""; } else { @@ -2400,10 +2365,7 @@ ${code} // Store result file files.push(file); - // Reset local data - currentFileContent = null; - currentFileOptions = {}; - currentFileName = fileName; + resetLocalData(); } currentFileName = basePath + "/" + match[2]; @@ -2430,10 +2392,7 @@ ${code} // Store result file files.push(file); - // Reset local data - currentFileContent = null; - currentFileOptions = {}; - currentFileName = fileName; + resetLocalData(); } } } @@ -2498,7 +2457,7 @@ ${code} if (markerValue === undefined) { reportError(fileName, location.sourceLine, location.sourceColumn, "Object markers can not be empty"); - return null; + return undefined; } const marker: Marker = { @@ -2527,7 +2486,7 @@ ${code} if (markerMap[name] !== undefined) { const message = "Marker '" + name + "' is duplicated in the source file contents."; reportError(marker.fileName, location.sourceLine, location.sourceColumn, message); - return null; + return undefined; } else { markerMap[name] = marker; @@ -2546,7 +2505,7 @@ ${code} let output = ""; /// The current marker (or maybe multi-line comment?) we're parsing, possibly - let openMarker: LocationInformation = null; + let openMarker: LocationInformation = undefined; /// A stack of the open range markers that are still unclosed const openRanges: RangeLocationInformation[] = []; @@ -2654,7 +2613,7 @@ ${code} difference += i + 1 - openMarker.sourcePosition; // Reset the state - openMarker = null; + openMarker = undefined; state = State.none; } break; @@ -2676,7 +2635,7 @@ ${code} difference += i + 1 - openMarker.sourcePosition; // Reset the state - openMarker = null; + openMarker = undefined; state = State.none; } else if (validMarkerChars.indexOf(currentChar) < 0) { @@ -2688,7 +2647,7 @@ ${code} // Bail out the text we've gathered so far back into the output flush(i); lastNormalCharPosition = i; - openMarker = null; + openMarker = undefined; state = State.none; } @@ -2719,7 +2678,7 @@ ${code} reportError(fileName, openRange.sourceLine, openRange.sourceColumn, "Unterminated range."); } - if (openMarker !== null) { + if (openMarker) { reportError(fileName, openMarker.sourceLine, openMarker.sourceColumn, "Unterminated marker."); } @@ -3043,23 +3002,8 @@ namespace FourSlashInterface { this.DocCommentTemplate(/*expectedText*/ undefined, /*expectedOffset*/ undefined, /*empty*/ true); } - public navigationBarCount(count: number) { - this.state.verifyNavigationBarCount(count); - } - - // TODO: figure out what to do with the unused arguments. - public navigationBarContains( - name: string, - kind: string, - fileName?: string, - parentName?: string, - isAdditionalSpan?: boolean, - markerPosition?: number) { - this.state.verifyNavigationBarContains(name, kind, fileName, parentName, isAdditionalSpan, markerPosition); - } - - public navigationBarChildItem(parent: string, name: string, kind: string) { - this.state.verifyNavigationBarChildItem(parent, name, kind); + public navigationBar(json: any) { + this.state.verifyNavigationBar(json); } public navigationItemsListCount(count: number, searchValue: string, matchKind?: string) { @@ -3285,6 +3229,10 @@ namespace FourSlashInterface { this.state.formatSelection(this.state.getMarkerByName(startMarker).position, this.state.getMarkerByName(endMarker).position); } + public onType(posMarker: string, key: string) { + this.state.formatOnType(this.state.getMarkerByName(posMarker).position, key); + } + public setOption(name: string, value: number): void; public setOption(name: string, value: string): void; public setOption(name: string, value: boolean): void; diff --git a/src/harness/fourslashRunner.ts b/src/harness/fourslashRunner.ts index 386bd9e340c..d835054a868 100644 --- a/src/harness/fourslashRunner.ts +++ b/src/harness/fourslashRunner.ts @@ -1,7 +1,6 @@ /// /// /// -/* tslint:disable:no-null-keyword */ const enum FourSlashTestType { Native, @@ -12,7 +11,7 @@ const enum FourSlashTestType { class FourSlashRunner extends RunnerBase { protected basePath: string; - protected testSuiteName: string; + protected testSuiteName: TestRunnerKind; constructor(private testType: FourSlashTestType) { super(); @@ -36,9 +35,17 @@ class FourSlashRunner extends RunnerBase { } } + public enumerateTestFiles() { + return this.enumerateFiles(this.basePath, /\.ts/i, { recursive: false }); + } + + public kind() { + return this.testSuiteName; + } + public initializeTests() { if (this.tests.length === 0) { - this.tests = this.enumerateFiles(this.basePath, /\.ts/i, { recursive: false }); + this.tests = this.enumerateTestFiles(); } describe(this.testSuiteName + " tests", () => { diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 704eafdbd7d..49dcab4d80b 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -23,7 +23,6 @@ /// /// /// -/* tslint:disable:no-null-keyword */ // Block scoped definitions work poorly for global variables, temporarily enable var /* tslint:disable:no-var-keyword */ @@ -32,7 +31,7 @@ var _chai: typeof chai = require("chai"); var assert: typeof _chai.assert = _chai.assert; declare var __dirname: string; // Node-specific -var global = Function("return this").call(null); +var global = Function("return this").call(undefined); /* tslint:enable:no-var-keyword */ namespace Utils { @@ -222,6 +221,19 @@ namespace Utils { return k; } + // For some markers in SyntaxKind, we should print its original syntax name instead of + // the marker name in tests. + if (k === (ts).SyntaxKind.FirstJSDocNode || + k === (ts).SyntaxKind.LastJSDocNode || + k === (ts).SyntaxKind.FirstJSDocTagNode || + k === (ts).SyntaxKind.LastJSDocTagNode) { + for (const kindName in (ts).SyntaxKind) { + if ((ts).SyntaxKind[kindName] === k) { + return kindName; + } + } + } + return (ts).SyntaxKind[k]; } @@ -622,15 +634,9 @@ namespace Harness { } export function directoryName(path: string) { - let dirPath = pathModule.dirname(path); - + const dirPath = pathModule.dirname(path); // Node will just continue to repeat the root path, rather than return null - if (dirPath === path) { - dirPath = null; - } - else { - return dirPath; - } + return dirPath === path ? undefined : dirPath; } export let listFiles: typeof IO.listFiles = (path, spec?, options?) => { @@ -698,7 +704,7 @@ namespace Harness { xhr.send(); } catch (e) { - return { status: 404, responseText: null }; + return { status: 404, responseText: undefined }; } return waitForXHR(xhr); @@ -715,7 +721,7 @@ namespace Harness { } catch (e) { log(`XHR Error: ${e}`); - return { status: 500, responseText: null }; + return { status: 500, responseText: undefined }; } return waitForXHR(xhr); @@ -727,7 +733,7 @@ namespace Harness { } export function deleteFile(path: string) { - Http.writeToServerSync(serverRoot + path, "DELETE", null); + Http.writeToServerSync(serverRoot + path, "DELETE"); } export function directoryExists(path: string): boolean { @@ -738,7 +744,7 @@ namespace Harness { let dirPath = path; // root of the server if (dirPath.match(/localhost:\d+$/) || dirPath.match(/localhost:\d+\/$/)) { - dirPath = null; + dirPath = undefined; // path + fileName } else if (dirPath.indexOf(".") === -1) { @@ -795,7 +801,7 @@ namespace Harness { return response.responseText; } else { - return null; + return undefined; } } @@ -1493,7 +1499,9 @@ namespace Harness { const opts: CompilerSettings = {}; let match: RegExpExecArray; - while ((match = optionRegex.exec(content)) != null) { + /* tslint:disable:no-null-keyword */ + while ((match = optionRegex.exec(content)) !== null) { + /* tslint:enable:no-null-keyword */ opts[match[1]] = match[2]; } @@ -1510,9 +1518,9 @@ namespace Harness { const lines = Utils.splitContentByNewlines(code); // Stuff related to the subfile we're parsing - let currentFileContent: string = null; + let currentFileContent: string = undefined; let currentFileOptions: any = {}; - let currentFileName: any = null; + let currentFileName: any = undefined; let refs: string[] = []; for (let i = 0; i < lines.length; i++) { @@ -1540,7 +1548,7 @@ namespace Harness { testUnitData.push(newTestFile); // Reset local data - currentFileContent = null; + currentFileContent = undefined; currentFileOptions = {}; currentFileName = testMetaData[2]; refs = []; @@ -1553,7 +1561,7 @@ namespace Harness { else { // Subfile content line // Append to the current subfile content, inserting a newline needed - if (currentFileContent === null) { + if (currentFileContent === undefined) { currentFileContent = ""; } else { @@ -1676,7 +1684,9 @@ namespace Harness { // Store the content in the 'local' folder so we // can accept it later (manually) + /* tslint:disable:no-null-keyword */ if (actual !== null) { + /* tslint:enable:no-null-keyword */ IO.writeFile(actualFileName, actual); } @@ -1693,7 +1703,9 @@ namespace Harness { const refFileName = referencePath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder); + /* tslint:disable:no-null-keyword */ if (actual === null) { + /* tslint:enable:no-null-keyword */ actual = ""; } diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index a63b15d97e7..881e879e6e1 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -172,7 +172,7 @@ namespace Harness.LanguageService { */ public positionToLineAndCharacter(fileName: string, position: number): ts.LineAndCharacter { const script: ScriptInfo = this.fileNameToScript[fileName]; - assert.isNotNull(script); + assert.isOk(script); return ts.computeLineAndCharacterOfPosition(script.getLineMap(), position); } diff --git a/src/harness/loggedIO.ts b/src/harness/loggedIO.ts index d468b371fbe..3535decf121 100644 --- a/src/harness/loggedIO.ts +++ b/src/harness/loggedIO.ts @@ -1,7 +1,6 @@ /// /// /// -/* tslint:disable:no-null-keyword */ interface FileInformation { contents: string; @@ -94,7 +93,7 @@ namespace Playback { return lookup[s] = func(s); }); run.reset = () => { - lookup = null; + lookup = undefined; }; return run; @@ -170,7 +169,8 @@ namespace Playback { path => callAndRecord(underlying.fileExists(path), recordLog.fileExists, { path }), memoize(path => { // If we read from the file, it must exist - if (findResultByPath(wrapper, replayLog.filesRead, path, null) !== null) { + const noResult = {}; + if (findResultByPath(wrapper, replayLog.filesRead, path, noResult) !== noResult) { return true; } else { @@ -226,13 +226,7 @@ namespace Playback { (path, extension, exclude) => findResultByPath(wrapper, replayLog.directoriesRead.filter( d => { - if (d.extension === extension) { - if (d.exclude) { - return ts.arrayIsEqualTo(d.exclude, exclude); - } - return true; - } - return false; + return d.extension === extension; } ), path)); diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index 9cfd02b4e84..21f3f144b74 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -1,6 +1,5 @@ /// /// -/* tslint:disable:no-null-keyword */ // Test case is json of below type in tests/cases/project/ interface ProjectRunnerTestCase { @@ -37,11 +36,19 @@ interface BatchCompileProjectTestCaseResult extends CompileProjectFilesResult { } class ProjectRunner extends RunnerBase { + + public enumerateTestFiles() { + return this.enumerateFiles("tests/cases/project", /\.json$/, { recursive: true }); + } + + public kind(): TestRunnerKind { + return "project"; + } + public initializeTests() { if (this.tests.length === 0) { - const testFiles = this.enumerateFiles("tests/cases/project", /\.json$/, { recursive: true }); + const testFiles = this.enumerateTestFiles(); testFiles.forEach(fn => { - fn = fn.replace(/\\/g, "/"); this.runProjectTestCase(fn); }); } @@ -53,7 +60,7 @@ class ProjectRunner extends RunnerBase { private runProjectTestCase(testCaseFileName: string) { let testCase: ProjectRunnerTestCase & ts.CompilerOptions; - let testFileText: string = null; + let testFileText: string; try { testFileText = Harness.IO.readFile(testCaseFileName); } diff --git a/src/harness/runner.ts b/src/harness/runner.ts index 262980baa9a..c3bd015910c 100644 --- a/src/harness/runner.ts +++ b/src/harness/runner.ts @@ -20,8 +20,6 @@ /// /// -/* tslint:disable:no-null-keyword */ - let runners: RunnerBase[] = []; let iterations = 1; @@ -33,24 +31,91 @@ function runTests(runners: RunnerBase[]) { } } +function tryGetConfig(args: string[]) { + const prefix = "--config="; + const configPath = ts.forEach(args, arg => arg.lastIndexOf(prefix, 0) === 0 && arg.substr(prefix.length)); + // strip leading and trailing quotes from the path (necessary on Windows since shell does not do it automatically) + return configPath && configPath.replace(/(^[\"'])|([\"']$)/g, ""); +} + +function createRunner(kind: TestRunnerKind): RunnerBase { + switch (kind) { + case "conformance": + return new CompilerBaselineRunner(CompilerTestType.Conformance); + case "compiler": + return new CompilerBaselineRunner(CompilerTestType.Regressions); + case "fourslash": + return new FourSlashRunner(FourSlashTestType.Native); + case "fourslash-shims": + return new FourSlashRunner(FourSlashTestType.Shims); + case "fourslash-shims-pp": + return new FourSlashRunner(FourSlashTestType.ShimsWithPreprocess); + case "fourslash-server": + return new FourSlashRunner(FourSlashTestType.Server); + case "project": + return new ProjectRunner(); + case "rwc": + return new RWCRunner(); + case "test262": + return new Test262BaselineRunner(); + } +} + // users can define tests to run in mytest.config that will override cmd line args, otherwise use cmd line args (test.config), otherwise no options -let mytestconfig = "mytest.config"; -let testconfig = "test.config"; -let testConfigFile = - Harness.IO.fileExists(mytestconfig) ? Harness.IO.readFile(mytestconfig) : - (Harness.IO.fileExists(testconfig) ? Harness.IO.readFile(testconfig) : ""); -type TestConfig = { - tests?: string[]; - stackTraceLimit?: number | "full"; +const mytestconfigFileName = "mytest.config"; +const testconfigFileName = "test.config"; + +const customConfig = tryGetConfig(Harness.IO.args()); +let testConfigContent = + customConfig && Harness.IO.fileExists(customConfig) + ? Harness.IO.readFile(customConfig) + : Harness.IO.fileExists(mytestconfigFileName) + ? Harness.IO.readFile(mytestconfigFileName) + : Harness.IO.fileExists(testconfigFileName) ? Harness.IO.readFile(testconfigFileName) : ""; + +let taskConfigsFolder: string; +let workerCount: number; +let runUnitTests = true; + +interface TestConfig { light?: boolean; -}; + taskConfigsFolder?: string; + workerCount?: number; + stackTraceLimit?: number | "full"; + tasks?: TaskSet[]; + test?: string[]; + runUnitTests?: boolean; +} -if (testConfigFile !== "") { - const testConfig = JSON.parse(testConfigFile); +interface TaskSet { + runner: TestRunnerKind; + files: string[]; +} + +if (testConfigContent !== "") { + const testConfig = JSON.parse(testConfigContent); if (testConfig.light) { Harness.lightMode = true; } + if (testConfig.taskConfigsFolder) { + taskConfigsFolder = testConfig.taskConfigsFolder; + } + if (testConfig.runUnitTests !== undefined) { + runUnitTests = testConfig.runUnitTests; + } + if (testConfig.workerCount) { + workerCount = testConfig.workerCount; + } + if (testConfig.tasks) { + for (const taskSet of testConfig.tasks) { + const runner = createRunner(taskSet.runner); + for (const file of taskSet.files) { + runner.addTest(file); + } + runners.push(runner); + } + } if (testConfig.stackTraceLimit === "full") { (Error).stackTraceLimit = Infinity; @@ -59,8 +124,8 @@ if (testConfigFile !== "") { (Error).stackTraceLimit = testConfig.stackTraceLimit; } - if (testConfig.tests && testConfig.tests.length > 0) { - for (const option of testConfig.tests) { + if (testConfig.test && testConfig.test.length > 0) { + for (const option of testConfig.test) { if (!option) { continue; } @@ -121,4 +186,41 @@ if (runners.length === 0) { // runners.push(new GeneratedFourslashRunner()); } -runTests(runners); +if (taskConfigsFolder) { + // this instance of mocha should only partition work but not run actual tests + runUnitTests = false; + const workerConfigs: TestConfig[] = []; + for (let i = 0; i < workerCount; i++) { + // pass light mode settings to workers + workerConfigs.push({ light: Harness.lightMode, tasks: [] }); + } + + for (const runner of runners) { + const files = runner.enumerateTestFiles(); + const chunkSize = Math.floor(files.length / workerCount) + 1; // add extra 1 to prevent missing tests due to rounding + for (let i = 0; i < workerCount; i++) { + const startPos = i * chunkSize; + const len = Math.min(chunkSize, files.length - startPos); + if (len !== 0) { + workerConfigs[i].tasks.push({ + runner: runner.kind(), + files: files.slice(startPos, startPos + len) + }); + } + } + } + + for (let i = 0; i < workerCount; i++) { + const config = workerConfigs[i]; + // use last worker to run unit tests + config.runUnitTests = i === workerCount - 1; + Harness.IO.writeFile(ts.combinePaths(taskConfigsFolder, `task-config${i}.json`), JSON.stringify(workerConfigs[i])); + } +} +else { + runTests(runners); +} +if (!runUnitTests) { + // patch `describe` to skip unit tests + describe = describe.skip; +} \ No newline at end of file diff --git a/src/harness/runnerbase.ts b/src/harness/runnerbase.ts index a114e8c3201..81da0907714 100644 --- a/src/harness/runnerbase.ts +++ b/src/harness/runnerbase.ts @@ -1,5 +1,10 @@ /// + +type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project" | "rwc" | "test262"; +type CompilerTestKind = "conformance" | "compiler"; +type FourslashTestKind = "fourslash" | "fourslash-shims" | "fourslash-shims-pp" | "fourslash-server"; + abstract class RunnerBase { constructor() { } @@ -12,9 +17,13 @@ abstract class RunnerBase { } public enumerateFiles(folder: string, regex?: RegExp, options?: { recursive: boolean }): string[] { - return Harness.IO.listFiles(Harness.userSpecifiedRoot + folder, regex, { recursive: (options ? options.recursive : false) }); + return ts.map(Harness.IO.listFiles(Harness.userSpecifiedRoot + folder, regex, { recursive: (options ? options.recursive : false) }), ts.normalizeSlashes); } + abstract kind(): TestRunnerKind; + + abstract enumerateTestFiles(): string[]; + /** Setup the runner's tests so that they are ready to be executed by the harness * The first test should be a describe/it block that sets up the harness's compiler instance appropriately */ diff --git a/src/harness/rwcRunner.ts b/src/harness/rwcRunner.ts index 39231435bf5..2ca69b09126 100644 --- a/src/harness/rwcRunner.ts +++ b/src/harness/rwcRunner.ts @@ -2,6 +2,7 @@ /// /// /// +// In harness baselines, null is different than undefined. See `generateActual` in `harness.ts`. /* tslint:disable:no-null-keyword */ namespace RWC { @@ -123,7 +124,7 @@ namespace RWC { opts.options.noLib = true; // Emit the results - compilerOptions = null; + compilerOptions = undefined; const output = Harness.Compiler.compileFiles( inputFiles, otherFiles, @@ -139,7 +140,7 @@ namespace RWC { function getHarnessCompilerInputUnit(fileName: string): Harness.Compiler.TestFile { const unitName = ts.normalizeSlashes(Harness.IO.resolvePath(fileName)); - let content: string = null; + let content: string; try { content = Harness.IO.readFile(unitName); } @@ -223,12 +224,20 @@ namespace RWC { class RWCRunner extends RunnerBase { private static sourcePath = "internal/cases/rwc/"; + public enumerateTestFiles() { + return Harness.IO.listFiles(RWCRunner.sourcePath, /.+\.json$/); + } + + public kind(): TestRunnerKind { + return "rwc"; + } + /** Setup the runner's tests so that they are ready to be executed by the harness * The first test should be a describe/it block that sets up the harness's compiler instance appropriately */ public initializeTests(): void { // Read in and evaluate the test list - const testList = Harness.IO.listFiles(RWCRunner.sourcePath, /.+\.json$/); + const testList = this.enumerateTestFiles(); for (let i = 0; i < testList.length; i++) { this.runTest(testList[i]); } diff --git a/src/harness/test262Runner.ts b/src/harness/test262Runner.ts index cc9957c1fac..c44b2286b83 100644 --- a/src/harness/test262Runner.ts +++ b/src/harness/test262Runner.ts @@ -1,5 +1,6 @@ /// /// +// In harness baselines, null is different than undefined. See `generateActual` in `harness.ts`. /* tslint:disable:no-null-keyword */ class Test262BaselineRunner extends RunnerBase { @@ -97,12 +98,20 @@ class Test262BaselineRunner extends RunnerBase { }); } + public kind(): TestRunnerKind { + return "test262"; + } + + public enumerateTestFiles() { + return ts.map(this.enumerateFiles(Test262BaselineRunner.basePath, Test262BaselineRunner.testFileExtensionRegex, { recursive: true }), ts.normalizePath); + } + public initializeTests() { // this will set up a series of describe/it blocks to run between the setup and cleanup phases if (this.tests.length === 0) { - const testFiles = this.enumerateFiles(Test262BaselineRunner.basePath, Test262BaselineRunner.testFileExtensionRegex, { recursive: true }); + const testFiles = this.enumerateTestFiles(); testFiles.forEach(fn => { - this.runTest(ts.normalizePath(fn)); + this.runTest(fn); }); } else { diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 2f5f10752f4..ef8fddcfb3a 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -81,6 +81,12 @@ namespace ts.formatting { while (isWhiteSpace(sourceFile.text.charCodeAt(endOfFormatSpan)) && !isLineBreak(sourceFile.text.charCodeAt(endOfFormatSpan))) { endOfFormatSpan--; } + // if the character at the end of the span is a line break, we shouldn't include it, because it indicates we don't want to + // touch the current line at all. Also, on some OSes the line break consists of two characters (\r\n), we should test if the + // previous character before the end of format span is line break character as well. + if (isLineBreak(sourceFile.text.charCodeAt(endOfFormatSpan))) { + endOfFormatSpan--; + } const span = { // get start position for the previous line pos: getStartPositionOfLine(line - 1, sourceFile), diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 84337909db9..253df86c7a3 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -9,16 +9,10 @@ namespace ts.NavigationBar { return getJsNavigationBarItems(sourceFile, compilerOptions); } - // If the source file has any child items, then it included in the tree - // and takes lexical ownership of all other top-level items. - let hasGlobalNode = false; - return getItemsWorker(getTopLevelNodes(sourceFile), createTopLevelItem); function getIndent(node: Node): number { - // If we have a global node in the tree, - // then it adds an extra layer of depth to all subnodes. - let indent = hasGlobalNode ? 1 : 0; + let indent = 1; // Global node is the only one with indent 0. let current = node.parent; while (current) { @@ -104,6 +98,7 @@ namespace ts.NavigationBar { case SyntaxKind.ImportEqualsDeclaration: case SyntaxKind.ImportSpecifier: case SyntaxKind.ExportSpecifier: + case SyntaxKind.TypeAliasDeclaration: childNodes.push(node); break; } @@ -140,7 +135,7 @@ namespace ts.NavigationBar { function sortNodes(nodes: Node[]): Node[] { return nodes.slice(0).sort((n1: Declaration, n2: Declaration) => { if (n1.name && n2.name) { - return getPropertyNameForPropertyNameNode(n1.name).localeCompare(getPropertyNameForPropertyNameNode(n2.name)); + return localeCompareFix(getPropertyNameForPropertyNameNode(n1.name), getPropertyNameForPropertyNameNode(n2.name)); } else if (n1.name) { return 1; @@ -152,6 +147,16 @@ namespace ts.NavigationBar { return n1.kind - n2.kind; } }); + + // node 0.10 treats "a" as greater than "B". + // For consistency, sort alphabetically, falling back to which is lower-case. + function localeCompareFix(a: string, b: string) { + const cmp = a.toLowerCase().localeCompare(b.toLowerCase()); + if (cmp !== 0) + return cmp; + // Return the *opposite* of the `<` operator, which works the same in node 0.10 and 6.0. + return a < b ? 1 : a > b ? -1 : 0; + } } function addTopLevelNodes(nodes: Node[], topLevelNodes: Node[]): void { @@ -320,9 +325,15 @@ namespace ts.NavigationBar { case SyntaxKind.EnumMember: return createItem(node, getTextOfNode((node).name), ts.ScriptElementKind.memberVariableElement); + case SyntaxKind.ModuleDeclaration: + return createItem(node, getModuleName(node), ts.ScriptElementKind.moduleElement); + case SyntaxKind.InterfaceDeclaration: return createItem(node, getTextOfNode((node).name), ts.ScriptElementKind.interfaceElement); + case SyntaxKind.TypeAliasDeclaration: + return createItem(node, getTextOfNode((node).name), ts.ScriptElementKind.typeElement); + case SyntaxKind.CallSignature: return createItem(node, "()", ts.ScriptElementKind.callSignatureElement); @@ -333,6 +344,9 @@ namespace ts.NavigationBar { case SyntaxKind.PropertySignature: return createItem(node, getTextOfNode((node).name), ts.ScriptElementKind.memberVariableElement); + case SyntaxKind.ClassDeclaration: + return createItem(node, getTextOfNode((node).name), ts.ScriptElementKind.classElement); + case SyntaxKind.FunctionDeclaration: return createItem(node, getTextOfNode((node).name), ts.ScriptElementKind.functionElement); @@ -436,26 +450,6 @@ namespace ts.NavigationBar { return undefined; - function getModuleName(moduleDeclaration: ModuleDeclaration): string { - // We want to maintain quotation marks. - if (isAmbientModule(moduleDeclaration)) { - return getTextOfNode(moduleDeclaration.name); - } - - // Otherwise, we need to aggregate each identifier to build up the qualified name. - const result: string[] = []; - - result.push(moduleDeclaration.name.text); - - while (moduleDeclaration.body && moduleDeclaration.body.kind === SyntaxKind.ModuleDeclaration) { - moduleDeclaration = moduleDeclaration.body; - - result.push(moduleDeclaration.name.text); - } - - return result.join("."); - } - function createModuleItem(node: ModuleDeclaration): NavigationBarItem { const moduleName = getModuleName(node); @@ -521,11 +515,6 @@ namespace ts.NavigationBar { function createSourceFileItem(node: SourceFile): ts.NavigationBarItem { const childItems = getItemsWorker(getChildNodes(node.statements), createChildItem); - if (childItems === undefined || childItems.length === 0) { - return undefined; - } - - hasGlobalNode = true; const rootName = isExternalModule(node) ? "\"" + escapeString(getBaseFileName(removeFileExtension(normalizePath(node.fileName)))) + "\"" : ""; @@ -590,6 +579,26 @@ namespace ts.NavigationBar { } } + function getModuleName(moduleDeclaration: ModuleDeclaration): string { + // We want to maintain quotation marks. + if (isAmbientModule(moduleDeclaration)) { + return getTextOfNode(moduleDeclaration.name); + } + + // Otherwise, we need to aggregate each identifier to build up the qualified name. + const result: string[] = []; + + result.push(moduleDeclaration.name.text); + + while (moduleDeclaration.body && moduleDeclaration.body.kind === SyntaxKind.ModuleDeclaration) { + moduleDeclaration = moduleDeclaration.body; + + result.push(moduleDeclaration.name.text); + } + + return result.join("."); + } + function removeComputedProperties(node: EnumDeclaration): Declaration[] { return filter(node.members, member => member.name === undefined || member.name.kind !== SyntaxKind.ComputedPropertyName); } @@ -643,6 +652,12 @@ namespace ts.NavigationBar { topItem.childItems.push(newItem); } + if (node.jsDocComments && node.jsDocComments.length > 0) { + for (const jsDocComment of node.jsDocComments) { + visitNode(jsDocComment); + } + } + // Add a level if traversing into a container if (newItem && (isFunctionLike(node) || isClassLike(node))) { const lastTop = topItem; @@ -722,6 +737,27 @@ namespace ts.NavigationBar { } const declName = declarationNameToString(decl.name); return getNavBarItem(declName, ScriptElementKind.constElement, [getNodeSpan(node)]); + case SyntaxKind.JSDocTypedefTag: + if ((node).name) { + return getNavBarItem( + (node).name.text, + ScriptElementKind.typeElement, + [getNodeSpan(node)]); + } + else { + const parentNode = node.parent && node.parent.parent; + if (parentNode && parentNode.kind === SyntaxKind.VariableStatement) { + if ((parentNode).declarationList.declarations.length > 0) { + const nameIdentifier = (parentNode).declarationList.declarations[0].name; + if (nameIdentifier.kind === SyntaxKind.Identifier) { + return getNavBarItem( + (nameIdentifier).text, + ScriptElementKind.typeElement, + [getNodeSpan(node)]); + } + } + } + } default: return undefined; } @@ -792,7 +828,7 @@ namespace ts.NavigationBar { } function getNodeSpan(node: Node) { - return node.kind === SyntaxKind.SourceFile + return node.kind === SyntaxKind.SourceFile ? createTextSpanFromBounds(node.getFullStart(), node.getEnd()) : createTextSpanFromBounds(node.getStart(), node.getEnd()); } diff --git a/src/services/services.ts b/src/services/services.ts index a82de3de121..02a8897ef5f 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -20,7 +20,7 @@ namespace ts { getChildCount(sourceFile?: SourceFile): number; getChildAt(index: number, sourceFile?: SourceFile): Node; getChildren(sourceFile?: SourceFile): Node[]; - getStart(sourceFile?: SourceFile): number; + getStart(sourceFile?: SourceFile, includeJsDocComment?: boolean): number; getFullStart(): number; getEnd(): number; getWidth(sourceFile?: SourceFile): number; @@ -172,6 +172,9 @@ namespace ts { "static", "throws", "type", + "typedef", + "property", + "prop", "version" ]; let jsDocCompletionEntries: CompletionEntry[]; @@ -189,6 +192,7 @@ namespace ts { public end: number; public flags: NodeFlags; public parent: Node; + public jsDocComments: JSDocComment[]; public original: Node; public transformFlags: TransformFlags; public excludeTransformFlags: TransformFlags; @@ -209,8 +213,8 @@ namespace ts { return getSourceFileOfNode(this); } - public getStart(sourceFile?: SourceFile): number { - return getTokenPosOfNode(this, sourceFile); + public getStart(sourceFile?: SourceFile, includeJsDocComment?: boolean): number { + return getTokenPosOfNode(this, sourceFile, includeJsDocComment); } public getFullStart(): number { @@ -241,12 +245,14 @@ namespace ts { return (sourceFile || this.getSourceFile()).text.substring(this.getStart(), this.getEnd()); } - private addSyntheticNodes(nodes: Node[], pos: number, end: number): number { + private addSyntheticNodes(nodes: Node[], pos: number, end: number, useJSDocScanner?: boolean): number { scanner.setTextPos(pos); while (pos < end) { - const token = scanner.scan(); + const token = useJSDocScanner ? scanner.scanJSDocToken() : scanner.scan(); const textPos = scanner.getTextPos(); - nodes.push(createNode(token, pos, textPos, 0, this)); + if (textPos <= end) { + nodes.push(createNode(token, pos, textPos, 0, this)); + } pos = textPos; } return pos; @@ -276,20 +282,27 @@ namespace ts { scanner.setText((sourceFile || this.getSourceFile()).text); children = []; let pos = this.pos; + const useJSDocScanner = this.kind >= SyntaxKind.FirstJSDocTagNode && this.kind <= SyntaxKind.LastJSDocTagNode; const processNode = (node: Node) => { if (pos < node.pos) { - pos = this.addSyntheticNodes(children, pos, node.pos); + pos = this.addSyntheticNodes(children, pos, node.pos, useJSDocScanner); } children.push(node); pos = node.end; }; const processNodes = (nodes: NodeArray) => { if (pos < nodes.pos) { - pos = this.addSyntheticNodes(children, pos, nodes.pos); + pos = this.addSyntheticNodes(children, pos, nodes.pos, useJSDocScanner); } children.push(this.createSyntaxList(>nodes)); pos = nodes.end; }; + // jsDocComments need to be the first children + if (this.jsDocComments) { + for (const jsDocComment of this.jsDocComments) { + processNode(jsDocComment); + } + } forEachChild(this, processNode, processNodes); if (pos < this.end) { this.addSyntheticNodes(children, pos, this.end); @@ -5643,7 +5656,7 @@ namespace ts { const sourceFile = getValidSourceFile(fileName); - const node = getTouchingPropertyName(sourceFile, position); + const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); if (node === sourceFile) { return undefined; } @@ -6005,7 +6018,8 @@ namespace ts { const sourceFile = container.getSourceFile(); const tripleSlashDirectivePrefixRegex = /^\/\/\/\s*= start and (position < end or (position === end && token is keyword or identifier)) */ - export function getTouchingWord(sourceFile: SourceFile, position: number): Node { - return getTouchingToken(sourceFile, position, n => isWord(n.kind)); + export function getTouchingWord(sourceFile: SourceFile, position: number, includeJsDocComment = false): Node { + return getTouchingToken(sourceFile, position, n => isWord(n.kind), includeJsDocComment); } /* Gets the token whose text has range [start, end) and position >= start * and (position < end or (position === end && token is keyword or identifier or numeric/string literal)) */ - export function getTouchingPropertyName(sourceFile: SourceFile, position: number): Node { - return getTouchingToken(sourceFile, position, n => isPropertyName(n.kind)); + export function getTouchingPropertyName(sourceFile: SourceFile, position: number, includeJsDocComment = false): Node { + return getTouchingToken(sourceFile, position, n => isPropertyName(n.kind), includeJsDocComment); } /** Returns the token if position is in [start, end) or if position === end and includeItemAtEndPosition(token) === true */ - export function getTouchingToken(sourceFile: SourceFile, position: number, includeItemAtEndPosition?: (n: Node) => boolean): Node { - return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ false, includeItemAtEndPosition); + export function getTouchingToken(sourceFile: SourceFile, position: number, includeItemAtEndPosition?: (n: Node) => boolean, includeJsDocComment = false): Node { + return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ false, includeItemAtEndPosition, includeJsDocComment); } /** Returns a token if position is in [start-of-leading-trivia, end) */ - export function getTokenAtPosition(sourceFile: SourceFile, position: number): Node { - return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ true, /*includeItemAtEndPosition*/ undefined); + export function getTokenAtPosition(sourceFile: SourceFile, position: number, includeJsDocComment = false): Node { + return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ true, /*includeItemAtEndPosition*/ undefined, includeJsDocComment); } /** Get the token whose text contains the position */ - function getTokenAtPositionWorker(sourceFile: SourceFile, position: number, allowPositionInLeadingTrivia: boolean, includeItemAtEndPosition: (n: Node) => boolean): Node { + function getTokenAtPositionWorker(sourceFile: SourceFile, position: number, allowPositionInLeadingTrivia: boolean, includeItemAtEndPosition: (n: Node) => boolean, includeJsDocComment = false): Node { let current: Node = sourceFile; outer: while (true) { if (isToken(current)) { @@ -264,10 +264,34 @@ namespace ts { return current; } + if (includeJsDocComment) { + const jsDocChildren = ts.filter(current.getChildren(), isJSDocNode); + for (const jsDocChild of jsDocChildren) { + const start = allowPositionInLeadingTrivia ? jsDocChild.getFullStart() : jsDocChild.getStart(sourceFile, includeJsDocComment); + if (start <= position) { + const end = jsDocChild.getEnd(); + if (position < end || (position === end && jsDocChild.kind === SyntaxKind.EndOfFileToken)) { + current = jsDocChild; + continue outer; + } + else if (includeItemAtEndPosition && end === position) { + const previousToken = findPrecedingToken(position, sourceFile, jsDocChild); + if (previousToken && includeItemAtEndPosition(previousToken)) { + return previousToken; + } + } + } + } + } + // find the child that contains 'position' for (let i = 0, n = current.getChildCount(sourceFile); i < n; i++) { const child = current.getChildAt(i); - const start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile); + // all jsDocComment nodes were already visited + if (isJSDocNode(child)) { + continue; + } + const start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile, includeJsDocComment); if (start <= position) { const end = child.getEnd(); if (position < end || (position === end && child.kind === SyntaxKind.EndOfFileToken)) { @@ -282,6 +306,7 @@ namespace ts { } } } + return current; } } @@ -420,6 +445,10 @@ namespace ts { return false; } + if (token.kind === SyntaxKind.JsxText) { + return true; + } + //
Hello |
if (token.kind === SyntaxKind.LessThanToken && token.parent.kind === SyntaxKind.JsxText) { return true; @@ -430,7 +459,7 @@ namespace ts { return true; } - //
{ + //
{ // | // } < /div> if (token && token.kind === SyntaxKind.CloseBraceToken && token.parent.kind === SyntaxKind.JsxExpression) { @@ -515,11 +544,12 @@ namespace ts { } if (node) { - const jsDocComment = node.jsDocComment; - if (jsDocComment) { - for (const tag of jsDocComment.tags) { - if (tag.pos <= position && position <= tag.end) { - return tag; + if (node.jsDocComments) { + for (const jsDocComment of node.jsDocComments) { + for (const tag of jsDocComment.tags) { + if (tag.pos <= position && position <= tag.end) { + return tag; + } } } } diff --git a/tests/baselines/reference/acceptableAlias1.symbols b/tests/baselines/reference/acceptableAlias1.symbols index cffbc70290f..31679fb6a52 100644 --- a/tests/baselines/reference/acceptableAlias1.symbols +++ b/tests/baselines/reference/acceptableAlias1.symbols @@ -13,5 +13,5 @@ module M { import r = M.X; >r : Symbol(r, Decl(acceptableAlias1.ts, 4, 1)) >M : Symbol(M, Decl(acceptableAlias1.ts, 0, 0)) ->X : Symbol(r, Decl(acceptableAlias1.ts, 0, 10)) +>X : Symbol(M.X, Decl(acceptableAlias1.ts, 2, 5)) diff --git a/tests/baselines/reference/amdImportNotAsPrimaryExpression.symbols b/tests/baselines/reference/amdImportNotAsPrimaryExpression.symbols index ae67c0a3175..a04bd7077c1 100644 --- a/tests/baselines/reference/amdImportNotAsPrimaryExpression.symbols +++ b/tests/baselines/reference/amdImportNotAsPrimaryExpression.symbols @@ -5,7 +5,7 @@ import foo = require("./foo_0"); // None of the below should cause a runtime dependency on foo_0 import f = foo.M1; >f : Symbol(f, Decl(foo_1.ts, 0, 32)) ->foo : Symbol(foo, Decl(foo_0.ts, 0, 0)) +>foo : Symbol(foo, Decl(foo_1.ts, 0, 0)) >M1 : Symbol(foo.M1, Decl(foo_0.ts, 8, 1)) var i: f.I2; diff --git a/tests/baselines/reference/assignmentCompatability10.errors.txt b/tests/baselines/reference/assignmentCompatability10.errors.txt deleted file mode 100644 index 883bf1c277c..00000000000 --- a/tests/baselines/reference/assignmentCompatability10.errors.txt +++ /dev/null @@ -1,17 +0,0 @@ -tests/cases/compiler/assignmentCompatability10.ts(9,1): error TS2322: Type 'interfaceWithPublicAndOptional' is not assignable to type 'classWithPublicAndOptional'. - Property 'two' is optional in type 'interfaceWithPublicAndOptional' but required in type 'classWithPublicAndOptional'. - - -==== tests/cases/compiler/assignmentCompatability10.ts (1 errors) ==== - module __test1__ { - export interface interfaceWithPublicAndOptional { one: T; two?: U; }; var obj4: interfaceWithPublicAndOptional = { one: 1 };; - export var __val__obj4 = obj4; - } - module __test2__ { - export class classWithPublicAndOptional { constructor(public one: T, public two?: U) {} } var x4 = new classWithPublicAndOptional(1);; - export var __val__x4 = x4; - } - __test2__.__val__x4 = __test1__.__val__obj4 - ~~~~~~~~~~~~~~~~~~~ -!!! error TS2322: Type 'interfaceWithPublicAndOptional' is not assignable to type 'classWithPublicAndOptional'. -!!! error TS2322: Property 'two' is optional in type 'interfaceWithPublicAndOptional' but required in type 'classWithPublicAndOptional'. \ No newline at end of file diff --git a/tests/baselines/reference/assignmentCompatability10.symbols b/tests/baselines/reference/assignmentCompatability10.symbols new file mode 100644 index 00000000000..d4fdcd73241 --- /dev/null +++ b/tests/baselines/reference/assignmentCompatability10.symbols @@ -0,0 +1,46 @@ +=== tests/cases/compiler/assignmentCompatability10.ts === +module __test1__ { +>__test1__ : Symbol(__test1__, Decl(assignmentCompatability10.ts, 0, 0)) + + export interface interfaceWithPublicAndOptional { one: T; two?: U; }; var obj4: interfaceWithPublicAndOptional = { one: 1 };; +>interfaceWithPublicAndOptional : Symbol(interfaceWithPublicAndOptional, Decl(assignmentCompatability10.ts, 0, 18)) +>T : Symbol(T, Decl(assignmentCompatability10.ts, 1, 52)) +>U : Symbol(U, Decl(assignmentCompatability10.ts, 1, 54)) +>one : Symbol(interfaceWithPublicAndOptional.one, Decl(assignmentCompatability10.ts, 1, 58)) +>T : Symbol(T, Decl(assignmentCompatability10.ts, 1, 52)) +>two : Symbol(interfaceWithPublicAndOptional.two, Decl(assignmentCompatability10.ts, 1, 66)) +>U : Symbol(U, Decl(assignmentCompatability10.ts, 1, 54)) +>obj4 : Symbol(obj4, Decl(assignmentCompatability10.ts, 1, 83)) +>interfaceWithPublicAndOptional : Symbol(interfaceWithPublicAndOptional, Decl(assignmentCompatability10.ts, 0, 18)) +>one : Symbol(one, Decl(assignmentCompatability10.ts, 1, 139)) + + export var __val__obj4 = obj4; +>__val__obj4 : Symbol(__val__obj4, Decl(assignmentCompatability10.ts, 2, 14)) +>obj4 : Symbol(obj4, Decl(assignmentCompatability10.ts, 1, 83)) +} +module __test2__ { +>__test2__ : Symbol(__test2__, Decl(assignmentCompatability10.ts, 3, 1)) + + export class classWithPublicAndOptional { constructor(public one: T, public two?: U) {} } var x4 = new classWithPublicAndOptional(1);; +>classWithPublicAndOptional : Symbol(classWithPublicAndOptional, Decl(assignmentCompatability10.ts, 4, 18)) +>T : Symbol(T, Decl(assignmentCompatability10.ts, 5, 44)) +>U : Symbol(U, Decl(assignmentCompatability10.ts, 5, 46)) +>one : Symbol(classWithPublicAndOptional.one, Decl(assignmentCompatability10.ts, 5, 63)) +>T : Symbol(T, Decl(assignmentCompatability10.ts, 5, 44)) +>two : Symbol(classWithPublicAndOptional.two, Decl(assignmentCompatability10.ts, 5, 77)) +>U : Symbol(U, Decl(assignmentCompatability10.ts, 5, 46)) +>x4 : Symbol(x4, Decl(assignmentCompatability10.ts, 5, 104)) +>classWithPublicAndOptional : Symbol(classWithPublicAndOptional, Decl(assignmentCompatability10.ts, 4, 18)) + + export var __val__x4 = x4; +>__val__x4 : Symbol(__val__x4, Decl(assignmentCompatability10.ts, 6, 14)) +>x4 : Symbol(x4, Decl(assignmentCompatability10.ts, 5, 104)) +} +__test2__.__val__x4 = __test1__.__val__obj4 +>__test2__.__val__x4 : Symbol(__test2__.__val__x4, Decl(assignmentCompatability10.ts, 6, 14)) +>__test2__ : Symbol(__test2__, Decl(assignmentCompatability10.ts, 3, 1)) +>__val__x4 : Symbol(__test2__.__val__x4, Decl(assignmentCompatability10.ts, 6, 14)) +>__test1__.__val__obj4 : Symbol(__test1__.__val__obj4, Decl(assignmentCompatability10.ts, 2, 14)) +>__test1__ : Symbol(__test1__, Decl(assignmentCompatability10.ts, 0, 0)) +>__val__obj4 : Symbol(__test1__.__val__obj4, Decl(assignmentCompatability10.ts, 2, 14)) + diff --git a/tests/baselines/reference/assignmentCompatability10.types b/tests/baselines/reference/assignmentCompatability10.types new file mode 100644 index 00000000000..f4c2bba451d --- /dev/null +++ b/tests/baselines/reference/assignmentCompatability10.types @@ -0,0 +1,51 @@ +=== tests/cases/compiler/assignmentCompatability10.ts === +module __test1__ { +>__test1__ : typeof __test1__ + + export interface interfaceWithPublicAndOptional { one: T; two?: U; }; var obj4: interfaceWithPublicAndOptional = { one: 1 };; +>interfaceWithPublicAndOptional : interfaceWithPublicAndOptional +>T : T +>U : U +>one : T +>T : T +>two : U +>U : U +>obj4 : interfaceWithPublicAndOptional +>interfaceWithPublicAndOptional : interfaceWithPublicAndOptional +>{ one: 1 } : { one: number; } +>one : number +>1 : number + + export var __val__obj4 = obj4; +>__val__obj4 : interfaceWithPublicAndOptional +>obj4 : interfaceWithPublicAndOptional +} +module __test2__ { +>__test2__ : typeof __test2__ + + export class classWithPublicAndOptional { constructor(public one: T, public two?: U) {} } var x4 = new classWithPublicAndOptional(1);; +>classWithPublicAndOptional : classWithPublicAndOptional +>T : T +>U : U +>one : T +>T : T +>two : U +>U : U +>x4 : classWithPublicAndOptional +>new classWithPublicAndOptional(1) : classWithPublicAndOptional +>classWithPublicAndOptional : typeof classWithPublicAndOptional +>1 : number + + export var __val__x4 = x4; +>__val__x4 : classWithPublicAndOptional +>x4 : classWithPublicAndOptional +} +__test2__.__val__x4 = __test1__.__val__obj4 +>__test2__.__val__x4 = __test1__.__val__obj4 : __test1__.interfaceWithPublicAndOptional +>__test2__.__val__x4 : __test2__.classWithPublicAndOptional +>__test2__ : typeof __test2__ +>__val__x4 : __test2__.classWithPublicAndOptional +>__test1__.__val__obj4 : __test1__.interfaceWithPublicAndOptional +>__test1__ : typeof __test1__ +>__val__obj4 : __test1__.interfaceWithPublicAndOptional + diff --git a/tests/baselines/reference/chainedImportAlias.symbols b/tests/baselines/reference/chainedImportAlias.symbols index 0f374305aeb..d10e22af119 100644 --- a/tests/baselines/reference/chainedImportAlias.symbols +++ b/tests/baselines/reference/chainedImportAlias.symbols @@ -4,7 +4,7 @@ import x = require('./chainedImportAlias_file0'); import y = x; >y : Symbol(y, Decl(chainedImportAlias_file1.ts, 0, 49)) ->x : Symbol(x, Decl(chainedImportAlias_file0.ts, 0, 0)) +>x : Symbol(x, Decl(chainedImportAlias_file1.ts, 0, 0)) y.m.foo(); >y.m.foo : Symbol(x.m.foo, Decl(chainedImportAlias_file0.ts, 0, 17)) diff --git a/tests/baselines/reference/commonJSImportNotAsPrimaryExpression.symbols b/tests/baselines/reference/commonJSImportNotAsPrimaryExpression.symbols index ae67c0a3175..a04bd7077c1 100644 --- a/tests/baselines/reference/commonJSImportNotAsPrimaryExpression.symbols +++ b/tests/baselines/reference/commonJSImportNotAsPrimaryExpression.symbols @@ -5,7 +5,7 @@ import foo = require("./foo_0"); // None of the below should cause a runtime dependency on foo_0 import f = foo.M1; >f : Symbol(f, Decl(foo_1.ts, 0, 32)) ->foo : Symbol(foo, Decl(foo_0.ts, 0, 0)) +>foo : Symbol(foo, Decl(foo_1.ts, 0, 0)) >M1 : Symbol(foo.M1, Decl(foo_0.ts, 8, 1)) var i: f.I2; diff --git a/tests/baselines/reference/computedPropertyNamesContextualType7_ES5.js b/tests/baselines/reference/computedPropertyNamesContextualType7_ES5.js index 9caf5f2aebf..2eddbbed14c 100644 --- a/tests/baselines/reference/computedPropertyNamesContextualType7_ES5.js +++ b/tests/baselines/reference/computedPropertyNamesContextualType7_ES5.js @@ -1,25 +1,31 @@ //// [computedPropertyNamesContextualType7_ES5.ts] -interface I { - [s: number]: T; -} - -declare function foo(obj: I): T - -foo({ - p: "", - 0: () => { }, - ["hi" + "bye"]: true, - [0 + 1]: 0, - [+"hi"]: [0] +interface I { + [n: number]: T; +} +interface J { + [s: string]: T; +} + +declare function foo(obj: I): T; +declare function g(obj: J): T; + +foo({ + 0: () => { }, + ["hi" + "bye"]: true, + [0 + 1]: 0, + [+"hi"]: [0] }); +g({ p: "" }); + + //// [computedPropertyNamesContextualType7_ES5.js] foo((_a = { - p: "", 0: function () { } }, _a["hi" + "bye"] = true, _a[0 + 1] = 0, _a[+"hi"] = [0], _a)); +g({ p: "" }); var _a; diff --git a/tests/baselines/reference/computedPropertyNamesContextualType7_ES5.symbols b/tests/baselines/reference/computedPropertyNamesContextualType7_ES5.symbols index 22e4cf2b45b..d6889f9912d 100644 --- a/tests/baselines/reference/computedPropertyNamesContextualType7_ES5.symbols +++ b/tests/baselines/reference/computedPropertyNamesContextualType7_ES5.symbols @@ -3,27 +3,45 @@ interface I { >I : Symbol(I, Decl(computedPropertyNamesContextualType7_ES5.ts, 0, 0)) >T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 0, 12)) - [s: number]: T; ->s : Symbol(s, Decl(computedPropertyNamesContextualType7_ES5.ts, 1, 5)) + [n: number]: T; +>n : Symbol(n, Decl(computedPropertyNamesContextualType7_ES5.ts, 1, 5)) >T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 0, 12)) } +interface J { +>J : Symbol(J, Decl(computedPropertyNamesContextualType7_ES5.ts, 2, 1)) +>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 3, 12)) -declare function foo(obj: I): T ->foo : Symbol(foo, Decl(computedPropertyNamesContextualType7_ES5.ts, 2, 1)) ->T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 4, 21)) ->obj : Symbol(obj, Decl(computedPropertyNamesContextualType7_ES5.ts, 4, 24)) + [s: string]: T; +>s : Symbol(s, Decl(computedPropertyNamesContextualType7_ES5.ts, 4, 5)) +>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 3, 12)) +} + +declare function foo(obj: I): T; +>foo : Symbol(foo, Decl(computedPropertyNamesContextualType7_ES5.ts, 5, 1)) +>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 7, 21)) +>obj : Symbol(obj, Decl(computedPropertyNamesContextualType7_ES5.ts, 7, 24)) >I : Symbol(I, Decl(computedPropertyNamesContextualType7_ES5.ts, 0, 0)) ->T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 4, 21)) ->T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 4, 21)) +>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 7, 21)) +>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 7, 21)) + +declare function g(obj: J): T; +>g : Symbol(g, Decl(computedPropertyNamesContextualType7_ES5.ts, 7, 38)) +>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 8, 19)) +>obj : Symbol(obj, Decl(computedPropertyNamesContextualType7_ES5.ts, 8, 22)) +>J : Symbol(J, Decl(computedPropertyNamesContextualType7_ES5.ts, 2, 1)) +>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 8, 19)) +>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 8, 19)) foo({ ->foo : Symbol(foo, Decl(computedPropertyNamesContextualType7_ES5.ts, 2, 1)) - - p: "", ->p : Symbol(p, Decl(computedPropertyNamesContextualType7_ES5.ts, 6, 5)) +>foo : Symbol(foo, Decl(computedPropertyNamesContextualType7_ES5.ts, 5, 1)) 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0] }); + +g({ p: "" }); +>g : Symbol(g, Decl(computedPropertyNamesContextualType7_ES5.ts, 7, 38)) +>p : Symbol(p, Decl(computedPropertyNamesContextualType7_ES5.ts, 17, 3)) + diff --git a/tests/baselines/reference/computedPropertyNamesContextualType7_ES5.types b/tests/baselines/reference/computedPropertyNamesContextualType7_ES5.types index 083388ba975..64367864881 100644 --- a/tests/baselines/reference/computedPropertyNamesContextualType7_ES5.types +++ b/tests/baselines/reference/computedPropertyNamesContextualType7_ES5.types @@ -3,12 +3,20 @@ interface I { >I : I >T : T - [s: number]: T; ->s : number + [n: number]: T; +>n : number +>T : T +} +interface J { +>J : J +>T : T + + [s: string]: T; +>s : string >T : T } -declare function foo(obj: I): T +declare function foo(obj: I): T; >foo : (obj: I) => T >T : T >obj : I @@ -16,14 +24,18 @@ declare function foo(obj: I): T >T : T >T : T -foo({ ->foo({ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : (() => void) | number | number[] ->foo : (obj: I) => T ->{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: string | (() => void) | boolean | number | number[]; [x: number]: (() => void) | number | number[]; 0: () => void; p: string; } +declare function g(obj: J): T; +>g : (obj: J) => T +>T : T +>obj : J +>J : J +>T : T +>T : T - p: "", ->p : string ->"" : string +foo({ +>foo({ 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : (() => void) | number | number[] +>foo : (obj: I) => T +>{ 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: (() => void) | boolean | number | number[]; [x: number]: (() => void) | number | number[]; 0: () => void; } 0: () => { }, >() => { } : () => void @@ -47,3 +59,11 @@ foo({ >0 : number }); + +g({ p: "" }); +>g({ p: "" }) : string +>g : (obj: J) => T +>{ p: "" } : { p: string; } +>p : string +>"" : string + diff --git a/tests/baselines/reference/computedPropertyNamesContextualType7_ES6.js b/tests/baselines/reference/computedPropertyNamesContextualType7_ES6.js index 185ccd72ead..273c15018b6 100644 --- a/tests/baselines/reference/computedPropertyNamesContextualType7_ES6.js +++ b/tests/baselines/reference/computedPropertyNamesContextualType7_ES6.js @@ -1,23 +1,29 @@ //// [computedPropertyNamesContextualType7_ES6.ts] interface I { - [s: number]: T; + [n: number]: T; +} +interface J { + [s: string]: T; } -declare function foo(obj: I): T +declare function foo(obj: I): T; +declare function g(obj: J): T; foo({ - p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0] -}); +}); + +g({ p: "" }); + //// [computedPropertyNamesContextualType7_ES6.js] foo({ - p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0] }); +g({ p: "" }); diff --git a/tests/baselines/reference/computedPropertyNamesContextualType7_ES6.symbols b/tests/baselines/reference/computedPropertyNamesContextualType7_ES6.symbols index 7f33ebf58ad..d04c8f913bd 100644 --- a/tests/baselines/reference/computedPropertyNamesContextualType7_ES6.symbols +++ b/tests/baselines/reference/computedPropertyNamesContextualType7_ES6.symbols @@ -3,27 +3,45 @@ interface I { >I : Symbol(I, Decl(computedPropertyNamesContextualType7_ES6.ts, 0, 0)) >T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 0, 12)) - [s: number]: T; ->s : Symbol(s, Decl(computedPropertyNamesContextualType7_ES6.ts, 1, 5)) + [n: number]: T; +>n : Symbol(n, Decl(computedPropertyNamesContextualType7_ES6.ts, 1, 5)) >T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 0, 12)) } +interface J { +>J : Symbol(J, Decl(computedPropertyNamesContextualType7_ES6.ts, 2, 1)) +>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 3, 12)) -declare function foo(obj: I): T ->foo : Symbol(foo, Decl(computedPropertyNamesContextualType7_ES6.ts, 2, 1)) ->T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 4, 21)) ->obj : Symbol(obj, Decl(computedPropertyNamesContextualType7_ES6.ts, 4, 24)) + [s: string]: T; +>s : Symbol(s, Decl(computedPropertyNamesContextualType7_ES6.ts, 4, 5)) +>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 3, 12)) +} + +declare function foo(obj: I): T; +>foo : Symbol(foo, Decl(computedPropertyNamesContextualType7_ES6.ts, 5, 1)) +>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 7, 21)) +>obj : Symbol(obj, Decl(computedPropertyNamesContextualType7_ES6.ts, 7, 24)) >I : Symbol(I, Decl(computedPropertyNamesContextualType7_ES6.ts, 0, 0)) ->T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 4, 21)) ->T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 4, 21)) +>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 7, 21)) +>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 7, 21)) + +declare function g(obj: J): T; +>g : Symbol(g, Decl(computedPropertyNamesContextualType7_ES6.ts, 7, 38)) +>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 8, 19)) +>obj : Symbol(obj, Decl(computedPropertyNamesContextualType7_ES6.ts, 8, 22)) +>J : Symbol(J, Decl(computedPropertyNamesContextualType7_ES6.ts, 2, 1)) +>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 8, 19)) +>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 8, 19)) foo({ ->foo : Symbol(foo, Decl(computedPropertyNamesContextualType7_ES6.ts, 2, 1)) - - p: "", ->p : Symbol(p, Decl(computedPropertyNamesContextualType7_ES6.ts, 6, 5)) +>foo : Symbol(foo, Decl(computedPropertyNamesContextualType7_ES6.ts, 5, 1)) 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0] }); + +g({ p: "" }); +>g : Symbol(g, Decl(computedPropertyNamesContextualType7_ES6.ts, 7, 38)) +>p : Symbol(p, Decl(computedPropertyNamesContextualType7_ES6.ts, 17, 3)) + diff --git a/tests/baselines/reference/computedPropertyNamesContextualType7_ES6.types b/tests/baselines/reference/computedPropertyNamesContextualType7_ES6.types index bc6ae72fb4f..07aeda807b0 100644 --- a/tests/baselines/reference/computedPropertyNamesContextualType7_ES6.types +++ b/tests/baselines/reference/computedPropertyNamesContextualType7_ES6.types @@ -3,12 +3,20 @@ interface I { >I : I >T : T - [s: number]: T; ->s : number + [n: number]: T; +>n : number +>T : T +} +interface J { +>J : J +>T : T + + [s: string]: T; +>s : string >T : T } -declare function foo(obj: I): T +declare function foo(obj: I): T; >foo : (obj: I) => T >T : T >obj : I @@ -16,14 +24,18 @@ declare function foo(obj: I): T >T : T >T : T -foo({ ->foo({ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : (() => void) | number | number[] ->foo : (obj: I) => T ->{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: string | (() => void) | boolean | number | number[]; [x: number]: (() => void) | number | number[]; 0: () => void; p: string; } +declare function g(obj: J): T; +>g : (obj: J) => T +>T : T +>obj : J +>J : J +>T : T +>T : T - p: "", ->p : string ->"" : string +foo({ +>foo({ 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : (() => void) | number | number[] +>foo : (obj: I) => T +>{ 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: (() => void) | boolean | number | number[]; [x: number]: (() => void) | number | number[]; 0: () => void; } 0: () => { }, >() => { } : () => void @@ -47,3 +59,11 @@ foo({ >0 : number }); + +g({ p: "" }); +>g({ p: "" }) : string +>g : (obj: J) => T +>{ p: "" } : { p: string; } +>p : string +>"" : string + diff --git a/tests/baselines/reference/constLocalsInFunctionExpressions.js b/tests/baselines/reference/constLocalsInFunctionExpressions.js new file mode 100644 index 00000000000..473de3b1a6c --- /dev/null +++ b/tests/baselines/reference/constLocalsInFunctionExpressions.js @@ -0,0 +1,73 @@ +//// [constLocalsInFunctionExpressions.ts] +declare function getStringOrNumber(): string | number; + +function f1() { + const x = getStringOrNumber(); + if (typeof x === "string") { + const f = () => x.length; + } +} + +function f2() { + const x = getStringOrNumber(); + if (typeof x !== "string") { + return; + } + const f = () => x.length; +} + +function f3() { + const x = getStringOrNumber(); + if (typeof x === "string") { + const f = function() { return x.length; }; + } +} + +function f4() { + const x = getStringOrNumber(); + if (typeof x !== "string") { + return; + } + const f = function() { return x.length; }; +} + +function f5() { + const x = getStringOrNumber(); + if (typeof x === "string") { + const f = () => () => x.length; + } +} + +//// [constLocalsInFunctionExpressions.js] +function f1() { + var x = getStringOrNumber(); + if (typeof x === "string") { + var f = function () { return x.length; }; + } +} +function f2() { + var x = getStringOrNumber(); + if (typeof x !== "string") { + return; + } + var f = function () { return x.length; }; +} +function f3() { + var x = getStringOrNumber(); + if (typeof x === "string") { + var f = function () { return x.length; }; + } +} +function f4() { + var x = getStringOrNumber(); + if (typeof x !== "string") { + return; + } + var f = function () { return x.length; }; +} +function f5() { + var x = getStringOrNumber(); + if (typeof x === "string") { + var f = function () { return function () { return x.length; }; }; + } +} diff --git a/tests/baselines/reference/constLocalsInFunctionExpressions.symbols b/tests/baselines/reference/constLocalsInFunctionExpressions.symbols new file mode 100644 index 00000000000..d9465a118aa --- /dev/null +++ b/tests/baselines/reference/constLocalsInFunctionExpressions.symbols @@ -0,0 +1,95 @@ +=== tests/cases/conformance/controlFlow/constLocalsInFunctionExpressions.ts === +declare function getStringOrNumber(): string | number; +>getStringOrNumber : Symbol(getStringOrNumber, Decl(constLocalsInFunctionExpressions.ts, 0, 0)) + +function f1() { +>f1 : Symbol(f1, Decl(constLocalsInFunctionExpressions.ts, 0, 54)) + + const x = getStringOrNumber(); +>x : Symbol(x, Decl(constLocalsInFunctionExpressions.ts, 3, 9)) +>getStringOrNumber : Symbol(getStringOrNumber, Decl(constLocalsInFunctionExpressions.ts, 0, 0)) + + if (typeof x === "string") { +>x : Symbol(x, Decl(constLocalsInFunctionExpressions.ts, 3, 9)) + + const f = () => x.length; +>f : Symbol(f, Decl(constLocalsInFunctionExpressions.ts, 5, 13)) +>x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(constLocalsInFunctionExpressions.ts, 3, 9)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) + } +} + +function f2() { +>f2 : Symbol(f2, Decl(constLocalsInFunctionExpressions.ts, 7, 1)) + + const x = getStringOrNumber(); +>x : Symbol(x, Decl(constLocalsInFunctionExpressions.ts, 10, 9)) +>getStringOrNumber : Symbol(getStringOrNumber, Decl(constLocalsInFunctionExpressions.ts, 0, 0)) + + if (typeof x !== "string") { +>x : Symbol(x, Decl(constLocalsInFunctionExpressions.ts, 10, 9)) + + return; + } + const f = () => x.length; +>f : Symbol(f, Decl(constLocalsInFunctionExpressions.ts, 14, 9)) +>x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(constLocalsInFunctionExpressions.ts, 10, 9)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) +} + +function f3() { +>f3 : Symbol(f3, Decl(constLocalsInFunctionExpressions.ts, 15, 1)) + + const x = getStringOrNumber(); +>x : Symbol(x, Decl(constLocalsInFunctionExpressions.ts, 18, 9)) +>getStringOrNumber : Symbol(getStringOrNumber, Decl(constLocalsInFunctionExpressions.ts, 0, 0)) + + if (typeof x === "string") { +>x : Symbol(x, Decl(constLocalsInFunctionExpressions.ts, 18, 9)) + + const f = function() { return x.length; }; +>f : Symbol(f, Decl(constLocalsInFunctionExpressions.ts, 20, 13)) +>x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(constLocalsInFunctionExpressions.ts, 18, 9)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) + } +} + +function f4() { +>f4 : Symbol(f4, Decl(constLocalsInFunctionExpressions.ts, 22, 1)) + + const x = getStringOrNumber(); +>x : Symbol(x, Decl(constLocalsInFunctionExpressions.ts, 25, 9)) +>getStringOrNumber : Symbol(getStringOrNumber, Decl(constLocalsInFunctionExpressions.ts, 0, 0)) + + if (typeof x !== "string") { +>x : Symbol(x, Decl(constLocalsInFunctionExpressions.ts, 25, 9)) + + return; + } + const f = function() { return x.length; }; +>f : Symbol(f, Decl(constLocalsInFunctionExpressions.ts, 29, 9)) +>x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(constLocalsInFunctionExpressions.ts, 25, 9)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) +} + +function f5() { +>f5 : Symbol(f5, Decl(constLocalsInFunctionExpressions.ts, 30, 1)) + + const x = getStringOrNumber(); +>x : Symbol(x, Decl(constLocalsInFunctionExpressions.ts, 33, 9)) +>getStringOrNumber : Symbol(getStringOrNumber, Decl(constLocalsInFunctionExpressions.ts, 0, 0)) + + if (typeof x === "string") { +>x : Symbol(x, Decl(constLocalsInFunctionExpressions.ts, 33, 9)) + + const f = () => () => x.length; +>f : Symbol(f, Decl(constLocalsInFunctionExpressions.ts, 35, 13)) +>x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(constLocalsInFunctionExpressions.ts, 33, 9)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) + } +} diff --git a/tests/baselines/reference/constLocalsInFunctionExpressions.types b/tests/baselines/reference/constLocalsInFunctionExpressions.types new file mode 100644 index 00000000000..e9f0086f6b1 --- /dev/null +++ b/tests/baselines/reference/constLocalsInFunctionExpressions.types @@ -0,0 +1,121 @@ +=== tests/cases/conformance/controlFlow/constLocalsInFunctionExpressions.ts === +declare function getStringOrNumber(): string | number; +>getStringOrNumber : () => string | number + +function f1() { +>f1 : () => void + + const x = getStringOrNumber(); +>x : string | number +>getStringOrNumber() : string | number +>getStringOrNumber : () => string | number + + if (typeof x === "string") { +>typeof x === "string" : boolean +>typeof x : string +>x : string | number +>"string" : string + + const f = () => x.length; +>f : () => number +>() => x.length : () => number +>x.length : number +>x : string +>length : number + } +} + +function f2() { +>f2 : () => void + + const x = getStringOrNumber(); +>x : string | number +>getStringOrNumber() : string | number +>getStringOrNumber : () => string | number + + if (typeof x !== "string") { +>typeof x !== "string" : boolean +>typeof x : string +>x : string | number +>"string" : string + + return; + } + const f = () => x.length; +>f : () => number +>() => x.length : () => number +>x.length : number +>x : string +>length : number +} + +function f3() { +>f3 : () => void + + const x = getStringOrNumber(); +>x : string | number +>getStringOrNumber() : string | number +>getStringOrNumber : () => string | number + + if (typeof x === "string") { +>typeof x === "string" : boolean +>typeof x : string +>x : string | number +>"string" : string + + const f = function() { return x.length; }; +>f : () => number +>function() { return x.length; } : () => number +>x.length : number +>x : string +>length : number + } +} + +function f4() { +>f4 : () => void + + const x = getStringOrNumber(); +>x : string | number +>getStringOrNumber() : string | number +>getStringOrNumber : () => string | number + + if (typeof x !== "string") { +>typeof x !== "string" : boolean +>typeof x : string +>x : string | number +>"string" : string + + return; + } + const f = function() { return x.length; }; +>f : () => number +>function() { return x.length; } : () => number +>x.length : number +>x : string +>length : number +} + +function f5() { +>f5 : () => void + + const x = getStringOrNumber(); +>x : string | number +>getStringOrNumber() : string | number +>getStringOrNumber : () => string | number + + if (typeof x === "string") { +>typeof x === "string" : boolean +>typeof x : string +>x : string | number +>"string" : string + + const f = () => () => x.length; +>f : () => () => number +>() => () => x.length : () => () => number +>() => x.length : () => number +>x.length : number +>x : string +>length : number + } +} diff --git a/tests/baselines/reference/controlFlowIIFE.js b/tests/baselines/reference/controlFlowIIFE.js new file mode 100644 index 00000000000..5d295b57315 --- /dev/null +++ b/tests/baselines/reference/controlFlowIIFE.js @@ -0,0 +1,89 @@ +//// [controlFlowIIFE.ts] + +declare function getStringOrNumber(): string | number; + +function f1() { + let x = getStringOrNumber(); + if (typeof x === "string") { + let n = function() { + return x.length; + }(); + } +} + +function f2() { + let x = getStringOrNumber(); + if (typeof x === "string") { + let n = (function() { + return x.length; + })(); + } +} + +function f3() { + let x = getStringOrNumber(); + let y: number; + if (typeof x === "string") { + let n = (z => x.length + y + z)(y = 1); + } +} + +// Repros from #8381 + +let maybeNumber: number | undefined; +(function () { + maybeNumber = 1; +})(); +maybeNumber++; +if (maybeNumber !== undefined) { + maybeNumber++; +} + +let test: string | undefined; +if (!test) { + throw new Error('Test is not defined'); +} +(() => { + test.slice(1); // No error +})(); + +//// [controlFlowIIFE.js] +function f1() { + var x = getStringOrNumber(); + if (typeof x === "string") { + var n = function () { + return x.length; + }(); + } +} +function f2() { + var x = getStringOrNumber(); + if (typeof x === "string") { + var n = (function () { + return x.length; + })(); + } +} +function f3() { + var x = getStringOrNumber(); + var y; + if (typeof x === "string") { + var n = (function (z) { return x.length + y + z; })(y = 1); + } +} +// Repros from #8381 +var maybeNumber; +(function () { + maybeNumber = 1; +})(); +maybeNumber++; +if (maybeNumber !== undefined) { + maybeNumber++; +} +var test; +if (!test) { + throw new Error('Test is not defined'); +} +(function () { + test.slice(1); // No error +})(); diff --git a/tests/baselines/reference/controlFlowIIFE.symbols b/tests/baselines/reference/controlFlowIIFE.symbols new file mode 100644 index 00000000000..b1b2b741158 --- /dev/null +++ b/tests/baselines/reference/controlFlowIIFE.symbols @@ -0,0 +1,111 @@ +=== tests/cases/conformance/controlFlow/controlFlowIIFE.ts === + +declare function getStringOrNumber(): string | number; +>getStringOrNumber : Symbol(getStringOrNumber, Decl(controlFlowIIFE.ts, 0, 0)) + +function f1() { +>f1 : Symbol(f1, Decl(controlFlowIIFE.ts, 1, 54)) + + let x = getStringOrNumber(); +>x : Symbol(x, Decl(controlFlowIIFE.ts, 4, 7)) +>getStringOrNumber : Symbol(getStringOrNumber, Decl(controlFlowIIFE.ts, 0, 0)) + + if (typeof x === "string") { +>x : Symbol(x, Decl(controlFlowIIFE.ts, 4, 7)) + + let n = function() { +>n : Symbol(n, Decl(controlFlowIIFE.ts, 6, 11)) + + return x.length; +>x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowIIFE.ts, 4, 7)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) + + }(); + } +} + +function f2() { +>f2 : Symbol(f2, Decl(controlFlowIIFE.ts, 10, 1)) + + let x = getStringOrNumber(); +>x : Symbol(x, Decl(controlFlowIIFE.ts, 13, 7)) +>getStringOrNumber : Symbol(getStringOrNumber, Decl(controlFlowIIFE.ts, 0, 0)) + + if (typeof x === "string") { +>x : Symbol(x, Decl(controlFlowIIFE.ts, 13, 7)) + + let n = (function() { +>n : Symbol(n, Decl(controlFlowIIFE.ts, 15, 11)) + + return x.length; +>x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowIIFE.ts, 13, 7)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) + + })(); + } +} + +function f3() { +>f3 : Symbol(f3, Decl(controlFlowIIFE.ts, 19, 1)) + + let x = getStringOrNumber(); +>x : Symbol(x, Decl(controlFlowIIFE.ts, 22, 7)) +>getStringOrNumber : Symbol(getStringOrNumber, Decl(controlFlowIIFE.ts, 0, 0)) + + let y: number; +>y : Symbol(y, Decl(controlFlowIIFE.ts, 23, 7)) + + if (typeof x === "string") { +>x : Symbol(x, Decl(controlFlowIIFE.ts, 22, 7)) + + let n = (z => x.length + y + z)(y = 1); +>n : Symbol(n, Decl(controlFlowIIFE.ts, 25, 11)) +>z : Symbol(z, Decl(controlFlowIIFE.ts, 25, 17)) +>x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowIIFE.ts, 22, 7)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>y : Symbol(y, Decl(controlFlowIIFE.ts, 23, 7)) +>z : Symbol(z, Decl(controlFlowIIFE.ts, 25, 17)) +>y : Symbol(y, Decl(controlFlowIIFE.ts, 23, 7)) + } +} + +// Repros from #8381 + +let maybeNumber: number | undefined; +>maybeNumber : Symbol(maybeNumber, Decl(controlFlowIIFE.ts, 31, 3)) + +(function () { + maybeNumber = 1; +>maybeNumber : Symbol(maybeNumber, Decl(controlFlowIIFE.ts, 31, 3)) + +})(); +maybeNumber++; +>maybeNumber : Symbol(maybeNumber, Decl(controlFlowIIFE.ts, 31, 3)) + +if (maybeNumber !== undefined) { +>maybeNumber : Symbol(maybeNumber, Decl(controlFlowIIFE.ts, 31, 3)) +>undefined : Symbol(undefined) + + maybeNumber++; +>maybeNumber : Symbol(maybeNumber, Decl(controlFlowIIFE.ts, 31, 3)) +} + +let test: string | undefined; +>test : Symbol(test, Decl(controlFlowIIFE.ts, 40, 3)) + +if (!test) { +>test : Symbol(test, Decl(controlFlowIIFE.ts, 40, 3)) + + throw new Error('Test is not defined'); +>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +} +(() => { + test.slice(1); // No error +>test.slice : Symbol(String.slice, Decl(lib.d.ts, --, --)) +>test : Symbol(test, Decl(controlFlowIIFE.ts, 40, 3)) +>slice : Symbol(String.slice, Decl(lib.d.ts, --, --)) + +})(); diff --git a/tests/baselines/reference/controlFlowIIFE.types b/tests/baselines/reference/controlFlowIIFE.types new file mode 100644 index 00000000000..c041de04bc7 --- /dev/null +++ b/tests/baselines/reference/controlFlowIIFE.types @@ -0,0 +1,153 @@ +=== tests/cases/conformance/controlFlow/controlFlowIIFE.ts === + +declare function getStringOrNumber(): string | number; +>getStringOrNumber : () => string | number + +function f1() { +>f1 : () => void + + let x = getStringOrNumber(); +>x : string | number +>getStringOrNumber() : string | number +>getStringOrNumber : () => string | number + + if (typeof x === "string") { +>typeof x === "string" : boolean +>typeof x : string +>x : string | number +>"string" : string + + let n = function() { +>n : number +>function() { return x.length; }() : number +>function() { return x.length; } : () => number + + return x.length; +>x.length : number +>x : string +>length : number + + }(); + } +} + +function f2() { +>f2 : () => void + + let x = getStringOrNumber(); +>x : string | number +>getStringOrNumber() : string | number +>getStringOrNumber : () => string | number + + if (typeof x === "string") { +>typeof x === "string" : boolean +>typeof x : string +>x : string | number +>"string" : string + + let n = (function() { +>n : number +>(function() { return x.length; })() : number +>(function() { return x.length; }) : () => number +>function() { return x.length; } : () => number + + return x.length; +>x.length : number +>x : string +>length : number + + })(); + } +} + +function f3() { +>f3 : () => void + + let x = getStringOrNumber(); +>x : string | number +>getStringOrNumber() : string | number +>getStringOrNumber : () => string | number + + let y: number; +>y : number + + if (typeof x === "string") { +>typeof x === "string" : boolean +>typeof x : string +>x : string | number +>"string" : string + + let n = (z => x.length + y + z)(y = 1); +>n : number +>(z => x.length + y + z)(y = 1) : number +>(z => x.length + y + z) : (z: number) => number +>z => x.length + y + z : (z: number) => number +>z : number +>x.length + y + z : number +>x.length + y : number +>x.length : number +>x : string +>length : number +>y : number +>z : number +>y = 1 : number +>y : number +>1 : number + } +} + +// Repros from #8381 + +let maybeNumber: number | undefined; +>maybeNumber : number | undefined + +(function () { +>(function () { maybeNumber = 1;})() : void +>(function () { maybeNumber = 1;}) : () => void +>function () { maybeNumber = 1;} : () => void + + maybeNumber = 1; +>maybeNumber = 1 : number +>maybeNumber : number | undefined +>1 : number + +})(); +maybeNumber++; +>maybeNumber++ : number +>maybeNumber : number + +if (maybeNumber !== undefined) { +>maybeNumber !== undefined : boolean +>maybeNumber : number +>undefined : undefined + + maybeNumber++; +>maybeNumber++ : number +>maybeNumber : number +} + +let test: string | undefined; +>test : string | undefined + +if (!test) { +>!test : boolean +>test : string | undefined + + throw new Error('Test is not defined'); +>new Error('Test is not defined') : Error +>Error : ErrorConstructor +>'Test is not defined' : string +} +(() => { +>(() => { test.slice(1); // No error})() : void +>(() => { test.slice(1); // No error}) : () => void +>() => { test.slice(1); // No error} : () => void + + test.slice(1); // No error +>test.slice(1) : string +>test.slice : (start?: number | undefined, end?: number | undefined) => string +>test : string +>slice : (start?: number | undefined, end?: number | undefined) => string +>1 : number + +})(); diff --git a/tests/baselines/reference/declFileForExportedImport.symbols b/tests/baselines/reference/declFileForExportedImport.symbols index fe14836199c..c9c36796826 100644 --- a/tests/baselines/reference/declFileForExportedImport.symbols +++ b/tests/baselines/reference/declFileForExportedImport.symbols @@ -11,7 +11,7 @@ var y = a.x; export import b = a; >b : Symbol(b, Decl(declFileForExportedImport_1.ts, 2, 12)) ->a : Symbol(a, Decl(declFileForExportedImport_0.ts, 0, 0)) +>a : Symbol(a, Decl(declFileForExportedImport_1.ts, 0, 0)) var z = b.x; >z : Symbol(z, Decl(declFileForExportedImport_1.ts, 5, 3)) diff --git a/tests/baselines/reference/declFileImportChainInExportAssignment.symbols b/tests/baselines/reference/declFileImportChainInExportAssignment.symbols index 12e05bed75a..a47db44a02e 100644 --- a/tests/baselines/reference/declFileImportChainInExportAssignment.symbols +++ b/tests/baselines/reference/declFileImportChainInExportAssignment.symbols @@ -17,7 +17,7 @@ import a = m.c; import b = a; >b : Symbol(b, Decl(declFileImportChainInExportAssignment.ts, 6, 15)) ->a : Symbol(a, Decl(declFileImportChainInExportAssignment.ts, 0, 10)) +>a : Symbol(a, Decl(declFileImportChainInExportAssignment.ts, 5, 1)) export = b; >b : Symbol(b, Decl(declFileImportChainInExportAssignment.ts, 6, 15)) diff --git a/tests/baselines/reference/declarationEmit_nameConflicts.symbols b/tests/baselines/reference/declarationEmit_nameConflicts.symbols index 1c5bb35b756..43657e85baf 100644 --- a/tests/baselines/reference/declarationEmit_nameConflicts.symbols +++ b/tests/baselines/reference/declarationEmit_nameConflicts.symbols @@ -37,7 +37,7 @@ export module M { export import d = im; >d : Symbol(d, Decl(declarationEmit_nameConflicts_0.ts, 11, 24)) ->im : Symbol(d, Decl(declarationEmit_nameConflicts_1.ts, 0, 0)) +>im : Symbol(im, Decl(declarationEmit_nameConflicts_0.ts, 0, 0)) } export module M.P { diff --git a/tests/baselines/reference/decoratorOnClass5.es6.js b/tests/baselines/reference/decoratorOnClass5.es6.js index 58c5f0d4f29..e34740d6517 100644 --- a/tests/baselines/reference/decoratorOnClass5.es6.js +++ b/tests/baselines/reference/decoratorOnClass5.es6.js @@ -16,10 +16,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; -let C_1; -let C = C_1 = class C { +let C_1 = class C { static x() { return C_1.y; } }; +let C = C_1; C.y = 1; C = C_1 = __decorate([ dec diff --git a/tests/baselines/reference/decoratorOnClass6.es6.js b/tests/baselines/reference/decoratorOnClass6.es6.js index d8330a57ef6..4e4197bb601 100644 --- a/tests/baselines/reference/decoratorOnClass6.es6.js +++ b/tests/baselines/reference/decoratorOnClass6.es6.js @@ -1,12 +1,12 @@ //// [decoratorOnClass6.es6.ts] -declare function dec(target: T): T; - -@dec -export class C { - static x() { return C.y; } - static y = 1; -} - +declare function dec(target: T): T; + +@dec +export class C { + static x() { return C.y; } + static y = 1; +} + let c = new C(); //// [decoratorOnClass6.es6.js] @@ -16,10 +16,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; -let C_1; -let C = C_1 = class C { +let C_1 = class C { static x() { return C_1.y; } }; +let C = C_1; C.y = 1; C = C_1 = __decorate([ dec diff --git a/tests/baselines/reference/decoratorOnClass7.es6.js b/tests/baselines/reference/decoratorOnClass7.es6.js index 3ffd0f1574f..7f111ea4abf 100644 --- a/tests/baselines/reference/decoratorOnClass7.es6.js +++ b/tests/baselines/reference/decoratorOnClass7.es6.js @@ -16,10 +16,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; -let C_1; -let C = C_1 = class C { +let C_1 = class C { static x() { return C_1.y; } }; +let C = C_1; C.y = 1; C = C_1 = __decorate([ dec diff --git a/tests/baselines/reference/dependencyViaImportAlias.symbols b/tests/baselines/reference/dependencyViaImportAlias.symbols index 8855b8d6451..04c0a9a1a13 100644 --- a/tests/baselines/reference/dependencyViaImportAlias.symbols +++ b/tests/baselines/reference/dependencyViaImportAlias.symbols @@ -4,7 +4,7 @@ import a = require('A'); import A = a.A; >A : Symbol(A, Decl(B.ts, 0, 24)) ->a : Symbol(a, Decl(A.ts, 0, 0)) +>a : Symbol(a, Decl(B.ts, 0, 0)) >A : Symbol(a.A, Decl(A.ts, 0, 0)) export = A; diff --git a/tests/baselines/reference/es6ImportNamedImportInIndirectExportAssignment.symbols b/tests/baselines/reference/es6ImportNamedImportInIndirectExportAssignment.symbols index 24eab96f54b..77b93c3ef00 100644 --- a/tests/baselines/reference/es6ImportNamedImportInIndirectExportAssignment.symbols +++ b/tests/baselines/reference/es6ImportNamedImportInIndirectExportAssignment.symbols @@ -14,7 +14,7 @@ import { a } from "./es6ImportNamedImportInIndirectExportAssignment_0"; import x = a; >x : Symbol(x, Decl(es6ImportNamedImportInIndirectExportAssignment_1.ts, 0, 71)) ->a : Symbol(a, Decl(es6ImportNamedImportInIndirectExportAssignment_0.ts, 0, 0)) +>a : Symbol(a, Decl(es6ImportNamedImportInIndirectExportAssignment_1.ts, 0, 8)) export = x; >x : Symbol(x, Decl(es6ImportNamedImportInIndirectExportAssignment_1.ts, 0, 71)) diff --git a/tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.symbols b/tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.symbols index 02e5e6cfc5a..d4b995af6b2 100644 --- a/tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.symbols +++ b/tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.symbols @@ -5,7 +5,7 @@ declare module 'timezonecomplete' { export import TimeUnit = basics.TimeUnit; >TimeUnit : Symbol(TimeUnit, Decl(externalModuleReferenceDoubleUnderscore1.ts, 1, 57)) ->basics : Symbol(basics, Decl(externalModuleReferenceDoubleUnderscore1.ts, 3, 1)) +>basics : Symbol(basics, Decl(externalModuleReferenceDoubleUnderscore1.ts, 0, 35)) >TimeUnit : Symbol(basics.TimeUnit, Decl(externalModuleReferenceDoubleUnderscore1.ts, 5, 44)) } diff --git a/tests/baselines/reference/importAliasAnExternalModuleInsideAnInternalModule.symbols b/tests/baselines/reference/importAliasAnExternalModuleInsideAnInternalModule.symbols index ffaca4a0ec5..ecc81c727e1 100644 --- a/tests/baselines/reference/importAliasAnExternalModuleInsideAnInternalModule.symbols +++ b/tests/baselines/reference/importAliasAnExternalModuleInsideAnInternalModule.symbols @@ -8,7 +8,7 @@ module m_private { //import r2 = require('m'); // would be error export import C = r; // no error >C : Symbol(C, Decl(importAliasAnExternalModuleInsideAnInternalModule_file1.ts, 1, 18)) ->r : Symbol(C, Decl(importAliasAnExternalModuleInsideAnInternalModule_file0.ts, 0, 0)) +>r : Symbol(r, Decl(importAliasAnExternalModuleInsideAnInternalModule_file1.ts, 0, 0)) C.m.foo(); >C.m.foo : Symbol(C.m.foo, Decl(importAliasAnExternalModuleInsideAnInternalModule_file0.ts, 0, 17)) diff --git a/tests/baselines/reference/import_reference-exported-alias.symbols b/tests/baselines/reference/import_reference-exported-alias.symbols index 5a7e8b8c5c7..10ccb7a9256 100644 --- a/tests/baselines/reference/import_reference-exported-alias.symbols +++ b/tests/baselines/reference/import_reference-exported-alias.symbols @@ -4,12 +4,12 @@ import appJs = require("file1"); import Services = appJs.Services; >Services : Symbol(Services, Decl(file2.ts, 0, 32)) ->appJs : Symbol(appJs, Decl(file1.ts, 0, 0)) +>appJs : Symbol(appJs, Decl(file2.ts, 0, 0)) >Services : Symbol(appJs.Services, Decl(file1.ts, 0, 12)) import UserServices = Services.UserServices; >UserServices : Symbol(UserServices, Decl(file2.ts, 1, 33)) ->Services : Symbol(appJs.Services, Decl(file1.ts, 0, 12)) +>Services : Symbol(Services, Decl(file2.ts, 0, 32)) >UserServices : Symbol(Services.UserServices, Decl(file1.ts, 1, 28)) var x = new UserServices().getUserName(); diff --git a/tests/baselines/reference/import_reference-to-type-alias.symbols b/tests/baselines/reference/import_reference-to-type-alias.symbols index 6d096c1cba3..996cf05be71 100644 --- a/tests/baselines/reference/import_reference-to-type-alias.symbols +++ b/tests/baselines/reference/import_reference-to-type-alias.symbols @@ -4,7 +4,7 @@ import appJs = require("file1"); import Services = appJs.App.Services; >Services : Symbol(Services, Decl(file2.ts, 0, 32)) ->appJs : Symbol(appJs, Decl(file1.ts, 0, 0)) +>appJs : Symbol(appJs, Decl(file2.ts, 0, 0)) >App : Symbol(appJs.App, Decl(file1.ts, 0, 0)) >Services : Symbol(Services, Decl(file1.ts, 0, 19)) diff --git a/tests/baselines/reference/importedAliasesInTypePositions.symbols b/tests/baselines/reference/importedAliasesInTypePositions.symbols index 1d28900c22f..1ad3c4254f8 100644 --- a/tests/baselines/reference/importedAliasesInTypePositions.symbols +++ b/tests/baselines/reference/importedAliasesInTypePositions.symbols @@ -4,7 +4,7 @@ import RT_ALIAS = require("file1"); import ReferredTo = RT_ALIAS.elaborate.nested.mod.name.ReferredTo; >ReferredTo : Symbol(ReferredTo, Decl(file2.ts, 0, 35)) ->RT_ALIAS : Symbol(RT_ALIAS, Decl(file1.ts, 0, 0)) +>RT_ALIAS : Symbol(RT_ALIAS, Decl(file2.ts, 0, 0)) >elaborate : Symbol(RT_ALIAS.elaborate, Decl(file1.ts, 0, 0)) >nested : Symbol(RT_ALIAS.elaborate.nested, Decl(file1.ts, 0, 24)) >mod : Symbol(RT_ALIAS.elaborate.nested.mod, Decl(file1.ts, 0, 31)) diff --git a/tests/baselines/reference/indexSignaturesInferentialTyping.js b/tests/baselines/reference/indexSignaturesInferentialTyping.js index 53636be716c..b5255861a10 100644 --- a/tests/baselines/reference/indexSignaturesInferentialTyping.js +++ b/tests/baselines/reference/indexSignaturesInferentialTyping.js @@ -3,15 +3,13 @@ function foo(items: { [index: number]: T }): T { return undefined; } function bar(items: { [index: string]: T }): T { return undefined; } var x1 = foo({ 0: 0, 1: 1 }); // type should be number -var x2 = foo({ zero: 0, one: 1 }); -var x3 = bar({ 0: 0, 1: 1 }); -var x4 = bar({ zero: 0, one: 1 }); // type should be number +var x2 = bar({ 0: 0, 1: 1 }); +var x3 = bar({ zero: 0, one: 1 }); // type should be number //// [indexSignaturesInferentialTyping.js] function foo(items) { return undefined; } function bar(items) { return undefined; } var x1 = foo({ 0: 0, 1: 1 }); // type should be number -var x2 = foo({ zero: 0, one: 1 }); -var x3 = bar({ 0: 0, 1: 1 }); -var x4 = bar({ zero: 0, one: 1 }); // type should be number +var x2 = bar({ 0: 0, 1: 1 }); +var x3 = bar({ zero: 0, one: 1 }); // type should be number diff --git a/tests/baselines/reference/indexSignaturesInferentialTyping.symbols b/tests/baselines/reference/indexSignaturesInferentialTyping.symbols index a34aa7a5cd1..754fe0390a4 100644 --- a/tests/baselines/reference/indexSignaturesInferentialTyping.symbols +++ b/tests/baselines/reference/indexSignaturesInferentialTyping.symbols @@ -21,19 +21,13 @@ var x1 = foo({ 0: 0, 1: 1 }); // type should be number >x1 : Symbol(x1, Decl(indexSignaturesInferentialTyping.ts, 3, 3)) >foo : Symbol(foo, Decl(indexSignaturesInferentialTyping.ts, 0, 0)) -var x2 = foo({ zero: 0, one: 1 }); +var x2 = bar({ 0: 0, 1: 1 }); >x2 : Symbol(x2, Decl(indexSignaturesInferentialTyping.ts, 4, 3)) ->foo : Symbol(foo, Decl(indexSignaturesInferentialTyping.ts, 0, 0)) ->zero : Symbol(zero, Decl(indexSignaturesInferentialTyping.ts, 4, 14)) ->one : Symbol(one, Decl(indexSignaturesInferentialTyping.ts, 4, 23)) +>bar : Symbol(bar, Decl(indexSignaturesInferentialTyping.ts, 0, 71)) -var x3 = bar({ 0: 0, 1: 1 }); +var x3 = bar({ zero: 0, one: 1 }); // type should be number >x3 : Symbol(x3, Decl(indexSignaturesInferentialTyping.ts, 5, 3)) >bar : Symbol(bar, Decl(indexSignaturesInferentialTyping.ts, 0, 71)) - -var x4 = bar({ zero: 0, one: 1 }); // type should be number ->x4 : Symbol(x4, Decl(indexSignaturesInferentialTyping.ts, 6, 3)) ->bar : Symbol(bar, Decl(indexSignaturesInferentialTyping.ts, 0, 71)) ->zero : Symbol(zero, Decl(indexSignaturesInferentialTyping.ts, 6, 14)) ->one : Symbol(one, Decl(indexSignaturesInferentialTyping.ts, 6, 23)) +>zero : Symbol(zero, Decl(indexSignaturesInferentialTyping.ts, 5, 14)) +>one : Symbol(one, Decl(indexSignaturesInferentialTyping.ts, 5, 23)) diff --git a/tests/baselines/reference/indexSignaturesInferentialTyping.types b/tests/baselines/reference/indexSignaturesInferentialTyping.types index 8545a7d4ca9..47c7aa21388 100644 --- a/tests/baselines/reference/indexSignaturesInferentialTyping.types +++ b/tests/baselines/reference/indexSignaturesInferentialTyping.types @@ -25,26 +25,16 @@ var x1 = foo({ 0: 0, 1: 1 }); // type should be number >0 : number >1 : number -var x2 = foo({ zero: 0, one: 1 }); ->x2 : {} ->foo({ zero: 0, one: 1 }) : {} ->foo : (items: { [index: number]: T; }) => T ->{ zero: 0, one: 1 } : { zero: number; one: number; } ->zero : number ->0 : number ->one : number ->1 : number - -var x3 = bar({ 0: 0, 1: 1 }); ->x3 : number +var x2 = bar({ 0: 0, 1: 1 }); +>x2 : number >bar({ 0: 0, 1: 1 }) : number >bar : (items: { [index: string]: T; }) => T >{ 0: 0, 1: 1 } : { 0: number; 1: number; } >0 : number >1 : number -var x4 = bar({ zero: 0, one: 1 }); // type should be number ->x4 : number +var x3 = bar({ zero: 0, one: 1 }); // type should be number +>x3 : number >bar({ zero: 0, one: 1 }) : number >bar : (items: { [index: string]: T; }) => T >{ zero: 0, one: 1 } : { zero: number; one: number; } diff --git a/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations.errors.txt b/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations.errors.txt index bb01b2fe125..ec0f330f1a3 100644 --- a/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations.errors.txt +++ b/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations.errors.txt @@ -5,9 +5,8 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerCo tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(36,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(50,5): error TS2412: Property '2.0' of type 'number' is not assignable to numeric index type 'string'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(68,5): error TS2412: Property '2.0' of type 'number' is not assignable to numeric index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(78,5): error TS2322: Type '{ 1.0: string; 2.0: number; a: string; b: number; c: () => void; "d": string; "e": number; "3.0": string; "4.0": number; f: any; X: string; foo(): string; }' is not assignable to type '{ [x: number]: string; }'. - Property '2.0' is incompatible with index signature. - Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(79,5): error TS2322: Type '{ 1.0: string; 2.0: number; a: string; b: number; c: () => void; "d": string; "e": number; "3.0": string; "4.0": number; f: any; X: string; foo(): string; }' is not assignable to type '{ [x: number]: string; }'. + Object literal may only specify known properties, and 'a' does not exist in type '{ [x: number]: string; }'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(88,9): error TS2304: Cannot find name 'Myn'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(90,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(93,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. @@ -106,11 +105,10 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerCo // error var b: { [x: number]: string; } = { - ~ -!!! error TS2322: Type '{ 1.0: string; 2.0: number; a: string; b: number; c: () => void; "d": string; "e": number; "3.0": string; "4.0": number; f: any; X: string; foo(): string; }' is not assignable to type '{ [x: number]: string; }'. -!!! error TS2322: Property '2.0' is incompatible with index signature. -!!! error TS2322: Type 'number' is not assignable to type 'string'. a: '', + ~~~~~ +!!! error TS2322: Type '{ 1.0: string; 2.0: number; a: string; b: number; c: () => void; "d": string; "e": number; "3.0": string; "4.0": number; f: any; X: string; foo(): string; }' is not assignable to type '{ [x: number]: string; }'. +!!! error TS2322: Object literal may only specify known properties, and 'a' does not exist in type '{ [x: number]: string; }'. b: 1, c: () => { }, "d": '', diff --git a/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations2.errors.txt b/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations2.errors.txt index 332b356c732..e6d22ff0712 100644 --- a/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations2.errors.txt +++ b/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations2.errors.txt @@ -1,9 +1,8 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(16,5): error TS2412: Property '3.0' of type 'number' is not assignable to numeric index type 'A'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(25,5): error TS2412: Property '3.0' of type 'number' is not assignable to numeric index type 'A'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(34,5): error TS2412: Property '3.0' of type 'number' is not assignable to numeric index type 'A'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(39,5): error TS2322: Type '{ 1.0: A; 2.0: B; 3.0: number; "2.5": B; "4.0": string; }' is not assignable to type '{ [x: number]: A; }'. - Property '3.0' is incompatible with index signature. - Type 'number' is not assignable to type 'A'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(44,5): error TS2322: Type '{ 1.0: A; 2.0: B; 3.0: number; "2.5": B; "4.0": string; }' is not assignable to type '{ [x: number]: A; }'. + Object literal may only specify known properties, and '"4.0"' does not exist in type '{ [x: number]: A; }'. ==== tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts (4 errors) ==== @@ -52,13 +51,12 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerCo // error var b: { [x: number]: A } = { - ~ -!!! error TS2322: Type '{ 1.0: A; 2.0: B; 3.0: number; "2.5": B; "4.0": string; }' is not assignable to type '{ [x: number]: A; }'. -!!! error TS2322: Property '3.0' is incompatible with index signature. -!!! error TS2322: Type 'number' is not assignable to type 'A'. 1.0: new A(), 2.0: new B(), "2.5": new B(), 3.0: 1, "4.0": '' + ~~~~~~~~~ +!!! error TS2322: Type '{ 1.0: A; 2.0: B; 3.0: number; "2.5": B; "4.0": string; }' is not assignable to type '{ [x: number]: A; }'. +!!! error TS2322: Object literal may only specify known properties, and '"4.0"' does not exist in type '{ [x: number]: A; }'. } \ No newline at end of file diff --git a/tests/baselines/reference/numericIndexerConstraint4.js b/tests/baselines/reference/numericIndexerConstraint4.js index 245569cb62e..a9eace23833 100644 --- a/tests/baselines/reference/numericIndexerConstraint4.js +++ b/tests/baselines/reference/numericIndexerConstraint4.js @@ -9,7 +9,8 @@ class B extends A { var x: { [idx: number]: A; -} = { data: new B() } +} = { 0: new B() } + //// [numericIndexerConstraint4.js] var __extends = (this && this.__extends) || function (d, b) { @@ -29,4 +30,4 @@ var B = (function (_super) { } return B; }(A)); -var x = { data: new B() }; +var x = { 0: new B() }; diff --git a/tests/baselines/reference/numericIndexerConstraint4.symbols b/tests/baselines/reference/numericIndexerConstraint4.symbols index 46301a6787b..8edf7d0f6fe 100644 --- a/tests/baselines/reference/numericIndexerConstraint4.symbols +++ b/tests/baselines/reference/numericIndexerConstraint4.symbols @@ -21,7 +21,6 @@ var x: { >idx : Symbol(idx, Decl(numericIndexerConstraint4.ts, 9, 5)) >A : Symbol(A, Decl(numericIndexerConstraint4.ts, 0, 0)) -} = { data: new B() } ->data : Symbol(data, Decl(numericIndexerConstraint4.ts, 10, 5)) +} = { 0: new B() } >B : Symbol(B, Decl(numericIndexerConstraint4.ts, 2, 1)) diff --git a/tests/baselines/reference/numericIndexerConstraint4.types b/tests/baselines/reference/numericIndexerConstraint4.types index c8af4d54a9a..c8cda0e6be2 100644 --- a/tests/baselines/reference/numericIndexerConstraint4.types +++ b/tests/baselines/reference/numericIndexerConstraint4.types @@ -21,9 +21,8 @@ var x: { >idx : number >A : A -} = { data: new B() } ->{ data: new B() } : { data: B; } ->data : B +} = { 0: new B() } +>{ 0: new B() } : { 0: B; } >new B() : B >B : typeof B diff --git a/tests/baselines/reference/objectLitIndexerContextualType.errors.txt b/tests/baselines/reference/objectLitIndexerContextualType.errors.txt index ca65ee5a5be..5012dc11728 100644 --- a/tests/baselines/reference/objectLitIndexerContextualType.errors.txt +++ b/tests/baselines/reference/objectLitIndexerContextualType.errors.txt @@ -2,11 +2,13 @@ tests/cases/compiler/objectLitIndexerContextualType.ts(12,13): error TS2362: The tests/cases/compiler/objectLitIndexerContextualType.ts(12,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/compiler/objectLitIndexerContextualType.ts(15,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/compiler/objectLitIndexerContextualType.ts(15,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/compiler/objectLitIndexerContextualType.ts(18,5): error TS2322: Type '{ s: (t: any) => number; }' is not assignable to type 'J'. + Object literal may only specify known properties, and 's' does not exist in type 'J'. tests/cases/compiler/objectLitIndexerContextualType.ts(21,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/compiler/objectLitIndexerContextualType.ts(21,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -==== tests/cases/compiler/objectLitIndexerContextualType.ts (6 errors) ==== +==== tests/cases/compiler/objectLitIndexerContextualType.ts (7 errors) ==== interface I { [s: string]: (s: string) => number; } @@ -32,7 +34,10 @@ tests/cases/compiler/objectLitIndexerContextualType.ts(21,17): error TS2363: The !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. }; y = { - s: t => t * t, // Should not error + s: t => t * t, // Should error + ~~~~~~~~~~~~~ +!!! error TS2322: Type '{ s: (t: any) => number; }' is not assignable to type 'J'. +!!! error TS2322: Object literal may only specify known properties, and 's' does not exist in type 'J'. }; y = { 0: t => t * t, // Should error @@ -40,4 +45,5 @@ tests/cases/compiler/objectLitIndexerContextualType.ts(21,17): error TS2363: The !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - }; \ No newline at end of file + }; + \ No newline at end of file diff --git a/tests/baselines/reference/objectLitIndexerContextualType.js b/tests/baselines/reference/objectLitIndexerContextualType.js index f0cf90724b3..601462d8751 100644 --- a/tests/baselines/reference/objectLitIndexerContextualType.js +++ b/tests/baselines/reference/objectLitIndexerContextualType.js @@ -16,11 +16,12 @@ x = { 0: t => t * t, // Should error }; y = { - s: t => t * t, // Should not error + s: t => t * t, // Should error }; y = { 0: t => t * t, // Should error -}; +}; + //// [objectLitIndexerContextualType.js] var x; diff --git a/tests/baselines/reference/objectLiteralExcessProperties.errors.txt b/tests/baselines/reference/objectLiteralExcessProperties.errors.txt index 84f635bf947..b96b9b0c542 100644 --- a/tests/baselines/reference/objectLiteralExcessProperties.errors.txt +++ b/tests/baselines/reference/objectLiteralExcessProperties.errors.txt @@ -15,9 +15,17 @@ tests/cases/compiler/objectLiteralExcessProperties.ts(19,57): error TS2322: Type Object literal may only specify known properties, and 'price' does not exist in type 'Book & Cover'. tests/cases/compiler/objectLiteralExcessProperties.ts(21,43): error TS2322: Type '{ foreword: string; price: number; }' is not assignable to type 'Book & number'. Object literal may only specify known properties, and 'price' does not exist in type 'Book & number'. +tests/cases/compiler/objectLiteralExcessProperties.ts(23,29): error TS2322: Type '{ couleur: string; }' is not assignable to type 'Cover | Cover[]'. + Object literal may only specify known properties, and 'couleur' does not exist in type 'Cover | Cover[]'. +tests/cases/compiler/objectLiteralExcessProperties.ts(25,27): error TS2322: Type '{ forewarned: string; }' is not assignable to type 'Book | Book[]'. + Object literal may only specify known properties, and 'forewarned' does not exist in type 'Book | Book[]'. +tests/cases/compiler/objectLiteralExcessProperties.ts(33,27): error TS2322: Type '{ 0: { colour: string; }; }' is not assignable to type 'Indexed'. + Property '0' is incompatible with index signature. + Type '{ colour: string; }' is not assignable to type 'Cover'. + Object literal may only specify known properties, and 'colour' does not exist in type 'Cover'. -==== tests/cases/compiler/objectLiteralExcessProperties.ts (7 errors) ==== +==== tests/cases/compiler/objectLiteralExcessProperties.ts (10 errors) ==== interface Book { foreword: string; } @@ -63,4 +71,27 @@ tests/cases/compiler/objectLiteralExcessProperties.ts(21,43): error TS2322: Type ~~~~~~~~~~~~ !!! error TS2322: Type '{ foreword: string; price: number; }' is not assignable to type 'Book & number'. !!! error TS2322: Object literal may only specify known properties, and 'price' does not exist in type 'Book & number'. + + var b8: Cover | Cover[] = { couleur : "non" }; + ~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ couleur: string; }' is not assignable to type 'Cover | Cover[]'. +!!! error TS2322: Object literal may only specify known properties, and 'couleur' does not exist in type 'Cover | Cover[]'. + + var b9: Book | Book[] = { forewarned: "still no" }; + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ forewarned: string; }' is not assignable to type 'Book | Book[]'. +!!! error TS2322: Object literal may only specify known properties, and 'forewarned' does not exist in type 'Book | Book[]'. + + interface Indexed { + [n: number]: Cover; + } + + var b10: Indexed = { 0: { }, '1': { } }; // ok + + var b11: Indexed = { 0: { colour: "blue" } }; // nested object literal still errors + ~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ 0: { colour: string; }; }' is not assignable to type 'Indexed'. +!!! error TS2322: Property '0' is incompatible with index signature. +!!! error TS2322: Type '{ colour: string; }' is not assignable to type 'Cover'. +!!! error TS2322: Object literal may only specify known properties, and 'colour' does not exist in type 'Cover'. \ No newline at end of file diff --git a/tests/baselines/reference/objectLiteralExcessProperties.js b/tests/baselines/reference/objectLiteralExcessProperties.js index 747928ccb20..38186b19bf7 100644 --- a/tests/baselines/reference/objectLiteralExcessProperties.js +++ b/tests/baselines/reference/objectLiteralExcessProperties.js @@ -20,6 +20,18 @@ var b5: Book & Cover = { foreward: "hi", color: "blue" }; var b6: Book & Cover = { foreword: "hi", color: "blue", price: 10.99 }; var b7: Book & number = { foreword: "hi", price: 10.99 }; + +var b8: Cover | Cover[] = { couleur : "non" }; + +var b9: Book | Book[] = { forewarned: "still no" }; + +interface Indexed { + [n: number]: Cover; +} + +var b10: Indexed = { 0: { }, '1': { } }; // ok + +var b11: Indexed = { 0: { colour: "blue" } }; // nested object literal still errors //// [objectLiteralExcessProperties.js] @@ -30,3 +42,7 @@ var b4 = { foreword: "hi", colour: "blue" }; var b5 = { foreward: "hi", color: "blue" }; var b6 = { foreword: "hi", color: "blue", price: 10.99 }; var b7 = { foreword: "hi", price: 10.99 }; +var b8 = { couleur: "non" }; +var b9 = { forewarned: "still no" }; +var b10 = { 0: {}, '1': {} }; // ok +var b11 = { 0: { colour: "blue" } }; // nested object literal still errors diff --git a/tests/baselines/reference/objectTypesIdentityWithNumericIndexers1.js b/tests/baselines/reference/objectTypesIdentityWithNumericIndexers1.js index c0bd423cd79..29781229b5a 100644 --- a/tests/baselines/reference/objectTypesIdentityWithNumericIndexers1.js +++ b/tests/baselines/reference/objectTypesIdentityWithNumericIndexers1.js @@ -26,7 +26,7 @@ class PB extends B { var a: { [x: number]: string; } -var b: { [x: number]: string; } = { foo: '' }; +var b: { [x: number]: string; } = { 0: '' }; function foo1(x: A); function foo1(x: A); // error @@ -159,7 +159,7 @@ var PB = (function (_super) { return PB; }(B)); var a; -var b = { foo: '' }; +var b = { 0: '' }; function foo1(x) { } function foo1b(x) { } function foo1c(x) { } diff --git a/tests/baselines/reference/objectTypesIdentityWithNumericIndexers1.symbols b/tests/baselines/reference/objectTypesIdentityWithNumericIndexers1.symbols index 4a2eb1ab2a1..798fb5c3c57 100644 --- a/tests/baselines/reference/objectTypesIdentityWithNumericIndexers1.symbols +++ b/tests/baselines/reference/objectTypesIdentityWithNumericIndexers1.symbols @@ -47,23 +47,22 @@ var a: { [x: number]: string; >x : Symbol(x, Decl(objectTypesIdentityWithNumericIndexers1.ts, 25, 5)) } -var b: { [x: number]: string; } = { foo: '' }; +var b: { [x: number]: string; } = { 0: '' }; >b : Symbol(b, Decl(objectTypesIdentityWithNumericIndexers1.ts, 27, 3)) >x : Symbol(x, Decl(objectTypesIdentityWithNumericIndexers1.ts, 27, 10)) ->foo : Symbol(foo, Decl(objectTypesIdentityWithNumericIndexers1.ts, 27, 35)) function foo1(x: A); ->foo1 : Symbol(foo1, Decl(objectTypesIdentityWithNumericIndexers1.ts, 27, 46), Decl(objectTypesIdentityWithNumericIndexers1.ts, 29, 20), Decl(objectTypesIdentityWithNumericIndexers1.ts, 30, 20)) +>foo1 : Symbol(foo1, Decl(objectTypesIdentityWithNumericIndexers1.ts, 27, 44), Decl(objectTypesIdentityWithNumericIndexers1.ts, 29, 20), Decl(objectTypesIdentityWithNumericIndexers1.ts, 30, 20)) >x : Symbol(x, Decl(objectTypesIdentityWithNumericIndexers1.ts, 29, 14)) >A : Symbol(A, Decl(objectTypesIdentityWithNumericIndexers1.ts, 0, 0)) function foo1(x: A); // error ->foo1 : Symbol(foo1, Decl(objectTypesIdentityWithNumericIndexers1.ts, 27, 46), Decl(objectTypesIdentityWithNumericIndexers1.ts, 29, 20), Decl(objectTypesIdentityWithNumericIndexers1.ts, 30, 20)) +>foo1 : Symbol(foo1, Decl(objectTypesIdentityWithNumericIndexers1.ts, 27, 44), Decl(objectTypesIdentityWithNumericIndexers1.ts, 29, 20), Decl(objectTypesIdentityWithNumericIndexers1.ts, 30, 20)) >x : Symbol(x, Decl(objectTypesIdentityWithNumericIndexers1.ts, 30, 14)) >A : Symbol(A, Decl(objectTypesIdentityWithNumericIndexers1.ts, 0, 0)) function foo1(x: any) { } ->foo1 : Symbol(foo1, Decl(objectTypesIdentityWithNumericIndexers1.ts, 27, 46), Decl(objectTypesIdentityWithNumericIndexers1.ts, 29, 20), Decl(objectTypesIdentityWithNumericIndexers1.ts, 30, 20)) +>foo1 : Symbol(foo1, Decl(objectTypesIdentityWithNumericIndexers1.ts, 27, 44), Decl(objectTypesIdentityWithNumericIndexers1.ts, 29, 20), Decl(objectTypesIdentityWithNumericIndexers1.ts, 30, 20)) >x : Symbol(x, Decl(objectTypesIdentityWithNumericIndexers1.ts, 31, 14)) function foo1b(x: B); diff --git a/tests/baselines/reference/objectTypesIdentityWithNumericIndexers1.types b/tests/baselines/reference/objectTypesIdentityWithNumericIndexers1.types index c5de5c7b9b4..78c69f0cdd3 100644 --- a/tests/baselines/reference/objectTypesIdentityWithNumericIndexers1.types +++ b/tests/baselines/reference/objectTypesIdentityWithNumericIndexers1.types @@ -47,11 +47,10 @@ var a: { [x: number]: string; >x : number } -var b: { [x: number]: string; } = { foo: '' }; +var b: { [x: number]: string; } = { 0: '' }; >b : { [x: number]: string; } >x : number ->{ foo: '' } : { foo: string; } ->foo : string +>{ 0: '' } : { 0: string; } >'' : string function foo1(x: A); diff --git a/tests/baselines/reference/objectTypesIdentityWithNumericIndexers2.js b/tests/baselines/reference/objectTypesIdentityWithNumericIndexers2.js index 98c29e96a86..7ecb597a2d9 100644 --- a/tests/baselines/reference/objectTypesIdentityWithNumericIndexers2.js +++ b/tests/baselines/reference/objectTypesIdentityWithNumericIndexers2.js @@ -29,7 +29,7 @@ class PB extends B { var a: { [x: number]: Base; } -var b: { [x: number]: Derived; } = { foo: null }; +var b: { [x: number]: Derived; } = { 0: null }; function foo1(x: A); function foo1(x: A); // error @@ -174,7 +174,7 @@ var PB = (function (_super) { return PB; }(B)); var a; -var b = { foo: null }; +var b = { 0: null }; function foo1(x) { } function foo1b(x) { } function foo1c(x) { } diff --git a/tests/baselines/reference/objectTypesIdentityWithNumericIndexers2.symbols b/tests/baselines/reference/objectTypesIdentityWithNumericIndexers2.symbols index 5fde90941ef..b4ad1857748 100644 --- a/tests/baselines/reference/objectTypesIdentityWithNumericIndexers2.symbols +++ b/tests/baselines/reference/objectTypesIdentityWithNumericIndexers2.symbols @@ -60,25 +60,24 @@ var a: { >x : Symbol(x, Decl(objectTypesIdentityWithNumericIndexers2.ts, 28, 5)) >Base : Symbol(Base, Decl(objectTypesIdentityWithNumericIndexers2.ts, 0, 0)) } -var b: { [x: number]: Derived; } = { foo: null }; +var b: { [x: number]: Derived; } = { 0: null }; >b : Symbol(b, Decl(objectTypesIdentityWithNumericIndexers2.ts, 30, 3)) >x : Symbol(x, Decl(objectTypesIdentityWithNumericIndexers2.ts, 30, 10)) >Derived : Symbol(Derived, Decl(objectTypesIdentityWithNumericIndexers2.ts, 2, 27)) ->foo : Symbol(foo, Decl(objectTypesIdentityWithNumericIndexers2.ts, 30, 36)) >Derived : Symbol(Derived, Decl(objectTypesIdentityWithNumericIndexers2.ts, 2, 27)) function foo1(x: A); ->foo1 : Symbol(foo1, Decl(objectTypesIdentityWithNumericIndexers2.ts, 30, 58), Decl(objectTypesIdentityWithNumericIndexers2.ts, 32, 20), Decl(objectTypesIdentityWithNumericIndexers2.ts, 33, 20)) +>foo1 : Symbol(foo1, Decl(objectTypesIdentityWithNumericIndexers2.ts, 30, 56), Decl(objectTypesIdentityWithNumericIndexers2.ts, 32, 20), Decl(objectTypesIdentityWithNumericIndexers2.ts, 33, 20)) >x : Symbol(x, Decl(objectTypesIdentityWithNumericIndexers2.ts, 32, 14)) >A : Symbol(A, Decl(objectTypesIdentityWithNumericIndexers2.ts, 3, 43)) function foo1(x: A); // error ->foo1 : Symbol(foo1, Decl(objectTypesIdentityWithNumericIndexers2.ts, 30, 58), Decl(objectTypesIdentityWithNumericIndexers2.ts, 32, 20), Decl(objectTypesIdentityWithNumericIndexers2.ts, 33, 20)) +>foo1 : Symbol(foo1, Decl(objectTypesIdentityWithNumericIndexers2.ts, 30, 56), Decl(objectTypesIdentityWithNumericIndexers2.ts, 32, 20), Decl(objectTypesIdentityWithNumericIndexers2.ts, 33, 20)) >x : Symbol(x, Decl(objectTypesIdentityWithNumericIndexers2.ts, 33, 14)) >A : Symbol(A, Decl(objectTypesIdentityWithNumericIndexers2.ts, 3, 43)) function foo1(x: any) { } ->foo1 : Symbol(foo1, Decl(objectTypesIdentityWithNumericIndexers2.ts, 30, 58), Decl(objectTypesIdentityWithNumericIndexers2.ts, 32, 20), Decl(objectTypesIdentityWithNumericIndexers2.ts, 33, 20)) +>foo1 : Symbol(foo1, Decl(objectTypesIdentityWithNumericIndexers2.ts, 30, 56), Decl(objectTypesIdentityWithNumericIndexers2.ts, 32, 20), Decl(objectTypesIdentityWithNumericIndexers2.ts, 33, 20)) >x : Symbol(x, Decl(objectTypesIdentityWithNumericIndexers2.ts, 34, 14)) function foo1b(x: B); diff --git a/tests/baselines/reference/objectTypesIdentityWithNumericIndexers2.types b/tests/baselines/reference/objectTypesIdentityWithNumericIndexers2.types index 17fc6a07a00..ce38d95174b 100644 --- a/tests/baselines/reference/objectTypesIdentityWithNumericIndexers2.types +++ b/tests/baselines/reference/objectTypesIdentityWithNumericIndexers2.types @@ -60,12 +60,11 @@ var a: { >x : number >Base : Base } -var b: { [x: number]: Derived; } = { foo: null }; +var b: { [x: number]: Derived; } = { 0: null }; >b : { [x: number]: Derived; } >x : number >Derived : Derived ->{ foo: null } : { foo: Derived; } ->foo : Derived +>{ 0: null } : { 0: Derived; } >null : Derived >Derived : Derived >null : null diff --git a/tests/baselines/reference/objectTypesIdentityWithNumericIndexers3.js b/tests/baselines/reference/objectTypesIdentityWithNumericIndexers3.js index ea85b8b3c67..9710afe700d 100644 --- a/tests/baselines/reference/objectTypesIdentityWithNumericIndexers3.js +++ b/tests/baselines/reference/objectTypesIdentityWithNumericIndexers3.js @@ -26,7 +26,7 @@ class PB extends B { var a: { [x: string]: string; } -var b: { [x: number]: string; } = { foo: '' }; +var b: { [x: number]: string; } = { 0: '' }; function foo1(x: A); function foo1(x: A); // error @@ -159,7 +159,7 @@ var PB = (function (_super) { return PB; }(B)); var a; -var b = { foo: '' }; +var b = { 0: '' }; function foo1(x) { } function foo1b(x) { } function foo1c(x) { } diff --git a/tests/baselines/reference/objectTypesIdentityWithNumericIndexers3.symbols b/tests/baselines/reference/objectTypesIdentityWithNumericIndexers3.symbols index c0bc1b5cf60..ed95b3a7025 100644 --- a/tests/baselines/reference/objectTypesIdentityWithNumericIndexers3.symbols +++ b/tests/baselines/reference/objectTypesIdentityWithNumericIndexers3.symbols @@ -47,23 +47,22 @@ var a: { [x: string]: string; >x : Symbol(x, Decl(objectTypesIdentityWithNumericIndexers3.ts, 25, 5)) } -var b: { [x: number]: string; } = { foo: '' }; +var b: { [x: number]: string; } = { 0: '' }; >b : Symbol(b, Decl(objectTypesIdentityWithNumericIndexers3.ts, 27, 3)) >x : Symbol(x, Decl(objectTypesIdentityWithNumericIndexers3.ts, 27, 10)) ->foo : Symbol(foo, Decl(objectTypesIdentityWithNumericIndexers3.ts, 27, 35)) function foo1(x: A); ->foo1 : Symbol(foo1, Decl(objectTypesIdentityWithNumericIndexers3.ts, 27, 46), Decl(objectTypesIdentityWithNumericIndexers3.ts, 29, 20), Decl(objectTypesIdentityWithNumericIndexers3.ts, 30, 20)) +>foo1 : Symbol(foo1, Decl(objectTypesIdentityWithNumericIndexers3.ts, 27, 44), Decl(objectTypesIdentityWithNumericIndexers3.ts, 29, 20), Decl(objectTypesIdentityWithNumericIndexers3.ts, 30, 20)) >x : Symbol(x, Decl(objectTypesIdentityWithNumericIndexers3.ts, 29, 14)) >A : Symbol(A, Decl(objectTypesIdentityWithNumericIndexers3.ts, 0, 0)) function foo1(x: A); // error ->foo1 : Symbol(foo1, Decl(objectTypesIdentityWithNumericIndexers3.ts, 27, 46), Decl(objectTypesIdentityWithNumericIndexers3.ts, 29, 20), Decl(objectTypesIdentityWithNumericIndexers3.ts, 30, 20)) +>foo1 : Symbol(foo1, Decl(objectTypesIdentityWithNumericIndexers3.ts, 27, 44), Decl(objectTypesIdentityWithNumericIndexers3.ts, 29, 20), Decl(objectTypesIdentityWithNumericIndexers3.ts, 30, 20)) >x : Symbol(x, Decl(objectTypesIdentityWithNumericIndexers3.ts, 30, 14)) >A : Symbol(A, Decl(objectTypesIdentityWithNumericIndexers3.ts, 0, 0)) function foo1(x: any) { } ->foo1 : Symbol(foo1, Decl(objectTypesIdentityWithNumericIndexers3.ts, 27, 46), Decl(objectTypesIdentityWithNumericIndexers3.ts, 29, 20), Decl(objectTypesIdentityWithNumericIndexers3.ts, 30, 20)) +>foo1 : Symbol(foo1, Decl(objectTypesIdentityWithNumericIndexers3.ts, 27, 44), Decl(objectTypesIdentityWithNumericIndexers3.ts, 29, 20), Decl(objectTypesIdentityWithNumericIndexers3.ts, 30, 20)) >x : Symbol(x, Decl(objectTypesIdentityWithNumericIndexers3.ts, 31, 14)) function foo1b(x: B); diff --git a/tests/baselines/reference/objectTypesIdentityWithNumericIndexers3.types b/tests/baselines/reference/objectTypesIdentityWithNumericIndexers3.types index 99e6b8c8632..a6ea5a292e5 100644 --- a/tests/baselines/reference/objectTypesIdentityWithNumericIndexers3.types +++ b/tests/baselines/reference/objectTypesIdentityWithNumericIndexers3.types @@ -47,11 +47,10 @@ var a: { [x: string]: string; >x : string } -var b: { [x: number]: string; } = { foo: '' }; +var b: { [x: number]: string; } = { 0: '' }; >b : { [x: number]: string; } >x : number ->{ foo: '' } : { foo: string; } ->foo : string +>{ 0: '' } : { 0: string; } >'' : string function foo1(x: A); diff --git a/tests/baselines/reference/optionalParameterProperty.errors.txt b/tests/baselines/reference/optionalParameterProperty.errors.txt new file mode 100644 index 00000000000..d585ff6964d --- /dev/null +++ b/tests/baselines/reference/optionalParameterProperty.errors.txt @@ -0,0 +1,23 @@ +tests/cases/compiler/optionalParameterProperty.ts(6,7): error TS2415: Class 'D' incorrectly extends base class 'C'. + Types of property 'p' are incompatible. + Type 'number | undefined' is not assignable to type 'number'. + Type 'undefined' is not assignable to type 'number'. + + +==== tests/cases/compiler/optionalParameterProperty.ts (1 errors) ==== + + class C { + p: number; + } + + class D extends C { + ~ +!!! error TS2415: Class 'D' incorrectly extends base class 'C'. +!!! error TS2415: Types of property 'p' are incompatible. +!!! error TS2415: Type 'number | undefined' is not assignable to type 'number'. +!!! error TS2415: Type 'undefined' is not assignable to type 'number'. + constructor(public p?: number) { + super(); + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/optionalParameterProperty.js b/tests/baselines/reference/optionalParameterProperty.js new file mode 100644 index 00000000000..48cefeef22c --- /dev/null +++ b/tests/baselines/reference/optionalParameterProperty.js @@ -0,0 +1,32 @@ +//// [optionalParameterProperty.ts] + +class C { + p: number; +} + +class D extends C { + constructor(public p?: number) { + super(); + } +} + + +//// [optionalParameterProperty.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var C = (function () { + function C() { + } + return C; +}()); +var D = (function (_super) { + __extends(D, _super); + function D(p) { + _super.call(this); + this.p = p; + } + return D; +}(C)); diff --git a/tests/baselines/reference/optionalParamterAndVariableDeclaration.js b/tests/baselines/reference/optionalParamterAndVariableDeclaration.js new file mode 100644 index 00000000000..ae672b15d54 --- /dev/null +++ b/tests/baselines/reference/optionalParamterAndVariableDeclaration.js @@ -0,0 +1,15 @@ +//// [optionalParamterAndVariableDeclaration.ts] +class C { + constructor(options?: number) { + var options = (options || 0); + } +} + + +//// [optionalParamterAndVariableDeclaration.js] +var C = (function () { + function C(options) { + var options = (options || 0); + } + return C; +}()); diff --git a/tests/baselines/reference/optionalParamterAndVariableDeclaration.symbols b/tests/baselines/reference/optionalParamterAndVariableDeclaration.symbols new file mode 100644 index 00000000000..0a761182e02 --- /dev/null +++ b/tests/baselines/reference/optionalParamterAndVariableDeclaration.symbols @@ -0,0 +1,13 @@ +=== tests/cases/compiler/optionalParamterAndVariableDeclaration.ts === +class C { +>C : Symbol(C, Decl(optionalParamterAndVariableDeclaration.ts, 0, 0)) + + constructor(options?: number) { +>options : Symbol(options, Decl(optionalParamterAndVariableDeclaration.ts, 1, 16), Decl(optionalParamterAndVariableDeclaration.ts, 2, 11)) + + var options = (options || 0); +>options : Symbol(options, Decl(optionalParamterAndVariableDeclaration.ts, 1, 16), Decl(optionalParamterAndVariableDeclaration.ts, 2, 11)) +>options : Symbol(options, Decl(optionalParamterAndVariableDeclaration.ts, 1, 16), Decl(optionalParamterAndVariableDeclaration.ts, 2, 11)) + } +} + diff --git a/tests/baselines/reference/optionalParamterAndVariableDeclaration.types b/tests/baselines/reference/optionalParamterAndVariableDeclaration.types new file mode 100644 index 00000000000..36c74bf00b9 --- /dev/null +++ b/tests/baselines/reference/optionalParamterAndVariableDeclaration.types @@ -0,0 +1,16 @@ +=== tests/cases/compiler/optionalParamterAndVariableDeclaration.ts === +class C { +>C : C + + constructor(options?: number) { +>options : number + + var options = (options || 0); +>options : number +>(options || 0) : number +>options || 0 : number +>options : number +>0 : number + } +} + diff --git a/tests/baselines/reference/optionalParamterAndVariableDeclaration2.errors.txt b/tests/baselines/reference/optionalParamterAndVariableDeclaration2.errors.txt new file mode 100644 index 00000000000..0d309327531 --- /dev/null +++ b/tests/baselines/reference/optionalParamterAndVariableDeclaration2.errors.txt @@ -0,0 +1,13 @@ +tests/cases/compiler/optionalParamterAndVariableDeclaration2.ts(4,13): error TS2403: Subsequent variable declarations must have the same type. Variable 'options' must be of type 'number | undefined', but here has type 'number'. + + +==== tests/cases/compiler/optionalParamterAndVariableDeclaration2.ts (1 errors) ==== + + class C { + constructor(options?: number) { + var options = (options || 0); + ~~~~~~~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'options' must be of type 'number | undefined', but here has type 'number'. + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/optionalParamterAndVariableDeclaration2.js b/tests/baselines/reference/optionalParamterAndVariableDeclaration2.js new file mode 100644 index 00000000000..a4ffc9f382d --- /dev/null +++ b/tests/baselines/reference/optionalParamterAndVariableDeclaration2.js @@ -0,0 +1,16 @@ +//// [optionalParamterAndVariableDeclaration2.ts] + +class C { + constructor(options?: number) { + var options = (options || 0); + } +} + + +//// [optionalParamterAndVariableDeclaration2.js] +var C = (function () { + function C(options) { + var options = (options || 0); + } + return C; +}()); diff --git a/tests/baselines/reference/propertyAccess.errors.txt b/tests/baselines/reference/propertyAccess.errors.txt index 7d496f87751..b3244956174 100644 --- a/tests/baselines/reference/propertyAccess.errors.txt +++ b/tests/baselines/reference/propertyAccess.errors.txt @@ -1,10 +1,12 @@ +tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(11,55): error TS2322: Type '{ 3: string; 'three': string; }' is not assignable to type '{ [n: number]: string; }'. + Object literal may only specify known properties, and ''three'' does not exist in type '{ [n: number]: string; }'. tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(45,14): error TS2339: Property 'qqq' does not exist on type '{ 10: string; x: string; y: number; z: { n: string; m: number; o: () => boolean; }; 'literal property': number; }'. tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(80,10): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'. tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(117,10): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'. tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(140,12): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'. -==== tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts (4 errors) ==== +==== tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts (5 errors) ==== class A { a: number; } @@ -16,6 +18,9 @@ tests/cases/conformance/expressions/propertyAccess/propertyAccess.ts(140,12): er } var numIndex: { [n: number]: string } = { 3: 'three', 'three': 'three' }; + ~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ 3: string; 'three': string; }' is not assignable to type '{ [n: number]: string; }'. +!!! error TS2322: Object literal may only specify known properties, and ''three'' does not exist in type '{ [n: number]: string; }'. var strIndex: { [n: string]: Compass } = { 'N': Compass.North, 'E': Compass.East }; var bothIndex: { diff --git a/tests/baselines/reference/propertyParameterWithQuestionMark.errors.txt b/tests/baselines/reference/propertyParameterWithQuestionMark.errors.txt index b3970c216eb..76dfb503e52 100644 --- a/tests/baselines/reference/propertyParameterWithQuestionMark.errors.txt +++ b/tests/baselines/reference/propertyParameterWithQuestionMark.errors.txt @@ -1,22 +1,17 @@ -tests/cases/compiler/propertyParameterWithQuestionMark.ts(6,5): error TS2322: Type '{}' is not assignable to type 'C'. - Property 'x' is missing in type '{}'. -tests/cases/compiler/propertyParameterWithQuestionMark.ts(8,1): error TS2322: Type '{ x?: any; }' is not assignable to type 'C'. - Property 'x' is optional in type '{ x?: any; }' but required in type 'C'. +tests/cases/compiler/propertyParameterWithQuestionMark.ts(9,5): error TS2322: Type 'C' is not assignable to type '{ x: any; }'. + Property 'x' is optional in type 'C' but required in type '{ x: any; }'. -==== tests/cases/compiler/propertyParameterWithQuestionMark.ts (2 errors) ==== +==== tests/cases/compiler/propertyParameterWithQuestionMark.ts (1 errors) ==== class C { constructor(public x?) { } } - // x should not be an optional property - var v: C = {}; // Should fail - ~ -!!! error TS2322: Type '{}' is not assignable to type 'C'. -!!! error TS2322: Property 'x' is missing in type '{}'. + // x should be an optional property + var v: C = {}; // Should succeed var v2: { x? } - v = v2; // Should fail - ~ -!!! error TS2322: Type '{ x?: any; }' is not assignable to type 'C'. -!!! error TS2322: Property 'x' is optional in type '{ x?: any; }' but required in type 'C'. - var v3: { x } = new C; // Should succeed \ No newline at end of file + v = v2; // Should succeed + var v3: { x } = new C; // Should fail + ~~ +!!! error TS2322: Type 'C' is not assignable to type '{ x: any; }'. +!!! error TS2322: Property 'x' is optional in type 'C' but required in type '{ x: any; }'. \ No newline at end of file diff --git a/tests/baselines/reference/propertyParameterWithQuestionMark.js b/tests/baselines/reference/propertyParameterWithQuestionMark.js index 511062663e8..b72638387dd 100644 --- a/tests/baselines/reference/propertyParameterWithQuestionMark.js +++ b/tests/baselines/reference/propertyParameterWithQuestionMark.js @@ -3,11 +3,11 @@ class C { constructor(public x?) { } } -// x should not be an optional property -var v: C = {}; // Should fail +// x should be an optional property +var v: C = {}; // Should succeed var v2: { x? } -v = v2; // Should fail -var v3: { x } = new C; // Should succeed +v = v2; // Should succeed +var v3: { x } = new C; // Should fail //// [propertyParameterWithQuestionMark.js] var C = (function () { @@ -16,8 +16,8 @@ var C = (function () { } return C; }()); -// x should not be an optional property -var v = {}; // Should fail +// x should be an optional property +var v = {}; // Should succeed var v2; -v = v2; // Should fail -var v3 = new C; // Should succeed +v = v2; // Should succeed +var v3 = new C; // Should fail diff --git a/tests/baselines/reference/reachabilityCheckWithEmptyDefault.js b/tests/baselines/reference/reachabilityCheckWithEmptyDefault.js new file mode 100644 index 00000000000..0096d2d2f9a --- /dev/null +++ b/tests/baselines/reference/reachabilityCheckWithEmptyDefault.js @@ -0,0 +1,18 @@ +//// [reachabilityCheckWithEmptyDefault.ts] +declare function print(s: string): void; +function foo(x: any) { + switch(x) { + case 1: return; + default: + } + print('1'); +} + +//// [reachabilityCheckWithEmptyDefault.js] +function foo(x) { + switch (x) { + case 1: return; + default: + } + print('1'); +} diff --git a/tests/baselines/reference/reachabilityCheckWithEmptyDefault.symbols b/tests/baselines/reference/reachabilityCheckWithEmptyDefault.symbols new file mode 100644 index 00000000000..d3123c0e8ba --- /dev/null +++ b/tests/baselines/reference/reachabilityCheckWithEmptyDefault.symbols @@ -0,0 +1,18 @@ +=== tests/cases/compiler/reachabilityCheckWithEmptyDefault.ts === +declare function print(s: string): void; +>print : Symbol(print, Decl(reachabilityCheckWithEmptyDefault.ts, 0, 0)) +>s : Symbol(s, Decl(reachabilityCheckWithEmptyDefault.ts, 0, 23)) + +function foo(x: any) { +>foo : Symbol(foo, Decl(reachabilityCheckWithEmptyDefault.ts, 0, 40)) +>x : Symbol(x, Decl(reachabilityCheckWithEmptyDefault.ts, 1, 13)) + + switch(x) { +>x : Symbol(x, Decl(reachabilityCheckWithEmptyDefault.ts, 1, 13)) + + case 1: return; + default: + } + print('1'); +>print : Symbol(print, Decl(reachabilityCheckWithEmptyDefault.ts, 0, 0)) +} diff --git a/tests/baselines/reference/reachabilityCheckWithEmptyDefault.types b/tests/baselines/reference/reachabilityCheckWithEmptyDefault.types new file mode 100644 index 00000000000..3d01b876473 --- /dev/null +++ b/tests/baselines/reference/reachabilityCheckWithEmptyDefault.types @@ -0,0 +1,22 @@ +=== tests/cases/compiler/reachabilityCheckWithEmptyDefault.ts === +declare function print(s: string): void; +>print : (s: string) => void +>s : string + +function foo(x: any) { +>foo : (x: any) => void +>x : any + + switch(x) { +>x : any + + case 1: return; +>1 : number + + default: + } + print('1'); +>print('1') : void +>print : (s: string) => void +>'1' : string +} diff --git a/tests/baselines/reference/tsxPreserveEmit1.symbols b/tests/baselines/reference/tsxPreserveEmit1.symbols index 53707b86104..b5651d7c38e 100644 --- a/tests/baselines/reference/tsxPreserveEmit1.symbols +++ b/tests/baselines/reference/tsxPreserveEmit1.symbols @@ -8,7 +8,7 @@ import ReactRouter = require('react-router'); import Route = ReactRouter.Route; >Route : Symbol(Route, Decl(test.tsx, 2, 45)) ->ReactRouter : Symbol(ReactRouter, Decl(react.d.ts, 4, 1)) +>ReactRouter : Symbol(ReactRouter, Decl(test.tsx, 1, 32)) >Route : Symbol(ReactRouter.Route, Decl(react.d.ts, 7, 4)) var routes1 = ; diff --git a/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.js b/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.js index 91443a9ae78..8ec45de814e 100644 --- a/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.js +++ b/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.js @@ -41,7 +41,7 @@ function foo4(x: number | string | boolean) { : x.toString(); // number })(x); // x here is narrowed to number | boolean } -// Type guards affect nested function expressions and nested function declarations +// Type guards do not affect nested function declarations function foo5(x: number | string | boolean) { if (typeof x === "string") { var y = x; // string; @@ -121,7 +121,7 @@ function foo4(x) { : x.toString(); // number })(x); // x here is narrowed to number | boolean } -// Type guards affect nested function expressions and nested function declarations +// Type guards do not affect nested function declarations function foo5(x) { if (typeof x === "string") { var y = x; // string; diff --git a/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.symbols b/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.symbols index bf21641624e..56eeb22bf9f 100644 --- a/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.symbols +++ b/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.symbols @@ -27,9 +27,9 @@ function foo(x: number | string | boolean) { >toString : Symbol(Object.toString, Decl(lib.d.ts, --, --)) : x.toString(); // number ->x.toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>x.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) >x : Symbol(x, Decl(typeGuardsInFunctionAndModuleBlock.ts, 2, 13)) ->toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) } (); } @@ -60,9 +60,9 @@ function foo2(x: number | string | boolean) { >toString : Symbol(Object.toString, Decl(lib.d.ts, --, --)) : x.toString(); // number ->x.toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>x.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) >x : Symbol(x, Decl(typeGuardsInFunctionAndModuleBlock.ts, 12, 14)) ->toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) } (x); // x here is narrowed to number | boolean >x : Symbol(x, Decl(typeGuardsInFunctionAndModuleBlock.ts, 12, 14)) @@ -91,9 +91,9 @@ function foo3(x: number | string | boolean) { >toString : Symbol(Object.toString, Decl(lib.d.ts, --, --)) : x.toString(); // number ->x.toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>x.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) >x : Symbol(x, Decl(typeGuardsInFunctionAndModuleBlock.ts, 22, 14)) ->toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) })(); } @@ -123,14 +123,14 @@ function foo4(x: number | string | boolean) { >toString : Symbol(Object.toString, Decl(lib.d.ts, --, --)) : x.toString(); // number ->x.toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>x.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) >x : Symbol(x, Decl(typeGuardsInFunctionAndModuleBlock.ts, 32, 14)) ->toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) })(x); // x here is narrowed to number | boolean >x : Symbol(x, Decl(typeGuardsInFunctionAndModuleBlock.ts, 32, 14)) } -// Type guards affect nested function expressions and nested function declarations +// Type guards do not affect nested function declarations function foo5(x: number | string | boolean) { >foo5 : Symbol(foo5, Decl(typeGuardsInFunctionAndModuleBlock.ts, 41, 1)) >x : Symbol(x, Decl(typeGuardsInFunctionAndModuleBlock.ts, 43, 14)) diff --git a/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.types b/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.types index 67d1816cfc3..cc9553b9767 100644 --- a/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.types +++ b/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.types @@ -21,14 +21,14 @@ function foo(x: number | string | boolean) { >f : () => string var b = x; // number | boolean ->b : number | string | boolean ->x : number | string | boolean +>b : number | boolean +>x : number | boolean return typeof x === "boolean" >typeof x === "boolean" ? x.toString() // boolean : x.toString() : string >typeof x === "boolean" : boolean >typeof x : string ->x : number | string | boolean +>x : number | boolean >"boolean" : string ? x.toString() // boolean @@ -40,7 +40,7 @@ function foo(x: number | string | boolean) { : x.toString(); // number >x.toString() : string >x.toString : (radix?: number) => string ->x : number | string +>x : number >toString : (radix?: number) => string } (); @@ -66,14 +66,14 @@ function foo2(x: number | string | boolean) { >a : number | boolean var b = x; // new scope - number | boolean ->b : number | string | boolean ->x : number | string | boolean +>b : number | boolean +>x : number | boolean return typeof x === "boolean" >typeof x === "boolean" ? x.toString() // boolean : x.toString() : string >typeof x === "boolean" : boolean >typeof x : string ->x : number | string | boolean +>x : number | boolean >"boolean" : string ? x.toString() // boolean @@ -85,7 +85,7 @@ function foo2(x: number | string | boolean) { : x.toString(); // number >x.toString() : string >x.toString : (radix?: number) => string ->x : number | string +>x : number >toString : (radix?: number) => string } (x); // x here is narrowed to number | boolean @@ -111,14 +111,14 @@ function foo3(x: number | string | boolean) { >() => { var b = x; // new scope - number | boolean return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number } : () => string var b = x; // new scope - number | boolean ->b : number | string | boolean ->x : number | string | boolean +>b : number | boolean +>x : number | boolean return typeof x === "boolean" >typeof x === "boolean" ? x.toString() // boolean : x.toString() : string >typeof x === "boolean" : boolean >typeof x : string ->x : number | string | boolean +>x : number | boolean >"boolean" : string ? x.toString() // boolean @@ -130,7 +130,7 @@ function foo3(x: number | string | boolean) { : x.toString(); // number >x.toString() : string >x.toString : (radix?: number) => string ->x : number | string +>x : number >toString : (radix?: number) => string })(); @@ -156,14 +156,14 @@ function foo4(x: number | string | boolean) { >a : number | boolean var b = x; // new scope - number | boolean ->b : number | string | boolean ->x : number | string | boolean +>b : number | boolean +>x : number | boolean return typeof x === "boolean" >typeof x === "boolean" ? x.toString() // boolean : x.toString() : string >typeof x === "boolean" : boolean >typeof x : string ->x : number | string | boolean +>x : number | boolean >"boolean" : string ? x.toString() // boolean @@ -175,13 +175,13 @@ function foo4(x: number | string | boolean) { : x.toString(); // number >x.toString() : string >x.toString : (radix?: number) => string ->x : number | string +>x : number >toString : (radix?: number) => string })(x); // x here is narrowed to number | boolean >x : number | boolean } -// Type guards affect nested function expressions and nested function declarations +// Type guards do not affect nested function declarations function foo5(x: number | string | boolean) { >foo5 : (x: number | string | boolean) => void >x : number | string | boolean diff --git a/tests/baselines/reference/typeParameterExplicitlyExtendsAny.errors.txt b/tests/baselines/reference/typeParameterExplicitlyExtendsAny.errors.txt index 24f40e967da..27d1738fcbc 100644 --- a/tests/baselines/reference/typeParameterExplicitlyExtendsAny.errors.txt +++ b/tests/baselines/reference/typeParameterExplicitlyExtendsAny.errors.txt @@ -1,9 +1,7 @@ tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(3,7): error TS2339: Property 'blah' does not exist on type 'T'. -tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(9,7): error TS2339: Property 'blah' does not exist on type 'T'. -tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(10,7): error TS2339: Property 'toString' does not exist on type 'T'. -==== tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts (3 errors) ==== +==== tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts (1 errors) ==== function fee() { var t: T; t.blah; // Error @@ -14,10 +12,28 @@ tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(10,7): error TS2339: P function fee2() { var t: T; - t.blah; // Error - ~~~~ -!!! error TS2339: Property 'blah' does not exist on type 'T'. + t.blah; // ok t.toString; // ok - ~~~~~~~~ -!!! error TS2339: Property 'toString' does not exist on type 'T'. - } \ No newline at end of file + } + + function f(x: T) { + x.children; + x(); + new x(); + x[100]; + x['hello']; + } + + + // Generic Tree structure + type Tree = T & { + children?: Tree[]; + } + + class MyClass { + public static displayTree1>(tree: T) { + // error "Property 'children' does not exist on type 'T'" + tree.children; + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/typeParameterExplicitlyExtendsAny.js b/tests/baselines/reference/typeParameterExplicitlyExtendsAny.js index 5a1775d44ae..3c2ec6c5977 100644 --- a/tests/baselines/reference/typeParameterExplicitlyExtendsAny.js +++ b/tests/baselines/reference/typeParameterExplicitlyExtendsAny.js @@ -7,9 +7,31 @@ function fee() { function fee2() { var t: T; - t.blah; // Error + t.blah; // ok t.toString; // ok -} +} + +function f(x: T) { + x.children; + x(); + new x(); + x[100]; + x['hello']; +} + + +// Generic Tree structure +type Tree = T & { + children?: Tree[]; +} + +class MyClass { + public static displayTree1>(tree: T) { + // error "Property 'children' does not exist on type 'T'" + tree.children; + } +} + //// [typeParameterExplicitlyExtendsAny.js] function fee() { @@ -19,6 +41,22 @@ function fee() { } function fee2() { var t; - t.blah; // Error + t.blah; // ok t.toString; // ok } +function f(x) { + x.children; + x(); + new x(); + x[100]; + x['hello']; +} +var MyClass = (function () { + function MyClass() { + } + MyClass.displayTree1 = function (tree) { + // error "Property 'children' does not exist on type 'T'" + tree.children; + }; + return MyClass; +}()); diff --git a/tests/cases/compiler/indexSignaturesInferentialTyping.ts b/tests/cases/compiler/indexSignaturesInferentialTyping.ts index e40f32a799b..b47293a77e5 100644 --- a/tests/cases/compiler/indexSignaturesInferentialTyping.ts +++ b/tests/cases/compiler/indexSignaturesInferentialTyping.ts @@ -2,6 +2,5 @@ function foo(items: { [index: number]: T }): T { return undefined; } function bar(items: { [index: string]: T }): T { return undefined; } var x1 = foo({ 0: 0, 1: 1 }); // type should be number -var x2 = foo({ zero: 0, one: 1 }); -var x3 = bar({ 0: 0, 1: 1 }); -var x4 = bar({ zero: 0, one: 1 }); // type should be number +var x2 = bar({ 0: 0, 1: 1 }); +var x3 = bar({ zero: 0, one: 1 }); // type should be number diff --git a/tests/cases/compiler/numericIndexerConstraint4.ts b/tests/cases/compiler/numericIndexerConstraint4.ts index abdfac0fc9c..7e890168558 100644 --- a/tests/cases/compiler/numericIndexerConstraint4.ts +++ b/tests/cases/compiler/numericIndexerConstraint4.ts @@ -8,4 +8,4 @@ class B extends A { var x: { [idx: number]: A; -} = { data: new B() } \ No newline at end of file +} = { 0: new B() } diff --git a/tests/cases/compiler/objectLitIndexerContextualType.ts b/tests/cases/compiler/objectLitIndexerContextualType.ts index 2b07d995183..b687e226cfc 100644 --- a/tests/cases/compiler/objectLitIndexerContextualType.ts +++ b/tests/cases/compiler/objectLitIndexerContextualType.ts @@ -15,8 +15,8 @@ x = { 0: t => t * t, // Should error }; y = { - s: t => t * t, // Should not error + s: t => t * t, // Should error }; y = { 0: t => t * t, // Should error -}; \ No newline at end of file +}; diff --git a/tests/cases/compiler/objectLiteralExcessProperties.ts b/tests/cases/compiler/objectLiteralExcessProperties.ts index 0aa81703c33..ca681b7b28e 100644 --- a/tests/cases/compiler/objectLiteralExcessProperties.ts +++ b/tests/cases/compiler/objectLiteralExcessProperties.ts @@ -19,3 +19,15 @@ var b5: Book & Cover = { foreward: "hi", color: "blue" }; var b6: Book & Cover = { foreword: "hi", color: "blue", price: 10.99 }; var b7: Book & number = { foreword: "hi", price: 10.99 }; + +var b8: Cover | Cover[] = { couleur : "non" }; + +var b9: Book | Book[] = { forewarned: "still no" }; + +interface Indexed { + [n: number]: Cover; +} + +var b10: Indexed = { 0: { }, '1': { } }; // ok + +var b11: Indexed = { 0: { colour: "blue" } }; // nested object literal still errors diff --git a/tests/cases/compiler/optionalParameterProperty.ts b/tests/cases/compiler/optionalParameterProperty.ts new file mode 100644 index 00000000000..1f547d4af26 --- /dev/null +++ b/tests/cases/compiler/optionalParameterProperty.ts @@ -0,0 +1,11 @@ +// @strictNullChecks: true + +class C { + p: number; +} + +class D extends C { + constructor(public p?: number) { + super(); + } +} diff --git a/tests/cases/compiler/optionalParamterAndVariableDeclaration.ts b/tests/cases/compiler/optionalParamterAndVariableDeclaration.ts new file mode 100644 index 00000000000..d9c1d407dca --- /dev/null +++ b/tests/cases/compiler/optionalParamterAndVariableDeclaration.ts @@ -0,0 +1,5 @@ +class C { + constructor(options?: number) { + var options = (options || 0); + } +} diff --git a/tests/cases/compiler/optionalParamterAndVariableDeclaration2.ts b/tests/cases/compiler/optionalParamterAndVariableDeclaration2.ts new file mode 100644 index 00000000000..7bdb0ab89c2 --- /dev/null +++ b/tests/cases/compiler/optionalParamterAndVariableDeclaration2.ts @@ -0,0 +1,7 @@ +// @strictNullChecks: true + +class C { + constructor(options?: number) { + var options = (options || 0); + } +} diff --git a/tests/cases/compiler/propertyParameterWithQuestionMark.ts b/tests/cases/compiler/propertyParameterWithQuestionMark.ts index 1a0eedb799e..ce2d88669c3 100644 --- a/tests/cases/compiler/propertyParameterWithQuestionMark.ts +++ b/tests/cases/compiler/propertyParameterWithQuestionMark.ts @@ -2,8 +2,8 @@ class C { constructor(public x?) { } } -// x should not be an optional property -var v: C = {}; // Should fail +// x should be an optional property +var v: C = {}; // Should succeed var v2: { x? } -v = v2; // Should fail -var v3: { x } = new C; // Should succeed \ No newline at end of file +v = v2; // Should succeed +var v3: { x } = new C; // Should fail \ No newline at end of file diff --git a/tests/cases/compiler/reachabilityCheckWithEmptyDefault.ts b/tests/cases/compiler/reachabilityCheckWithEmptyDefault.ts new file mode 100644 index 00000000000..6429528a0da --- /dev/null +++ b/tests/cases/compiler/reachabilityCheckWithEmptyDefault.ts @@ -0,0 +1,8 @@ +declare function print(s: string): void; +function foo(x: any) { + switch(x) { + case 1: return; + default: + } + print('1'); +} \ No newline at end of file diff --git a/tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts b/tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts index f004bf84c5e..1ff14373dcb 100644 --- a/tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts +++ b/tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts @@ -6,6 +6,27 @@ function fee() { function fee2() { var t: T; - t.blah; // Error + t.blah; // ok t.toString; // ok -} \ No newline at end of file +} + +function f(x: T) { + x.children; + x(); + new x(); + x[100]; + x['hello']; +} + + +// Generic Tree structure +type Tree = T & { + children?: Tree[]; +} + +class MyClass { + public static displayTree1>(tree: T) { + // error "Property 'children' does not exist on type 'T'" + tree.children; + } +} diff --git a/tests/cases/conformance/controlFlow/constLocalsInFunctionExpressions.ts b/tests/cases/conformance/controlFlow/constLocalsInFunctionExpressions.ts new file mode 100644 index 00000000000..69b19fcb307 --- /dev/null +++ b/tests/cases/conformance/controlFlow/constLocalsInFunctionExpressions.ts @@ -0,0 +1,38 @@ +declare function getStringOrNumber(): string | number; + +function f1() { + const x = getStringOrNumber(); + if (typeof x === "string") { + const f = () => x.length; + } +} + +function f2() { + const x = getStringOrNumber(); + if (typeof x !== "string") { + return; + } + const f = () => x.length; +} + +function f3() { + const x = getStringOrNumber(); + if (typeof x === "string") { + const f = function() { return x.length; }; + } +} + +function f4() { + const x = getStringOrNumber(); + if (typeof x !== "string") { + return; + } + const f = function() { return x.length; }; +} + +function f5() { + const x = getStringOrNumber(); + if (typeof x === "string") { + const f = () => () => x.length; + } +} \ No newline at end of file diff --git a/tests/cases/conformance/controlFlow/controlFlowIIFE.ts b/tests/cases/conformance/controlFlow/controlFlowIIFE.ts new file mode 100644 index 00000000000..c72f038c1ec --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowIIFE.ts @@ -0,0 +1,48 @@ +// @strictNullChecks: true + +declare function getStringOrNumber(): string | number; + +function f1() { + let x = getStringOrNumber(); + if (typeof x === "string") { + let n = function() { + return x.length; + }(); + } +} + +function f2() { + let x = getStringOrNumber(); + if (typeof x === "string") { + let n = (function() { + return x.length; + })(); + } +} + +function f3() { + let x = getStringOrNumber(); + let y: number; + if (typeof x === "string") { + let n = (z => x.length + y + z)(y = 1); + } +} + +// Repros from #8381 + +let maybeNumber: number | undefined; +(function () { + maybeNumber = 1; +})(); +maybeNumber++; +if (maybeNumber !== undefined) { + maybeNumber++; +} + +let test: string | undefined; +if (!test) { + throw new Error('Test is not defined'); +} +(() => { + test.slice(1); // No error +})(); \ No newline at end of file diff --git a/tests/cases/conformance/es6/computedProperties/computedPropertyNamesContextualType7_ES5.ts b/tests/cases/conformance/es6/computedProperties/computedPropertyNamesContextualType7_ES5.ts index 722891c2f6a..6d98092b968 100644 --- a/tests/cases/conformance/es6/computedProperties/computedPropertyNamesContextualType7_ES5.ts +++ b/tests/cases/conformance/es6/computedProperties/computedPropertyNamesContextualType7_ES5.ts @@ -1,14 +1,19 @@ // @target: es5 interface I { - [s: number]: T; + [n: number]: T; +} +interface J { + [s: string]: T; } -declare function foo(obj: I): T +declare function foo(obj: I): T; +declare function g(obj: J): T; foo({ - p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0] -}); \ No newline at end of file +}); + +g({ p: "" }); diff --git a/tests/cases/conformance/es6/computedProperties/computedPropertyNamesContextualType7_ES6.ts b/tests/cases/conformance/es6/computedProperties/computedPropertyNamesContextualType7_ES6.ts index 1ddb966488d..459ce1471b4 100644 --- a/tests/cases/conformance/es6/computedProperties/computedPropertyNamesContextualType7_ES6.ts +++ b/tests/cases/conformance/es6/computedProperties/computedPropertyNamesContextualType7_ES6.ts @@ -1,14 +1,19 @@ // @target: es6 interface I { - [s: number]: T; + [n: number]: T; +} +interface J { + [s: string]: T; } -declare function foo(obj: I): T +declare function foo(obj: I): T; +declare function g(obj: J): T; foo({ - p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0] -}); \ No newline at end of file +}); + +g({ p: "" }); diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardsInFunctionAndModuleBlock.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardsInFunctionAndModuleBlock.ts index 5dbc925d04b..f1ba854394b 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardsInFunctionAndModuleBlock.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardsInFunctionAndModuleBlock.ts @@ -40,7 +40,7 @@ function foo4(x: number | string | boolean) { : x.toString(); // number })(x); // x here is narrowed to number | boolean } -// Type guards affect nested function expressions and nested function declarations +// Type guards do not affect nested function declarations function foo5(x: number | string | boolean) { if (typeof x === "string") { var y = x; // string; diff --git a/tests/cases/conformance/types/typeRelationships/typeAndMemberIdentity/objectTypesIdentityWithNumericIndexers1.ts b/tests/cases/conformance/types/typeRelationships/typeAndMemberIdentity/objectTypesIdentityWithNumericIndexers1.ts index 7092fab6c31..867199d9051 100644 --- a/tests/cases/conformance/types/typeRelationships/typeAndMemberIdentity/objectTypesIdentityWithNumericIndexers1.ts +++ b/tests/cases/conformance/types/typeRelationships/typeAndMemberIdentity/objectTypesIdentityWithNumericIndexers1.ts @@ -25,7 +25,7 @@ class PB extends B { var a: { [x: number]: string; } -var b: { [x: number]: string; } = { foo: '' }; +var b: { [x: number]: string; } = { 0: '' }; function foo1(x: A); function foo1(x: A); // error diff --git a/tests/cases/conformance/types/typeRelationships/typeAndMemberIdentity/objectTypesIdentityWithNumericIndexers2.ts b/tests/cases/conformance/types/typeRelationships/typeAndMemberIdentity/objectTypesIdentityWithNumericIndexers2.ts index b5c0f4c1615..ea9d7d04ee2 100644 --- a/tests/cases/conformance/types/typeRelationships/typeAndMemberIdentity/objectTypesIdentityWithNumericIndexers2.ts +++ b/tests/cases/conformance/types/typeRelationships/typeAndMemberIdentity/objectTypesIdentityWithNumericIndexers2.ts @@ -28,7 +28,7 @@ class PB extends B { var a: { [x: number]: Base; } -var b: { [x: number]: Derived; } = { foo: null }; +var b: { [x: number]: Derived; } = { 0: null }; function foo1(x: A); function foo1(x: A); // error diff --git a/tests/cases/conformance/types/typeRelationships/typeAndMemberIdentity/objectTypesIdentityWithNumericIndexers3.ts b/tests/cases/conformance/types/typeRelationships/typeAndMemberIdentity/objectTypesIdentityWithNumericIndexers3.ts index ae64acedcec..d3f22604c44 100644 --- a/tests/cases/conformance/types/typeRelationships/typeAndMemberIdentity/objectTypesIdentityWithNumericIndexers3.ts +++ b/tests/cases/conformance/types/typeRelationships/typeAndMemberIdentity/objectTypesIdentityWithNumericIndexers3.ts @@ -25,7 +25,7 @@ class PB extends B { var a: { [x: string]: string; } -var b: { [x: number]: string; } = { foo: '' }; +var b: { [x: number]: string; } = { 0: '' }; function foo1(x: A); function foo1(x: A); // error diff --git a/tests/cases/fourslash/deleteClassWithEnumPresent.ts b/tests/cases/fourslash/deleteClassWithEnumPresent.ts index 29f7c61e259..17d2adae0b1 100644 --- a/tests/cases/fourslash/deleteClassWithEnumPresent.ts +++ b/tests/cases/fourslash/deleteClassWithEnumPresent.ts @@ -5,4 +5,34 @@ goTo.marker(); edit.deleteAtCaret('class Bar { }'.length); -verify.navigationBarContains('Foo', 'enum', 'tests/cases/fourslash/deleteClassWithEnumPresent.ts', ''); \ No newline at end of file +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "Foo", + "kind": "enum" + } + ] + }, + { + "text": "Foo", + "kind": "enum", + "childItems": [ + { + "text": "a", + "kind": "property" + }, + { + "text": "b", + "kind": "property" + }, + { + "text": "c", + "kind": "property" + } + ], + "indent": 1 + } +]); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 08883f163f2..71e1c3cc5d7 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -175,9 +175,7 @@ declare namespace FourSlashInterface { DocCommentTemplate(expectedText: string, expectedOffset: number, empty?: boolean): void; noDocCommentTemplate(): void; - navigationBarCount(count: number): void; - navigationBarContains(name: string, kind: string, fileName?: string, parentName?: string, isAdditionalSpan?: boolean, markerPosition?: number): void; - navigationBarChildItem(parent: string, text: string, kind: string): void; + navigationBar(json: any): void; navigationItemsListCount(count: number, searchValue: string, matchKind?: string): void; navigationItemsListContains(name: string, kind: string, searchValue: string, matchKind: string, fileName?: string, parentName?: string): void; occurrencesAtPositionContains(range: Range, isWriteAccess?: boolean): void; @@ -248,6 +246,7 @@ declare namespace FourSlashInterface { copyFormatOptions(): FormatCodeOptions; setFormatOptions(options: FormatCodeOptions): any; selection(startMarker: string, endMarker: string): void; + onType(posMarker: string, key: string): void; setOption(name: string, value: number): any; setOption(name: string, value: string): any; setOption(name: string, value: boolean): any; diff --git a/tests/cases/fourslash/getNavigationBarItems.ts b/tests/cases/fourslash/getNavigationBarItems.ts index 8e9b8de5b05..c3b519fe114 100644 --- a/tests/cases/fourslash/getNavigationBarItems.ts +++ b/tests/cases/fourslash/getNavigationBarItems.ts @@ -5,7 +5,30 @@ //// ["bar"]: string; ////} -verify.navigationBarCount(3); -verify.navigationBarContains("C", "class"); -verify.navigationBarChildItem("C", "[\"bar\"]", "property"); -verify.navigationBarChildItem("C", "foo", "property"); +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "C", + "kind": "class" + } + ] + }, + { + "text": "C", + "kind": "class", + "childItems": [ + { + "text": "[\"bar\"]", + "kind": "property" + }, + { + "text": "foo", + "kind": "property" + } + ], + "indent": 1 + } +]) diff --git a/tests/cases/fourslash/navbar_const.ts b/tests/cases/fourslash/navbar_const.ts index 5d8b42607c8..6ec594a2873 100644 --- a/tests/cases/fourslash/navbar_const.ts +++ b/tests/cases/fourslash/navbar_const.ts @@ -1,13 +1,16 @@ /// -//// {| "itemName": "c", "kind": "const", "parentName": "" |}const c = 0; +//// const c = 0; -test.markers().forEach(marker => { - verify.navigationBarContains( - marker.data.itemName, - marker.data.kind, - marker.fileName, - marker.data.parentName, - marker.data.isAdditionalRange, - marker.position); -}); \ No newline at end of file +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "c", + "kind": "const" + } + ] + } +]); diff --git a/tests/cases/fourslash/navbar_contains-no-duplicates.ts b/tests/cases/fourslash/navbar_contains-no-duplicates.ts index ec86e4b2f20..e259a7bef90 100644 --- a/tests/cases/fourslash/navbar_contains-no-duplicates.ts +++ b/tests/cases/fourslash/navbar_contains-no-duplicates.ts @@ -1,41 +1,141 @@ /// -//// {| "itemName": "Windows", "kind": "module", "parentName": "" |}declare module Windows { -//// {| "itemName": "Foundation", "kind": "module", "parentName": "" |}export module Foundation { -//// export var {| "itemName": "A", "kind": "var" |}A; -//// {| "itemName": "Test", "kind": "class" |}export class Test { -//// {| "itemName": "wow", "kind": "method" |}public wow(); +//// declare module Windows { +//// export module Foundation { +//// export var A; +//// export class Test { +//// public wow(); //// } //// } //// } //// -//// {| "itemName": "Windows", "kind": "module", "parentName": "", "isAdditionalRange": true |}declare module Windows { -//// {| "itemName": "Foundation", "kind": "module", "parentName": "", "isAdditionalRange": true |}export module Foundation { -//// export var {| "itemName": "B", "kind": "var" |}B; -//// {| "itemName": "Test", "kind": "module" |}export module Test { -//// {| "itemName": "Boom", "kind": "function" |}export function Boom(): number; +//// declare module Windows { +//// export module Foundation { +//// export var B; +//// export module Test { +//// export function Boom(): number; //// } //// } //// } //// -//// {| "itemName": "ABC", "kind": "class", "parentName": "" |}class ABC { -//// {| "itemName": "foo", "kind": "method" |}public foo() { +//// class ABC { +//// public foo() { //// return 3; //// } //// } //// -//// {| "itemName": "ABC", "kind": "module", "parentName": "" |}module ABC { -//// export var {| "itemName": "x", "kind": "var" |}x = 3; +//// module ABC { +//// export var x = 3; //// } -test.markers().forEach(marker => { - if (marker.data) { - verify.navigationBarContains( - marker.data.itemName, - marker.data.kind, - marker.fileName, - marker.data.parentName, - marker.data.isAdditionalRange, - marker.position); +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "ABC", + "kind": "class" + }, + { + "text": "ABC", + "kind": "module" + }, + { + "text": "Windows", + "kind": "module", + "kindModifiers": "declare" + } + ] + }, + { + "text": "ABC", + "kind": "class", + "childItems": [ + { + "text": "foo", + "kind": "method", + "kindModifiers": "public" + } + ], + "indent": 1 + }, + { + "text": "ABC", + "kind": "module", + "childItems": [ + { + "text": "x", + "kind": "var", + "kindModifiers": "export" + } + ], + "indent": 1 + }, + { + "text": "Windows", + "kind": "module", + "kindModifiers": "declare", + "childItems": [ + { + "text": "Foundation", + "kind": "module", + "kindModifiers": "export,declare" + } + ], + "indent": 1 + }, + { + "text": "Foundation", + "kind": "module", + "kindModifiers": "export,declare", + "childItems": [ + { + "text": "A", + "kind": "var", + "kindModifiers": "export,declare" + }, + { + "text": "Test", + "kind": "class", + "kindModifiers": "export,declare" + }, + { + "text": "B", + "kind": "var", + "kindModifiers": "export,declare" + }, + { + "text": "Test", + "kind": "module", + "kindModifiers": "export,declare" + } + ], + "indent": 2 + }, + { + "text": "Test", + "kind": "class", + "kindModifiers": "export,declare", + "childItems": [ + { + "text": "wow", + "kind": "method", + "kindModifiers": "public,declare" + } + ], + "indent": 3 + }, + { + "text": "Test", + "kind": "module", + "kindModifiers": "export,declare", + "childItems": [ + { + "text": "Boom", + "kind": "function", + "kindModifiers": "export,declare" + } + ], + "indent": 3 } -}); -verify.navigationBarCount(12); \ No newline at end of file +]); diff --git a/tests/cases/fourslash/navbar_exportDefault.ts b/tests/cases/fourslash/navbar_exportDefault.ts index a56eeb8b226..dc99cff7d64 100644 --- a/tests/cases/fourslash/navbar_exportDefault.ts +++ b/tests/cases/fourslash/navbar_exportDefault.ts @@ -1,24 +1,83 @@ /// // @Filename: a.ts -//// {| "itemName": "default", "kind": "class", "parentName": "" |}export default class { } +////export default class { } // @Filename: b.ts -//// {| "itemName": "C", "kind": "class", "parentName": "" |}export default class C { } +////export default class C { } // @Filename: c.ts -//// {| "itemName": "default", "kind": "function", "parentName": "" |}export default function { } +////export default function { } // @Filename: d.ts -//// {| "itemName": "Func", "kind": "function", "parentName": "" |}export default function Func { } +////export default function Func { } -test.markers().forEach(marker => { - goTo.file(marker.fileName); - verify.navigationBarContains( - marker.data.itemName, - marker.data.kind, - marker.fileName, - marker.data.parentName, - marker.data.isAdditionalRange, - marker.position); -}); \ No newline at end of file +goTo.file("a.ts"); +verify.navigationBar([ + { + "text": "\"a\"", + "kind": "module" + }, + { + "text": "default", + "kind": "class", + "kindModifiers": "export", + "indent": 1 + } +]); + +goTo.file("b.ts"); +verify.navigationBar([ + { + "text": "\"b\"", + "kind": "module", + "childItems": [ + { + "text": "C", + "kind": "class", + "kindModifiers": "export" + } + ] + }, + { + "text": "C", + "kind": "class", + "kindModifiers": "export", + "indent": 1 + } +]); + +goTo.file("c.ts"); +verify.navigationBar([ + { + "text": "\"c\"", + "kind": "module", + }, + { + "text": "default", + "kind": "function", + "kindModifiers": "export", + "indent": 1 + } +]); + +goTo.file("d.ts"); +verify.navigationBar([ + { + "text": "\"d\"", + "kind": "module", + "childItems": [ + { + "text": "Func", + "kind": "function", + "kindModifiers": "export" + } + ] + }, + { + "text": "Func", + "kind": "function", + "kindModifiers": "export", + "indent": 1 + } +]); diff --git a/tests/cases/fourslash/navbar_let.ts b/tests/cases/fourslash/navbar_let.ts index c3b125526ef..7ccd61cdfd6 100644 --- a/tests/cases/fourslash/navbar_let.ts +++ b/tests/cases/fourslash/navbar_let.ts @@ -1,13 +1,16 @@ /// -//// {| "itemName": "c", "kind": "let", "parentName": "" |}let c = 0; +////let c = 0; -test.markers().forEach(marker => { - verify.navigationBarContains( - marker.data.itemName, - marker.data.kind, - marker.fileName, - marker.data.parentName, - marker.data.isAdditionalRange, - marker.position); -}); \ No newline at end of file +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "c", + "kind": "let" + } + ] + } +]); diff --git a/tests/cases/fourslash/navigationBarItemsBindingPatterns.ts b/tests/cases/fourslash/navigationBarItemsBindingPatterns.ts index afac15daacc..849f918f473 100644 --- a/tests/cases/fourslash/navigationBarItemsBindingPatterns.ts +++ b/tests/cases/fourslash/navigationBarItemsBindingPatterns.ts @@ -6,16 +6,55 @@ ////const bar1, [c, d] ////var {e, x: [f, g]} = {a:1, x:[]}; -verify.navigationBarCount(12); // global (1) + variable declarations (4) + binding patterns (7) -verify.navigationBarContains("foo", "var"); -verify.navigationBarContains("bar", "var"); -verify.navigationBarContains("foo1", "let") -verify.navigationBarContains("a", "let"); -verify.navigationBarContains("b", "let"); -verify.navigationBarContains("bar1", "const"); -verify.navigationBarContains("c", "const"); -verify.navigationBarContains("d", "const"); -verify.navigationBarContains("e", "var"); -verify.navigationBarContains("f", "var"); -verify.navigationBarContains("g", "var"); - +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "a", + "kind": "let" + }, + { + "text": "b", + "kind": "let" + }, + { + "text": "bar", + "kind": "var" + }, + { + "text": "bar1", + "kind": "const" + }, + { + "text": "c", + "kind": "const" + }, + { + "text": "d", + "kind": "const" + }, + { + "text": "e", + "kind": "var" + }, + { + "text": "f", + "kind": "var" + }, + { + "text": "foo", + "kind": "var" + }, + { + "text": "foo1", + "kind": "let" + }, + { + "text": "g", + "kind": "var" + } + ] + } +]); diff --git a/tests/cases/fourslash/navigationBarItemsBindingPatternsInConstructor.ts b/tests/cases/fourslash/navigationBarItemsBindingPatternsInConstructor.ts index 84c1d09efe7..0ae3e692aa1 100644 --- a/tests/cases/fourslash/navigationBarItemsBindingPatternsInConstructor.ts +++ b/tests/cases/fourslash/navigationBarItemsBindingPatternsInConstructor.ts @@ -11,4 +11,49 @@ //// } ////} -verify.navigationBarCount(6); // 2x(class + field + constructor) +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "A", + "kind": "class" + }, + { + "text": "B", + "kind": "class" + } + ] + }, + { + "text": "A", + "kind": "class", + "childItems": [ + { + "text": "constructor", + "kind": "constructor" + }, + { + "text": "x", + "kind": "property" + } + ], + "indent": 1 + }, + { + "text": "B", + "kind": "class", + "childItems": [ + { + "text": "constructor", + "kind": "constructor" + }, + { + "text": "x", + "kind": "property" + } + ], + "indent": 1 + } +]); diff --git a/tests/cases/fourslash/navigationBarItemsEmptyConstructors.ts b/tests/cases/fourslash/navigationBarItemsEmptyConstructors.ts index 2255d29e293..fd534f4c6db 100644 --- a/tests/cases/fourslash/navigationBarItemsEmptyConstructors.ts +++ b/tests/cases/fourslash/navigationBarItemsEmptyConstructors.ts @@ -5,8 +5,26 @@ //// } ////} -verify.navigationBarContains("Test", "class"); -verify.navigationBarContains("constructor", "constructor"); - -// no other items -verify.navigationBarCount(2); \ No newline at end of file +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "Test", + "kind": "class" + } + ] + }, + { + "text": "Test", + "kind": "class", + "childItems": [ + { + "text": "constructor", + "kind": "constructor" + } + ], + "indent": 1 + } +]); diff --git a/tests/cases/fourslash/navigationBarItemsExports.ts b/tests/cases/fourslash/navigationBarItemsExports.ts index b88b60d0efb..3ec9b0a7138 100644 --- a/tests/cases/fourslash/navigationBarItemsExports.ts +++ b/tests/cases/fourslash/navigationBarItemsExports.ts @@ -1,18 +1,32 @@ /// -////export { {| "itemName": "a", "kind": "alias", "parentName": "" |}a } from "a"; +////export { a } from "a"; //// -////export { {| "itemName": "B", "kind": "alias", "parentName": "" |}b as B } from "a" +////export { b as B } from "a" //// -////{| "itemName": "e", "kind": "alias", "parentName": "" |} export import e = require("a"); +////export import e = require("a"); //// ////export * from "a"; // no bindings here -test.markers().forEach((marker) => { - if (marker.data) { - verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); +verify.navigationBar([ + { + "text": "\"navigationBarItemsExports\"", + "kind": "module", + "childItems": [ + { + "text": "a", + "kind": "alias" + }, + { + "text": "B", + "kind": "alias" + }, + { + "text": "e", + "kind": "alias", + "kindModifiers": "export" + } + ] } -}); - -verify.navigationBarCount(4); +]); diff --git a/tests/cases/fourslash/navigationBarItemsFunctions.ts b/tests/cases/fourslash/navigationBarItemsFunctions.ts index 0948923c046..91546462a25 100644 --- a/tests/cases/fourslash/navigationBarItemsFunctions.ts +++ b/tests/cases/fourslash/navigationBarItemsFunctions.ts @@ -1,23 +1,59 @@ /// -////{| "itemName": "", "kind": "module" |} -//// -////{| "itemName": "foo", "kind": "function" |}function foo() { +////function foo() { //// var x = 10; -//// {| "itemName": "bar", "kind": "function", "parentName": "foo" |}function bar() { +//// function bar() { //// var y = 10; -//// {| "itemName": "biz", "kind": "function", "parentName": "bar" |}function biz() { +//// function biz() { //// var z = 10; //// } //// } ////} //// -////{| "itemName": "baz", "kind": "function", "parentName": "" |}function baz() { +////function baz() { //// var v = 10; ////} -test.markers().forEach((marker) => { - verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); -}); - -verify.navigationBarCount(8); // 4 functions + global. Note: there are 8 because of the functions show up at the top level and as child items. +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "baz", + "kind": "function" + }, + { + "text": "foo", + "kind": "function" + } + ] + }, + { + "text": "baz", + "kind": "function", + "indent": 1 + }, + { + "text": "foo", + "kind": "function", + "childItems": [ + { + "text": "bar", + "kind": "function" + } + ], + "indent": 1 + }, + { + "text": "bar", + "kind": "function", + "childItems": [ + { + "text": "biz", + "kind": "function" + } + ], + "indent": 2 + } +]); diff --git a/tests/cases/fourslash/navigationBarItemsFunctionsBroken.ts b/tests/cases/fourslash/navigationBarItemsFunctionsBroken.ts index e8bf1d33fc3..96dcbb944ae 100644 --- a/tests/cases/fourslash/navigationBarItemsFunctionsBroken.ts +++ b/tests/cases/fourslash/navigationBarItemsFunctionsBroken.ts @@ -1,12 +1,23 @@ /// -////{| "itemName": "f", "kind": "function" |} ////function f() { //// function; ////} -test.markers().forEach((marker) => { - verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); -}); - -verify.navigationBarCount(3); // and 'f'. \ No newline at end of file +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "f", + "kind": "function" + } + ] + }, + { + "text": "f", + "kind": "function", + "indent": 1 + } +]); diff --git a/tests/cases/fourslash/navigationBarItemsFunctionsBroken2.ts b/tests/cases/fourslash/navigationBarItemsFunctionsBroken2.ts index 9576d4dd789..127bde8c9e7 100644 --- a/tests/cases/fourslash/navigationBarItemsFunctionsBroken2.ts +++ b/tests/cases/fourslash/navigationBarItemsFunctionsBroken2.ts @@ -1,13 +1,24 @@ /// ////function; -////{| "itemName": "f", "kind": "function" |} ////function f() { //// function; ////} -test.markers().forEach((marker) => { - verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); -}); - -verify.navigationBarCount(3); // and 'f' \ No newline at end of file +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "f", + "kind": "function" + } + ] + }, + { + "text": "f", + "kind": "function", + "indent": 1 + } +]); diff --git a/tests/cases/fourslash/navigationBarItemsImports.ts b/tests/cases/fourslash/navigationBarItemsImports.ts index 53619da310a..ed398ec7f1d 100644 --- a/tests/cases/fourslash/navigationBarItemsImports.ts +++ b/tests/cases/fourslash/navigationBarItemsImports.ts @@ -1,25 +1,56 @@ /// -////import {| "itemName": "d1", "kind": "alias", "parentName": "" |}d1 from "a"; +////import d1 from "a"; //// -////import { {| "itemName": "a", "kind": "alias", "parentName": "" |}a } from "a"; +////import { a } from "a"; //// -////import { {| "itemName": "B", "kind": "alias", "parentName": "" |}b as B } from "a" +////import { b as B } from "a" //// -////import {| "itemName": "d2", "kind": "alias", "parentName": "" |}d2, -//// { {| "itemName": "c", "kind": "alias", "parentName": "" |}c, -//// {| "itemName": "D", "kind": "alias", "parentName": "" |} d as D } from "a" +////import d2, { c, d as D } from "a" //// -////{| "itemName": "e", "kind": "alias", "parentName": "" |}import e = require("a"); +////import e = require("a"); //// -////import {| "itemName": "ns", "kind": "alias", "parentName": "" |}* as ns from "a"; +////import * as ns from "a"; -test.markers().forEach((marker) => { - if (marker.data) { - verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); +verify.navigationBar([ + { + "text": "\"navigationBarItemsImports\"", + "kind": "module", + "childItems": [ + { + "text": "a", + "kind": "alias" + }, + { + "text": "B", + "kind": "alias" + }, + { + "text": "c", + "kind": "alias" + }, + { + "text": "D", + "kind": "alias" + }, + { + "text": "d1", + "kind": "alias" + }, + { + "text": "d2", + "kind": "alias" + }, + { + "text": "e", + "kind": "alias" + }, + { + "text": "ns", + "kind": "alias" + } + ] } -}); - -verify.navigationBarCount(9); +]); diff --git a/tests/cases/fourslash/navigationBarItemsInsideMethodsAndConstructors.ts b/tests/cases/fourslash/navigationBarItemsInsideMethodsAndConstructors.ts index d6fb0a91eb2..28ec25c6f1d 100644 --- a/tests/cases/fourslash/navigationBarItemsInsideMethodsAndConstructors.ts +++ b/tests/cases/fourslash/navigationBarItemsInsideMethodsAndConstructors.ts @@ -2,41 +2,136 @@ ////class Class { //// constructor() { -//// {| "itemName": "LocalFunctionInConstructor", "kind": "function", "parentName": "constructor"|}function LocalFunctionInConstructor() { -//// -//// } -//// -//// {| "itemName": "LocalInterfaceInConstrcutor", "kind": "interface", "parentName": "constructor"|}interface LocalInterfaceInConstrcutor { -//// } -//// -//// {| "itemName": "LocalEnumInConstructor", "kind": "enum", "parentName": "constructor"|}enum LocalEnumInConstructor { -//// {| "itemName": "LocalEnumMemberInConstructor", "kind": "property", "parentName": "LocalEnumInConstructor"|}LocalEnumMemberInConstructor, -//// } +//// function LocalFunctionInConstructor() {} +//// interface LocalInterfaceInConstrcutor {} +//// enum LocalEnumInConstructor { LocalEnumMemberInConstructor } //// } //// //// method() { -//// {| "itemName": "LocalFunctionInMethod", "kind": "function", "parentName": "method"|}function LocalFunctionInMethod() { -//// {| "itemName": "LocalFunctionInLocalFunctionInMethod", "kind": "function", "parentName": "LocalFunctionInMethod"|}function LocalFunctionInLocalFunctionInMethod() { -//// -//// } -//// } -//// -//// {| "itemName": "LocalInterfaceInMethod", "kind": "interface", "parentName": "method"|}interface LocalInterfaceInMethod { -//// } -//// -//// {| "itemName": "LocalEnumInMethod", "kind": "enum", "parentName": "method"|}enum LocalEnumInMethod { -//// {| "itemName": "LocalEnumMemberInMethod", "kind": "property", "parentName": "LocalEnumInMethod"|}LocalEnumMemberInMethod, +//// function LocalFunctionInMethod() { +//// function LocalFunctionInLocalFunctionInMethod() {} //// } +//// interface LocalInterfaceInMethod {} +//// enum LocalEnumInMethod { LocalEnumMemberInMethod } //// } //// -//// emptyMethod() { // Non child functions method should not be duplicated -//// -//// } +//// emptyMethod() { } // Non child functions method should not be duplicated ////} -test.markers().forEach((marker) => { - verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); -}); - -// no other items -verify.navigationBarCount(21); +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "Class", + "kind": "class" + } + ] + }, + { + "text": "Class", + "kind": "class", + "childItems": [ + { + "text": "constructor", + "kind": "constructor" + }, + { + "text": "emptyMethod", + "kind": "method" + }, + { + "text": "method", + "kind": "method" + } + ], + "indent": 1 + }, + { + "text": "constructor", + "kind": "constructor", + "childItems": [ + { + "text": "LocalEnumInConstructor", + "kind": "enum" + }, + { + "text": "LocalFunctionInConstructor", + "kind": "function" + }, + { + "text": "LocalInterfaceInConstrcutor", + "kind": "interface" + } + ], + "indent": 2 + }, + { + "text": "LocalEnumInConstructor", + "kind": "enum", + "childItems": [ + { + "text": "LocalEnumMemberInConstructor", + "kind": "property" + } + ], + "indent": 2 + }, + { + "text": "LocalFunctionInConstructor", + "kind": "function", + "indent": 2 + }, + { + "text": "LocalInterfaceInConstrcutor", + "kind": "interface", + "indent": 2 + }, + { + "text": "method", + "kind": "method", + "childItems": [ + { + "text": "LocalEnumInMethod", + "kind": "enum" + }, + { + "text": "LocalFunctionInMethod", + "kind": "function" + }, + { + "text": "LocalInterfaceInMethod", + "kind": "interface" + } + ], + "indent": 2 + }, + { + "text": "LocalEnumInMethod", + "kind": "enum", + "childItems": [ + { + "text": "LocalEnumMemberInMethod", + "kind": "property" + } + ], + "indent": 2 + }, + { + "text": "LocalFunctionInMethod", + "kind": "function", + "childItems": [ + { + "text": "LocalFunctionInLocalFunctionInMethod", + "kind": "function" + } + ], + "indent": 2 + }, + { + "text": "LocalInterfaceInMethod", + "kind": "interface", + "indent": 2 + } +]); diff --git a/tests/cases/fourslash/navigationBarItemsItems.ts b/tests/cases/fourslash/navigationBarItemsItems.ts index d9ae3d35dff..87da8581734 100644 --- a/tests/cases/fourslash/navigationBarItemsItems.ts +++ b/tests/cases/fourslash/navigationBarItemsItems.ts @@ -1,52 +1,171 @@ /// ////// Interface -////{| "itemName": "IPoint", "kind": "interface", "parentName": "" |}interface IPoint { -//// {| "itemName": "getDist", "kind": "method", "parentName": "IPoint" |}getDist(): number; -//// {| "itemName": "new()", "kind": "construct", "parentName": "IPoint" |}new(): IPoint; -//// {| "itemName": "()", "kind": "call", "parentName": "IPoint" |}(): any; -//// {| "itemName": "[]", "kind": "index", "parentName": "IPoint" |}[x:string]: number; -//// {| "itemName": "prop", "kind": "property", "parentName": "IPoint" |}prop: string; +////interface IPoint { +//// getDist(): number; +//// new(): IPoint; +//// (): any; +//// [x:string]: number; +//// prop: string; ////} //// /////// Module -////{| "itemName": "Shapes", "kind": "module", "parentName": "" |}module Shapes { +////module Shapes { //// //// // Class -//// {| "itemName": "Point", "kind": "class", "parentName": "" |}export class Point implements IPoint { -//// {| "itemName": "constructor", "kind": "constructor", "parentName": "Point" |}constructor (public x: number, public y: number) { } +//// export class Point implements IPoint { +//// constructor (public x: number, public y: number) { } //// //// // Instance member -//// {| "itemName": "getDist", "kind": "method", "parentName": "Point" |}getDist() { return Math.sqrt(this.x * this.x + this.y * this.y); } +//// getDist() { return Math.sqrt(this.x * this.x + this.y * this.y); } //// //// // Getter -//// {| "itemName": "value", "kind": "getter", "parentName": "Point" |}get value(): number { return 0; } +//// get value(): number { return 0; } //// //// // Setter -//// {| "itemName": "value", "kind": "setter", "parentName": "Point" |}set value(newValue: number) { return; } +//// set value(newValue: number) { return; } //// //// // Static member -//// {| "itemName": "origin", "kind": "property", "parentName": "Point" |}static origin = new Point(0, 0); +//// static origin = new Point(0, 0); //// //// // Static method -//// {| "itemName": "getOrigin", "kind": "method", "parentName": "Point" |}private static getOrigin() { return Point.origin;} +//// private static getOrigin() { return Point.origin; } //// } //// -//// {| "itemName": "Values", "kind": "enum", "parentName": "Shapes" |}enum Values { -//// value1, -//// {| "itemName": "value2", "kind": "property", "parentName": "Values" |}value2, -//// value3, -//// } +//// enum Values { value1, value2, value3 } ////} //// ////// Local variables -////{| "itemName": "p", "kind": "var", "parentName": "" |}var p: IPoint = new Shapes.Point(3, 4); -////{| "itemName": "dist", "kind": "var", "parentName": "" |}var dist = p.getDist(); +////var p: IPoint = new Shapes.Point(3, 4); +////var dist = p.getDist(); -test.markers().forEach((marker) => { - if (marker.data) { - verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "dist", + "kind": "var" + }, + { + "text": "IPoint", + "kind": "interface" + }, + { + "text": "p", + "kind": "var" + }, + { + "text": "Shapes", + "kind": "module" + } + ] + }, + { + "text": "IPoint", + "kind": "interface", + "childItems": [ + { + "text": "()", + "kind": "call" + }, + { + "text": "new()", + "kind": "construct" + }, + { + "text": "[]", + "kind": "index" + }, + { + "text": "getDist", + "kind": "method" + }, + { + "text": "prop", + "kind": "property" + } + ], + "indent": 1 + }, + { + "text": "Shapes", + "kind": "module", + "childItems": [ + { + "text": "Point", + "kind": "class", + "kindModifiers": "export" + }, + { + "text": "Values", + "kind": "enum" + } + ], + "indent": 1 + }, + { + "text": "Point", + "kind": "class", + "kindModifiers": "export", + "childItems": [ + { + "text": "constructor", + "kind": "constructor" + }, + { + "text": "getDist", + "kind": "method" + }, + { + "text": "getOrigin", + "kind": "method", + "kindModifiers": "private,static" + }, + { + "text": "origin", + "kind": "property", + "kindModifiers": "static" + }, + { + "text": "value", + "kind": "getter" + }, + { + "text": "value", + "kind": "setter" + }, + { + "text": "x", + "kind": "property", + "kindModifiers": "public" + }, + { + "text": "y", + "kind": "property", + "kindModifiers": "public" + } + ], + "indent": 2 + }, + { + "text": "Values", + "kind": "enum", + "childItems": [ + { + "text": "value1", + "kind": "property" + }, + { + "text": "value2", + "kind": "property" + }, + { + "text": "value3", + "kind": "property" + } + ], + "indent": 2 } -}); - -verify.navigationBarCount(25); +]); diff --git a/tests/cases/fourslash/navigationBarItemsItems2.ts b/tests/cases/fourslash/navigationBarItemsItems2.ts index d4ffde54051..762531d8778 100644 --- a/tests/cases/fourslash/navigationBarItemsItems2.ts +++ b/tests/cases/fourslash/navigationBarItemsItems2.ts @@ -1,6 +1,5 @@ /// - /////**/ goTo.marker(); @@ -8,5 +7,26 @@ edit.insertLine("module A"); edit.insert("export class "); // should not crash -verify.navigationBarCount(2); - +verify.navigationBar([ + { + "text": "\"navigationBarItemsItems2\"", + "kind": "module", + "childItems": [ + { + "text": "A", + "kind": "module" + } + ] + }, + { + "text": "default", + "kind": "class", + "kindModifiers": "export", + "indent": 1 + }, + { + "text": "A", + "kind": "module", + "indent": 1 + } +]); diff --git a/tests/cases/fourslash/navigationBarItemsItemsContainsNoAnonymousFunctions.ts b/tests/cases/fourslash/navigationBarItemsItemsContainsNoAnonymousFunctions.ts index dac6e96ab93..276e19624c9 100644 --- a/tests/cases/fourslash/navigationBarItemsItemsContainsNoAnonymousFunctions.ts +++ b/tests/cases/fourslash/navigationBarItemsItemsContainsNoAnonymousFunctions.ts @@ -30,15 +30,51 @@ ////} goTo.marker("file1"); -verify.navigationBarCount(0); +verify.navigationBar([ + { + "text": "", + "kind": "module" + } +]); goTo.marker("file2"); -verify.navigationBarContains("", "module"); -verify.navigationBarContains("x", "var"); -verify.navigationBarCount(2); +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "x", + "kind": "var" + } + ] + } +]); goTo.marker("file3"); -verify.navigationBarContains("", "module"); -verify.navigationBarContains("foo", "function"); -verify.navigationBarContains("bar", "function"); -verify.navigationBarCount(5); \ No newline at end of file +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "bar", + "kind": "function" + }, + { + "text": "foo", + "kind": "function" + } + ] + }, + { + "text": "bar", + "kind": "function", + "indent": 1 + }, + { + "text": "foo", + "kind": "function", + "indent": 1 + } +]); diff --git a/tests/cases/fourslash/navigationBarItemsItemsExternalModules.ts b/tests/cases/fourslash/navigationBarItemsItemsExternalModules.ts index 64a595cafb1..04091185dd0 100644 --- a/tests/cases/fourslash/navigationBarItemsItemsExternalModules.ts +++ b/tests/cases/fourslash/navigationBarItemsItemsExternalModules.ts @@ -1,11 +1,32 @@ /// -////{| "itemName": "Bar", "kind": "class" |}export class Bar { -//// {| "itemName": "s", "kind": "property", "parentName": "Bar" |}public s: string; +////export class Bar { +//// public s: string; ////} -test.markers().forEach((marker) => { - verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); -}); - -verify.navigationBarCount(2); // external module node + class + property +verify.navigationBar([ + { + "text": "\"navigationBarItemsItemsExternalModules\"", + "kind": "module", + "childItems": [ + { + "text": "Bar", + "kind": "class", + "kindModifiers": "export" + } + ] + }, + { + "text": "Bar", + "kind": "class", + "kindModifiers": "export", + "childItems": [ + { + "text": "s", + "kind": "property", + "kindModifiers": "public" + } + ], + "indent": 1 + } +]); diff --git a/tests/cases/fourslash/navigationBarItemsItemsExternalModules2.ts b/tests/cases/fourslash/navigationBarItemsItemsExternalModules2.ts index 7c1c32cff76..4939091d944 100644 --- a/tests/cases/fourslash/navigationBarItemsItemsExternalModules2.ts +++ b/tests/cases/fourslash/navigationBarItemsItemsExternalModules2.ts @@ -1,15 +1,39 @@ /// // @Filename: test/file.ts -////{| "itemName": "Bar", "kind": "class" |}export class Bar { -//// {| "itemName": "s", "kind": "property", "parentName": "Bar" |}public s: string; +////export class Bar { +//// public s: string; ////} -////{| "itemName": "\"file\"", "kind": "module" |} -////{| "itemName": "x", "kind": "var", "parentName": "\"file\"" |} ////export var x: number; -test.markers().forEach((marker) => { - verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); -}); - -verify.navigationBarCount(4); // external module node + variable in module + class + property +verify.navigationBar([ + { + "text": "\"file\"", + "kind": "module", + "childItems": [ + { + "text": "Bar", + "kind": "class", + "kindModifiers": "export" + }, + { + "text": "x", + "kind": "var", + "kindModifiers": "export" + } + ] + }, + { + "text": "Bar", + "kind": "class", + "kindModifiers": "export", + "childItems": [ + { + "text": "s", + "kind": "property", + "kindModifiers": "public" + } + ], + "indent": 1 + } +]); diff --git a/tests/cases/fourslash/navigationBarItemsItemsExternalModules3.ts b/tests/cases/fourslash/navigationBarItemsItemsExternalModules3.ts index 6e6dc9871cc..5ee760fabc6 100644 --- a/tests/cases/fourslash/navigationBarItemsItemsExternalModules3.ts +++ b/tests/cases/fourslash/navigationBarItemsItemsExternalModules3.ts @@ -1,15 +1,39 @@ /// // @Filename: test/my fil"e.ts -////{| "itemName": "Bar", "kind": "class" |}export class Bar { -//// {| "itemName": "s", "kind": "property", "parentName": "Bar" |}public s: string; +////export class Bar { +//// public s: string; ////} -////{| "itemName": "\"my fil\\\"e\"", "kind": "module" |} -////{| "itemName": "x", "kind": "var", "parentName": "\"my fil\\\"e\"" |} ////export var x: number; -test.markers().forEach((marker) => { - verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); -}); - -verify.navigationBarCount(4); // external module node + variable in module + class + property +verify.navigationBar([ + { + "text": "\"my fil\\\"e\"", + "kind": "module", + "childItems": [ + { + "text": "Bar", + "kind": "class", + "kindModifiers": "export" + }, + { + "text": "x", + "kind": "var", + "kindModifiers": "export" + } + ] + }, + { + "text": "Bar", + "kind": "class", + "kindModifiers": "export", + "childItems": [ + { + "text": "s", + "kind": "property", + "kindModifiers": "public" + } + ], + "indent": 1 + } +]); diff --git a/tests/cases/fourslash/navigationBarItemsItemsModuleVariables.ts b/tests/cases/fourslash/navigationBarItemsItemsModuleVariables.ts index afc1acfb9cb..6b85d481612 100644 --- a/tests/cases/fourslash/navigationBarItemsItemsModuleVariables.ts +++ b/tests/cases/fourslash/navigationBarItemsItemsModuleVariables.ts @@ -19,12 +19,54 @@ //// export var z = 0; ////} goTo.marker("file1"); -verify.navigationBarContains("Module1", "module"); -verify.navigationBarContains("x", "var"); // nothing else should show up -verify.navigationBarCount(2); +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "Module1", + "kind": "module" + } + ] + }, + { + "text": "Module1", + "kind": "module", + "childItems": [ + { + "text": "x", + "kind": "var", + "kindModifiers": "export" + } + ], + "indent": 1 + } +]); goTo.marker("file2"); -verify.navigationBarContains("Module1.SubModule", "module"); -verify.navigationBarContains("y", "var"); -verify.navigationBarCount(2); +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "Module1.SubModule", + "kind": "module" + } + ] + }, + { + "text": "Module1.SubModule", + "kind": "module", + "childItems": [ + { + "text": "y", + "kind": "var", + "kindModifiers": "export" + } + ], + "indent": 1 + } +]); diff --git a/tests/cases/fourslash/navigationBarItemsMissingName1.ts b/tests/cases/fourslash/navigationBarItemsMissingName1.ts index 98321039c5a..af0e89683bc 100644 --- a/tests/cases/fourslash/navigationBarItemsMissingName1.ts +++ b/tests/cases/fourslash/navigationBarItemsMissingName1.ts @@ -1,16 +1,28 @@ ////export function -/////** -//// * This is a class. -//// */ -////{| "itemName": "C", "kind": "class" |} class C { -//// {| "itemName": "foo", "kind": "method" |} foo() { -//// } +////class C { +//// foo() {} ////} - -test.markers().forEach((marker) => { - verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); -}); - -/// Only have two named elements. -verify.navigationBarCount(2); +verify.navigationBar([ + { + "text": "\"navigationBarItemsMissingName1\"", + "kind": "module", + "childItems": [ + { + "text": "C", + "kind": "class" + } + ] + }, + { + "text": "C", + "kind": "class", + "childItems": [ + { + "text": "foo", + "kind": "method" + } + ], + "indent": 1 + } +]); diff --git a/tests/cases/fourslash/navigationBarItemsMissingName2.ts b/tests/cases/fourslash/navigationBarItemsMissingName2.ts index d26aa0b553d..2eda3b07855 100644 --- a/tests/cases/fourslash/navigationBarItemsMissingName2.ts +++ b/tests/cases/fourslash/navigationBarItemsMissingName2.ts @@ -2,10 +2,24 @@ //// * This is a class. //// */ ////class /* But it has no name! */ { -//// foo() { -//// } +//// foo() {} ////} - -// The class is unnamed, so its method is not included either. -verify.navigationBarCount(2); +// Anonymous classes are still included. +verify.navigationBar([ + { + "text": "", + "kind": "module" + }, + { + "text": "default", + "kind": "class", + "childItems": [ + { + "text": "foo", + "kind": "method" + } + ], + "indent": 1 + } +]); diff --git a/tests/cases/fourslash/navigationBarItemsModules.ts b/tests/cases/fourslash/navigationBarItemsModules.ts index 895a9e23a06..979f22084e5 100644 --- a/tests/cases/fourslash/navigationBarItemsModules.ts +++ b/tests/cases/fourslash/navigationBarItemsModules.ts @@ -1,48 +1,134 @@ +/// -////{| "itemName": "\"X.Y.Z\"", "kind": "module" |} -////declare module "X.Y.Z" { -////} +////declare module "X.Y.Z" {} //// -////{| "itemName": "'X2.Y2.Z2'", "kind": "module" |} -////declare module 'X2.Y2.Z2' { -////} +////declare module 'X2.Y2.Z2' {} //// -////{| "itemName": "A.B.C", "kind": "module" |} ////module A.B.C { -//// {| "itemName": "x", "kind": "var", "parentName": "A.B.C" |} //// export var x; ////} //// -////{| "itemName": "A.B", "kind": "module" |} ////module A.B { -//// {| "itemName": "y", "kind": "var", "parentName": "A.B" |} //// export var y; ////} //// -////{| "itemName": "A", "kind": "module" |} ////module A { -//// {| "itemName": "z", "kind": "var", "parentName": "A" |} //// export var z; ////} //// -////{| "itemName": "A", "kind": "module" |} ////module A { -//// {| "itemName": "B", "kind": "module", "parentName": "" |} //// module B { -//// {| "itemName": "C", "kind": "module", "parentName": "" |} //// module C { -//// {| "itemName": "x", "kind": "var", "parentName": "C" |} //// declare var x; //// } //// } ////} - -test.markers().forEach((marker) => { - verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); -}); - -/// We have 8 module keywords, and 4 var keywords. -/// The declarations of A.B.C.x do not get merged, so the 4 vars are independent. -/// The two 'A' modules, however, do get merged, so in reality we have 7 modules. -verify.navigationBarCount(11); +//We have 8 module keywords, and 4 var keywords. +//The declarations of A.B.C.x do not get merged, so the 4 vars are independent. +//The two 'A' modules, however, do get merged, so in reality we have 7 modules. +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "A.B.C", + "kind": "module" + }, + { + "text": "A.B", + "kind": "module" + }, + { + "text": "A", + "kind": "module" + }, + { + "text": "\"X.Y.Z\"", + "kind": "module", + "kindModifiers": "declare" + }, + { + "text": "'X2.Y2.Z2'", + "kind": "module", + "kindModifiers": "declare" + } + ] + }, + { + "text": "A.B.C", + "kind": "module", + "childItems": [ + { + "text": "x", + "kind": "var", + "kindModifiers": "export" + } + ], + "indent": 1 + }, + { + "text": "A.B", + "kind": "module", + "childItems": [ + { + "text": "y", + "kind": "var", + "kindModifiers": "export" + } + ], + "indent": 1 + }, + { + "text": "A", + "kind": "module", + "childItems": [ + { + "text": "z", + "kind": "var", + "kindModifiers": "export" + }, + { + "text": "B", + "kind": "module" + } + ], + "indent": 1 + }, + { + "text": "B", + "kind": "module", + "childItems": [ + { + "text": "C", + "kind": "module" + } + ], + "indent": 2 + }, + { + "text": "C", + "kind": "module", + "childItems": [ + { + "text": "x", + "kind": "var", + "kindModifiers": "declare" + } + ], + "indent": 3 + }, + { + "text": "\"X.Y.Z\"", + "kind": "module", + "kindModifiers": "declare", + "indent": 1 + }, + { + "text": "'X2.Y2.Z2'", + "kind": "module", + "kindModifiers": "declare", + "indent": 1 + } +]); diff --git a/tests/cases/fourslash/navigationBarItemsMultilineStringIdentifiers.ts b/tests/cases/fourslash/navigationBarItemsMultilineStringIdentifiers.ts index f779c7a0580..2ee4c93a2f1 100644 --- a/tests/cases/fourslash/navigationBarItemsMultilineStringIdentifiers.ts +++ b/tests/cases/fourslash/navigationBarItemsMultilineStringIdentifiers.ts @@ -1,31 +1,22 @@ -////{| "itemName": "\"Multiline\\r\\nMadness\"", "kind": "module" |} ////declare module "Multiline\r\nMadness" { ////} //// -////{| "itemName": "\"Multiline\\\nMadness\"", "kind": "module" |} ////declare module "Multiline\ ////Madness" { ////} -////{| "itemName": "\"MultilineMadness\"", "kind": "module" |} ////declare module "MultilineMadness" {} //// -////{| "itemName": "Foo", "kind": "interface", "parentName": "" |} ////interface Foo { -//// {| "itemName": "\"a1\\\\\\r\\nb\"", "kind": "property", "parentName": "Foo" |} //// "a1\\\r\nb"; -//// {| "itemName": "\"a2\\\n \\\n b\"", "kind": "method", "parentName": "Foo" |} //// "a2\ //// \ //// b"(): Foo; ////} //// -////{| "itemName": "Bar", "kind": "class" |} ////class Bar implements Foo { -//// {| "itemName": "'a1\\\\\\r\\nb'", "kind": "property", "parentName": "Bar" |} //// 'a1\\\r\nb': Foo; //// -//// {| "itemName": "'a2\\\n \\\n b'", "kind": "method", "parentName": "Bar" |} //// 'a2\ //// \ //// b'(): Foo { @@ -33,9 +24,82 @@ //// } ////} - -test.markers().forEach((marker) => { - verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); -}); - -verify.navigationBarCount(11); // interface w/ 2 properties, class w/ 2 properties, 3 modules \ No newline at end of file +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "Bar", + "kind": "class" + }, + { + "text": "Foo", + "kind": "interface" + }, + { + "text": "\"Multiline\\r\\nMadness\"", + "kind": "module", + "kindModifiers": "declare" + }, + { + "text": "\"Multiline\\\nMadness\"", + "kind": "module", + "kindModifiers": "declare" + }, + { + "text": "\"MultilineMadness\"", + "kind": "module", + "kindModifiers": "declare" + } + ] + }, + { + "text": "Bar", + "kind": "class", + "childItems": [ + { + "text": "'a1\\\\\\r\\nb'", + "kind": "property" + }, + { + "text": "'a2\\\n \\\n b'", + "kind": "method" + } + ], + "indent": 1 + }, + { + "text": "Foo", + "kind": "interface", + "childItems": [ + { + "text": "\"a1\\\\\\r\\nb\"", + "kind": "property" + }, + { + "text": "\"a2\\\n \\\n b\"", + "kind": "method" + } + ], + "indent": 1 + }, + { + "text": "\"Multiline\\r\\nMadness\"", + "kind": "module", + "kindModifiers": "declare", + "indent": 1 + }, + { + "text": "\"Multiline\\\nMadness\"", + "kind": "module", + "kindModifiers": "declare", + "indent": 1 + }, + { + "text": "\"MultilineMadness\"", + "kind": "module", + "kindModifiers": "declare", + "indent": 1 + } +]); diff --git a/tests/cases/fourslash/navigationBarItemsPropertiesDefinedInConstructors.ts b/tests/cases/fourslash/navigationBarItemsPropertiesDefinedInConstructors.ts index 9b3f4aacd9c..0ea7a0745c2 100644 --- a/tests/cases/fourslash/navigationBarItemsPropertiesDefinedInConstructors.ts +++ b/tests/cases/fourslash/navigationBarItemsPropertiesDefinedInConstructors.ts @@ -1,15 +1,45 @@ /// ////class List { -//// constructor(public a: boolean, public b: T, c: number) { +//// constructor(public a: boolean, private b: T, readonly c: string, d: number) { //// var local = 0; //// } ////} -verify.navigationBarContains("List", "class"); -verify.navigationBarContains("constructor", "constructor"); -verify.navigationBarContains("a", "property"); -verify.navigationBarContains("b", "property"); - -// no other items -verify.navigationBarCount(4); \ No newline at end of file +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "List", + "kind": "class" + } + ] + }, + { + "text": "List", + "kind": "class", + "childItems": [ + { + "text": "constructor", + "kind": "constructor" + }, + { + "text": "a", + "kind": "property", + "kindModifiers": "public" + }, + { + "text": "b", + "kind": "property", + "kindModifiers": "private" + }, + { + "text": "c", + "kind": "property" + } + ], + "indent": 1 + } +]); diff --git a/tests/cases/fourslash/navigationBarItemsSymbols1.ts b/tests/cases/fourslash/navigationBarItemsSymbols1.ts index c9df85b3ece..53f4c7af445 100644 --- a/tests/cases/fourslash/navigationBarItemsSymbols1.ts +++ b/tests/cases/fourslash/navigationBarItemsSymbols1.ts @@ -1,17 +1,39 @@ /// -////{| "itemName": "C", "kind": "class", "parentName": "" |} ////class C { -//// {| "itemName": "[Symbol.isRegExp]", "kind": "property", "parentName": "C" |} //// [Symbol.isRegExp] = 0; -//// {| "itemName": "[Symbol.iterator]", "kind": "method", "parentName": "C" |} //// [Symbol.iterator]() { } -//// {| "itemName": "[Symbol.isConcatSpreadable]", "kind": "getter", "parentName": "C" |} //// get [Symbol.isConcatSpreadable]() { } ////} -test.markers().forEach(marker => { - verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); -}); - -verify.navigationBarCount(test.markers().length); \ No newline at end of file +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "C", + "kind": "class" + } + ] + }, + { + "text": "C", + "kind": "class", + "childItems": [ + { + "text": "[Symbol.isConcatSpreadable]", + "kind": "getter" + }, + { + "text": "[Symbol.isRegExp]", + "kind": "property" + }, + { + "text": "[Symbol.iterator]", + "kind": "method" + } + ], + "indent": 1 + } +]); diff --git a/tests/cases/fourslash/navigationBarItemsSymbols2.ts b/tests/cases/fourslash/navigationBarItemsSymbols2.ts index 5c398f77bbd..2674047f9c0 100644 --- a/tests/cases/fourslash/navigationBarItemsSymbols2.ts +++ b/tests/cases/fourslash/navigationBarItemsSymbols2.ts @@ -1,16 +1,34 @@ /// -////{| "itemName": "I", "kind": "interface", "parentName": "" |} ////interface I { -//// {| "itemName": "[Symbol.isRegExp]", "kind": "property", "parentName": "I" |} //// [Symbol.isRegExp]: string; -//// {| "itemName": "[Symbol.iterator]", "kind": "method", "parentName": "I" |} //// [Symbol.iterator](): string; ////} -test.markers().forEach(marker => { - verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); -}); - -// 2 are not marked: and its child. -verify.navigationBarCount(2 + test.markers().length); \ No newline at end of file +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "I", + "kind": "interface" + } + ] + }, + { + "text": "I", + "kind": "interface", + "childItems": [ + { + "text": "[Symbol.isRegExp]", + "kind": "property" + }, + { + "text": "[Symbol.iterator]", + "kind": "method" + } + ], + "indent": 1 + } +]); diff --git a/tests/cases/fourslash/navigationBarItemsSymbols3.ts b/tests/cases/fourslash/navigationBarItemsSymbols3.ts index 23451588ecd..9564c496dd8 100644 --- a/tests/cases/fourslash/navigationBarItemsSymbols3.ts +++ b/tests/cases/fourslash/navigationBarItemsSymbols3.ts @@ -1,13 +1,24 @@ /// -////{| "itemName": "E", "kind": "enum", "parentName": "" |} ////enum E { //// // No nav bar entry for this //// [Symbol.isRegExp] = 0 ////} -test.markers().forEach(marker => { - verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); -}); - -verify.navigationBarCount(3); // and E appearing both toplevel and under \ No newline at end of file +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "E", + "kind": "enum" + } + ] + }, + { + "text": "E", + "kind": "enum", + "indent": 1 + } +]); diff --git a/tests/cases/fourslash/navigationBarItemsTypeAlias.ts b/tests/cases/fourslash/navigationBarItemsTypeAlias.ts index 50923256533..8ff9854ac16 100644 --- a/tests/cases/fourslash/navigationBarItemsTypeAlias.ts +++ b/tests/cases/fourslash/navigationBarItemsTypeAlias.ts @@ -2,5 +2,20 @@ ////type T = number | string; -verify.navigationBarCount(1); -verify.navigationBarContains("T", "type"); +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "T", + "kind": "type" + } + ] + }, + { + "text": "T", + "kind": "type", + "indent": 1 + } +]); diff --git a/tests/cases/fourslash/renameAlias.ts b/tests/cases/fourslash/renameAlias.ts new file mode 100644 index 00000000000..e3f57ac7b41 --- /dev/null +++ b/tests/cases/fourslash/renameAlias.ts @@ -0,0 +1,11 @@ +/// + +////module SomeModule { export class SomeClass { } } +////import [|M|] = SomeModule; +////import C = [|M|].SomeClass; + +let ranges = test.ranges() +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/renameAlias2.ts b/tests/cases/fourslash/renameAlias2.ts new file mode 100644 index 00000000000..da1bcf8248d --- /dev/null +++ b/tests/cases/fourslash/renameAlias2.ts @@ -0,0 +1,11 @@ +/// + +////module [|SomeModule|] { export class SomeClass { } } +////import M = [|SomeModule|]; +////import C = M.SomeClass; + +let ranges = test.ranges() +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/renameAlias3.ts b/tests/cases/fourslash/renameAlias3.ts new file mode 100644 index 00000000000..9172f052abb --- /dev/null +++ b/tests/cases/fourslash/renameAlias3.ts @@ -0,0 +1,11 @@ +/// + +////module SomeModule { export class [|SomeClass|] { } } +////import M = SomeModule; +////import C = M.[|SomeClass|]; + +let ranges = test.ranges() +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/renameAliasExternalModule.ts b/tests/cases/fourslash/renameAliasExternalModule.ts new file mode 100644 index 00000000000..54277fd6e64 --- /dev/null +++ b/tests/cases/fourslash/renameAliasExternalModule.ts @@ -0,0 +1,16 @@ +/// + +// @Filename: a.ts +////module SomeModule { export class SomeClass { } } +////export = SomeModule; + +// @Filename: b.ts +////import [|M|] = require("./a"); +////import C = [|M|].SomeClass; + +let ranges = test.ranges() +for (let range of ranges) { + goTo.file(range.fileName); + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/renameAliasExternalModule2.ts b/tests/cases/fourslash/renameAliasExternalModule2.ts new file mode 100644 index 00000000000..2d9d07efb68 --- /dev/null +++ b/tests/cases/fourslash/renameAliasExternalModule2.ts @@ -0,0 +1,16 @@ +/// + +// @Filename: a.ts +////module [|SomeModule|] { export class SomeClass { } } +////export = [|SomeModule|]; + +// @Filename: b.ts +////import M = require("./a"); +////import C = M.SomeClass; + +let ranges = test.ranges() +for (let range of ranges) { + goTo.file(range.fileName); + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/renameAliasExternalModule3.ts b/tests/cases/fourslash/renameAliasExternalModule3.ts new file mode 100644 index 00000000000..acff9371c77 --- /dev/null +++ b/tests/cases/fourslash/renameAliasExternalModule3.ts @@ -0,0 +1,16 @@ +/// + +// @Filename: a.ts +////module SomeModule { export class [|SomeClass|] { } } +////export = SomeModule; + +// @Filename: b.ts +////import M = require("./a"); +////import C = M.[|SomeClass|]; + +let ranges = test.ranges() +for (let range of ranges) { + goTo.file(range.fileName); + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/renameJsThisProperty03.ts b/tests/cases/fourslash/renameJsThisProperty03.ts new file mode 100644 index 00000000000..f2176538578 --- /dev/null +++ b/tests/cases/fourslash/renameJsThisProperty03.ts @@ -0,0 +1,14 @@ +/// + +// @allowJs: true +// @Filename: a.js +////class C { +//// constructor(y) { +//// this./**/[|x|] = y; +//// } +////} +////var t = new C(12); +////t.[|x|] = 11; + +goTo.marker(); +verify.renameLocations( /*findInStrings*/ false, /*findInComments*/ false); diff --git a/tests/cases/fourslash/renameJsThisProperty04.ts b/tests/cases/fourslash/renameJsThisProperty04.ts new file mode 100644 index 00000000000..e307022c66f --- /dev/null +++ b/tests/cases/fourslash/renameJsThisProperty04.ts @@ -0,0 +1,14 @@ +/// + +// @allowJs: true +// @Filename: a.js +////class C { +//// constructor(y) { +//// this.[|x|] = y; +//// } +////} +////var t = new C(12); +////t./**/[|x|] = 11; + +goTo.marker(); +verify.renameLocations( /*findInStrings*/ false, /*findInComments*/ false); diff --git a/tests/cases/fourslash/server/formatOnEnter.ts b/tests/cases/fourslash/server/formatOnEnter.ts new file mode 100644 index 00000000000..f505cf6cec7 --- /dev/null +++ b/tests/cases/fourslash/server/formatOnEnter.ts @@ -0,0 +1,17 @@ +/// + +/////*3*/function listAPIFiles (path : string): string[] { +//// /*1*/ +//// /*2*/ +////} + +goTo.marker("1"); +format.onType("1", "\n"); +verify.currentLineContentIs(" "); + +goTo.marker("2"); +format.onType("2", "\n"); +verify.currentLineContentIs(" "); + +goTo.marker("3"); +verify.currentLineContentIs("function listAPIFiles(path: string): string[] {"); \ No newline at end of file diff --git a/tests/cases/fourslash/server/jsdocTypedefTag.ts b/tests/cases/fourslash/server/jsdocTypedefTag.ts new file mode 100644 index 00000000000..e645b518020 --- /dev/null +++ b/tests/cases/fourslash/server/jsdocTypedefTag.ts @@ -0,0 +1,64 @@ +/// + +// @allowNonTsExtensions: true +// @Filename: jsdocCompletion_typedef.js + +//// /** @typedef {(string | number)} NumberLike */ +//// +//// /** +//// * @typedef Animal +//// * @type {Object} +//// * @property {string} animalName +//// * @property {number} animalAge +//// */ +//// +//// /** +//// * @typedef {Object} Person +//// * @property {string} personName +//// * @property {number} personAge +//// */ +//// +//// /** +//// * @typedef {Object} +//// * @property {string} catName +//// * @property {number} catAge +//// */ +//// var Cat; +//// +//// /** @typedef {{ dogName: string, dogAge: number }} */ +//// var Dog; +//// +//// /** @type {NumberLike} */ +//// var numberLike; numberLike./*numberLike*/ +//// +//// /** @type {Person} */ +//// var p;p./*person*/ +//// +//// /** @type {Animal} */ +//// var a;a./*animal*/ +//// +//// /** @type {Cat} */ +//// var c;c./*cat*/ +//// +//// /** @type {Dog} */ +//// var d;d./*dog*/ + +goTo.marker('numberLike'); +verify.memberListContains('charAt'); +verify.memberListContains('toExponential'); + +goTo.marker('person'); +verify.memberListContains('personName'); +verify.memberListContains('personAge'); + +goTo.marker('animal'); +verify.memberListContains('animalName'); +verify.memberListContains('animalAge'); + +goTo.marker('dog'); +verify.memberListContains('dogName'); +verify.memberListContains('dogAge'); + +goTo.marker('cat'); +verify.memberListContains('catName'); +verify.memberListContains('catAge'); \ No newline at end of file diff --git a/tests/cases/fourslash/server/jsdocTypedefTagGoToDefinition.ts b/tests/cases/fourslash/server/jsdocTypedefTagGoToDefinition.ts new file mode 100644 index 00000000000..4db14611938 --- /dev/null +++ b/tests/cases/fourslash/server/jsdocTypedefTagGoToDefinition.ts @@ -0,0 +1,29 @@ +/// + +// @allowNonTsExtensions: true +// @Filename: jsdocCompletion_typedef.js + +//// /** +//// * @typedef {Object} Person +//// * /*1*/@property {string} personName +//// * @property {number} personAge +//// */ +//// +//// /** +//// * @typedef {{ /*2*/animalName: string, animalAge: number }} Animal +//// */ +//// +//// /** @type {Person} */ +//// var person; person.personName/*3*/ +//// +//// /** @type {Animal} */ +//// var animal; animal.animalName/*4*/ + +goTo.file('jsdocCompletion_typedef.js'); +goTo.marker('3'); +goTo.definition(); +verify.caretAtMarker('1'); + +goTo.marker('4'); +goTo.definition(); +verify.caretAtMarker('2'); diff --git a/tests/cases/fourslash/server/jsdocTypedefTagNavigateTo.ts b/tests/cases/fourslash/server/jsdocTypedefTagNavigateTo.ts new file mode 100644 index 00000000000..77cd75aa44c --- /dev/null +++ b/tests/cases/fourslash/server/jsdocTypedefTagNavigateTo.ts @@ -0,0 +1,30 @@ +/// + +// @allowNonTsExtensions: true +// @Filename: jsDocTypedef_form2.js +//// +//// /** @typedef {(string | number)} NumberLike */ +//// /** @typedef {(string | number | string[])} */ +//// var NumberLike2; +//// +//// /** @type {/*1*/NumberLike} */ +//// var numberLike; + +verify.navigationBar([ + { + "text": "NumberLike", + "kind": "type" + }, + { + "text": "NumberLike2", + "kind": "type" + }, + { + "text": "NumberLike2", + "kind": "var" + }, + { + "text": "numberLike", + "kind": "var" + } +]); \ No newline at end of file diff --git a/tests/cases/fourslash/server/jsdocTypedefTagRename01.ts b/tests/cases/fourslash/server/jsdocTypedefTagRename01.ts new file mode 100644 index 00000000000..776d0180b06 --- /dev/null +++ b/tests/cases/fourslash/server/jsdocTypedefTagRename01.ts @@ -0,0 +1,20 @@ +/// + +// @allowNonTsExtensions: true +// @Filename: jsDocTypedef_form1.js +//// +//// /** @typedef {(string | number)} */ +//// var /*1*/[|NumberLike|]; +//// +//// /*2*/[|NumberLike|] = 10; +//// +//// /** @type {/*3*/[|NumberLike|]} */ +//// var numberLike; + +goTo.file('jsDocTypedef_form1.js') +goTo.marker('1'); +verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ true); +goTo.marker('2'); +verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ true); +goTo.marker('3'); +verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ true); \ No newline at end of file diff --git a/tests/cases/fourslash/server/jsdocTypedefTagRename02.ts b/tests/cases/fourslash/server/jsdocTypedefTagRename02.ts new file mode 100644 index 00000000000..7f1d422d971 --- /dev/null +++ b/tests/cases/fourslash/server/jsdocTypedefTagRename02.ts @@ -0,0 +1,15 @@ +/// + +// @allowNonTsExtensions: true +// @Filename: jsDocTypedef_form2.js +//// +//// /** @typedef {(string | number)} /*1*/[|NumberLike|] */ +//// +//// /** @type {/*2*/[|NumberLike|]} */ +//// var numberLike; + +goTo.file('jsDocTypedef_form2.js') +goTo.marker('1'); +verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ true); +goTo.marker('2'); +verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ true); \ No newline at end of file diff --git a/tests/cases/fourslash/server/jsdocTypedefTagRename03.ts b/tests/cases/fourslash/server/jsdocTypedefTagRename03.ts new file mode 100644 index 00000000000..c1b38945806 --- /dev/null +++ b/tests/cases/fourslash/server/jsdocTypedefTagRename03.ts @@ -0,0 +1,20 @@ +/// + +// @allowNonTsExtensions: true +// @Filename: jsDocTypedef_form3.js +//// +//// /** +//// * @typedef /*1*/[|Person|] +//// * @type {Object} +//// * @property {number} age +//// * @property {string} name +//// */ +//// +//// /** @type {/*2*/[|Person|]} */ +//// var person; + +goTo.file('jsDocTypedef_form3.js') +goTo.marker('1'); +verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ true); +goTo.marker('2'); +verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ true); \ No newline at end of file diff --git a/tests/cases/fourslash/server/jsdocTypedefTagRename04.ts b/tests/cases/fourslash/server/jsdocTypedefTagRename04.ts new file mode 100644 index 00000000000..b7bf220512a --- /dev/null +++ b/tests/cases/fourslash/server/jsdocTypedefTagRename04.ts @@ -0,0 +1,24 @@ +/// + +// @allowNonTsExtensions: true +// @Filename: jsDocTypedef_form2.js +//// +//// function test1() { +//// /** @typedef {(string | number)} NumberLike */ +//// +//// /** @type {/*1*/NumberLike} */ +//// var numberLike; +//// } +//// function test2() { +//// /** @typedef {(string | number)} NumberLike2 */ +//// +//// /** @type {NumberLike2} */ +//// var n/*2*/umberLike2; +//// } + +goTo.marker('2'); +verify.quickInfoExists(); +goTo.marker('1'); +edit.insert('111'); +goTo.marker('2'); +verify.quickInfoExists(); \ No newline at end of file diff --git a/tests/cases/fourslash/server/navbar01.ts b/tests/cases/fourslash/server/navbar01.ts index 05e92c2835f..7f2229fcb81 100644 --- a/tests/cases/fourslash/server/navbar01.ts +++ b/tests/cases/fourslash/server/navbar01.ts @@ -1,52 +1,166 @@ /// ////// Interface -////{| "itemName": "IPoint", "kind": "interface", "parentName": "" |}interface IPoint { -//// {| "itemName": "getDist", "kind": "method", "parentName": "IPoint" |}getDist(): number; -//// {| "itemName": "new()", "kind": "construct", "parentName": "IPoint" |}new(): IPoint; -//// {| "itemName": "()", "kind": "call", "parentName": "IPoint" |}(): any; -//// {| "itemName": "[]", "kind": "index", "parentName": "IPoint" |}[x:string]: number; -//// {| "itemName": "prop", "kind": "property", "parentName": "IPoint" |}prop: string; +////interface IPoint { +//// getDist(): number; +//// new(): IPoint; +//// (): any; +//// [x:string]: number; +//// prop: string; ////} //// /////// Module -////{| "itemName": "Shapes", "kind": "module", "parentName": "" |}module Shapes { -//// +////module Shapes { //// // Class -//// {| "itemName": "Point", "kind": "class", "parentName": "" |}export class Point implements IPoint { -//// {| "itemName": "constructor", "kind": "constructor", "parentName": "Point" |}constructor (public x: number, public y: number) { } +//// export class Point implements IPoint { +//// constructor (public x: number, public y: number) { } //// //// // Instance member -//// {| "itemName": "getDist", "kind": "method", "parentName": "Point" |}getDist() { return Math.sqrt(this.x * this.x + this.y * this.y); } +//// getDist() { return Math.sqrt(this.x * this.x + this.y * this.y); } //// //// // Getter -//// {| "itemName": "value", "kind": "getter", "parentName": "Point" |}get value(): number { return 0; } +//// get value(): number { return 0; } //// //// // Setter -//// {| "itemName": "value", "kind": "setter", "parentName": "Point" |}set value(newValue: number) { return; } +//// set value(newValue: number) { return; } //// //// // Static member -//// {| "itemName": "origin", "kind": "property", "parentName": "Point" |}static origin = new Point(0, 0); +//// static origin = new Point(0, 0); //// //// // Static method -//// {| "itemName": "getOrigin", "kind": "method", "parentName": "Point" |}private static getOrigin() { return Point.origin;} +//// private static getOrigin() { return Point.origin;} //// } //// -//// {| "itemName": "Values", "kind": "enum", "parentName": "Shapes" |}enum Values { -//// value1, -//// {| "itemName": "value2", "kind": "property", "parentName": "Values" |}value2, -//// value3, -//// } +//// enum Values { value1, value2, value3 } ////} //// ////// Local variables -////{| "itemName": "p", "kind": "var", "parentName": "" |}var p: IPoint = new Shapes.Point(3, 4); -////{| "itemName": "dist", "kind": "var", "parentName": "" |}var dist = p.getDist(); +////var p: IPoint = new Shapes.Point(3, 4); +////var dist = p.getDist(); -test.markers().forEach((marker) => { - if (marker.data) { - verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "dist", + "kind": "var" + }, + { + "text": "IPoint", + "kind": "interface" + }, + { + "text": "p", + "kind": "var" + }, + { + "text": "Shapes", + "kind": "module" + } + ] + }, + { + "text": "IPoint", + "kind": "interface", + "childItems": [ + { + "text": "()", + "kind": "call" + }, + { + "text": "new()", + "kind": "construct" + }, + { + "text": "[]", + "kind": "index" + }, + { + "text": "getDist", + "kind": "method" + }, + { + "text": "prop", + "kind": "property" + } + ] + }, + { + "text": "Shapes", + "kind": "module", + "childItems": [ + { + "text": "Point", + "kind": "class", + "kindModifiers": "export" + }, + { + "text": "Values", + "kind": "enum" + } + ] + }, + { + "text": "Point", + "kind": "class", + "kindModifiers": "export", + "childItems": [ + { + "text": "constructor", + "kind": "constructor" + }, + { + "text": "getDist", + "kind": "method" + }, + { + "text": "getOrigin", + "kind": "method", + "kindModifiers": "private,static" + }, + { + "text": "origin", + "kind": "property", + "kindModifiers": "static" + }, + { + "text": "value", + "kind": "getter" + }, + { + "text": "value", + "kind": "setter" + }, + { + "text": "x", + "kind": "property", + "kindModifiers": "public" + }, + { + "text": "y", + "kind": "property", + "kindModifiers": "public" + } + ] + }, + { + "text": "Values", + "kind": "enum", + "childItems": [ + { + "text": "value1", + "kind": "property" + }, + { + "text": "value2", + "kind": "property" + }, + { + "text": "value3", + "kind": "property" + } + ] } -}); - -verify.navigationBarCount(25); +]); diff --git a/tests/cases/fourslash/shims-pp/getNavigationBarItems.ts b/tests/cases/fourslash/shims-pp/getNavigationBarItems.ts index a2cdb80baef..b06d782d8bf 100644 --- a/tests/cases/fourslash/shims-pp/getNavigationBarItems.ts +++ b/tests/cases/fourslash/shims-pp/getNavigationBarItems.ts @@ -2,12 +2,15 @@ //// {| "itemName": "c", "kind": "const", "parentName": "" |}const c = 0; -test.markers().forEach(marker => { - verify.navigationBarContains( - marker.data.itemName, - marker.data.kind, - marker.fileName, - marker.data.parentName, - marker.data.isAdditionalRange, - marker.position); -}); \ No newline at end of file +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "c", + "kind": "const" + } + ] + } +]); diff --git a/tests/cases/fourslash/shims/getNavigationBarItems.ts b/tests/cases/fourslash/shims/getNavigationBarItems.ts index a2cdb80baef..b06d782d8bf 100644 --- a/tests/cases/fourslash/shims/getNavigationBarItems.ts +++ b/tests/cases/fourslash/shims/getNavigationBarItems.ts @@ -2,12 +2,15 @@ //// {| "itemName": "c", "kind": "const", "parentName": "" |}const c = 0; -test.markers().forEach(marker => { - verify.navigationBarContains( - marker.data.itemName, - marker.data.kind, - marker.fileName, - marker.data.parentName, - marker.data.isAdditionalRange, - marker.position); -}); \ No newline at end of file +verify.navigationBar([ + { + "text": "", + "kind": "module", + "childItems": [ + { + "text": "c", + "kind": "const" + } + ] + } +]);