diff --git a/lib/tsc.js b/lib/tsc.js index 3fb71924bd1..1577f9f0c17 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -191,7 +191,17 @@ var ts; return undefined; } ts.forEach = forEach; - function find(array, callback) { + function find(array, predicate) { + for (var i = 0, len = array.length; i < len; i++) { + var value = array[i]; + if (predicate(value, i)) { + return value; + } + } + return undefined; + } + ts.find = find; + function findMap(array, callback) { for (var i = 0, len = array.length; i < len; i++) { var result = callback(array[i], i); if (result) { @@ -200,7 +210,7 @@ var ts; } Debug.fail(); } - ts.find = find; + ts.findMap = findMap; function contains(array, value) { if (array) { for (var _i = 0, array_1 = array; _i < array_1.length; _i++) { @@ -1158,6 +1168,7 @@ var ts; } ts.getScriptKindFromFileName = getScriptKindFromFileName; ts.supportedTypeScriptExtensions = [".ts", ".tsx", ".d.ts"]; + ts.supportedTypescriptExtensionsForExtractExtension = [".d.ts", ".ts", ".tsx"]; ts.supportedJavascriptExtensions = [".js", ".jsx"]; var allSupportedExtensions = ts.supportedTypeScriptExtensions.concat(ts.supportedJavascriptExtensions); function getSupportedExtensions(options) { @@ -1220,9 +1231,13 @@ var ts; } ts.removeFileExtension = removeFileExtension; function tryRemoveExtension(path, extension) { - return fileExtensionIs(path, extension) ? path.substring(0, path.length - extension.length) : undefined; + return fileExtensionIs(path, extension) ? removeExtension(path, extension) : undefined; } ts.tryRemoveExtension = tryRemoveExtension; + function removeExtension(path, extension) { + return path.substring(0, path.length - extension.length); + } + ts.removeExtension = removeExtension; function isJsxOrTsxExtension(ext) { return ext === ".jsx" || ext === ".tsx"; } @@ -2227,6 +2242,7 @@ var ts; Cannot_find_type_definition_file_for_0: { code: 2688, category: ts.DiagnosticCategory.Error, key: "Cannot_find_type_definition_file_for_0_2688", message: "Cannot find type definition file for '{0}'." }, Cannot_extend_an_interface_0_Did_you_mean_implements: { code: 2689, category: ts.DiagnosticCategory.Error, key: "Cannot_extend_an_interface_0_Did_you_mean_implements_2689", message: "Cannot extend an interface '{0}'. Did you mean 'implements'?" }, A_class_must_be_declared_after_its_base_class: { code: 2690, category: ts.DiagnosticCategory.Error, key: "A_class_must_be_declared_after_its_base_class_2690", message: "A class must be declared after its base class." }, + An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead: { code: 2691, category: ts.DiagnosticCategory.Error, key: "An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead_2691", message: "An import path cannot end with a '{0}' extension. Consider importing '{1}' instead." }, 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}'." }, @@ -6230,6 +6246,10 @@ var ts; return ts.forEach(ts.supportedTypeScriptExtensions, function (extension) { return ts.fileExtensionIs(fileName, extension); }); } ts.hasTypeScriptFileExtension = hasTypeScriptFileExtension; + function tryExtractTypeScriptExtension(fileName) { + return ts.find(ts.supportedTypescriptExtensionsForExtractExtension, function (extension) { return ts.fileExtensionIs(fileName, extension); }); + } + ts.tryExtractTypeScriptExtension = tryExtractTypeScriptExtension; function getExpandedCharCodes(input) { var output = []; var length = input.length; @@ -8837,6 +8857,8 @@ var ts; return parseTypeOfExpression(); case 103: return parseVoidExpression(); + case 119: + return parseAwaitExpression(); case 25: return parseTypeAssertion(); default: @@ -13902,7 +13924,7 @@ var ts; } } function getDeclarationOfAliasSymbol(symbol) { - return ts.find(symbol.declarations, function (d) { return ts.isAliasSymbolDeclaration(d) ? d : undefined; }); + return ts.findMap(symbol.declarations, function (d) { return ts.isAliasSymbolDeclaration(d) ? d : undefined; }); } function getTargetOfImportEqualsDeclaration(node) { if (node.moduleReference.kind === 240) { @@ -14162,7 +14184,14 @@ var ts; } } if (moduleNotFoundError) { - error(moduleReferenceLiteral, moduleNotFoundError, moduleName); + var tsExtension = ts.tryExtractTypeScriptExtension(moduleName); + if (tsExtension) { + var diag = ts.Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead; + error(moduleReferenceLiteral, diag, tsExtension, ts.removeExtension(moduleName, tsExtension)); + } + else { + error(moduleReferenceLiteral, moduleNotFoundError, moduleName); + } } return undefined; } @@ -15526,25 +15555,23 @@ var ts; return checkIdentifier(declaration.name); } if (ts.isBindingPattern(declaration.name)) { - return getTypeFromBindingPattern(declaration.name, false); + return getTypeFromBindingPattern(declaration.name, false, true); } return undefined; } - function getTypeFromBindingElement(element, includePatternInType) { + function getTypeFromBindingElement(element, includePatternInType, reportErrors) { if (element.initializer) { - var type = checkExpressionCached(element.initializer); - reportErrorsFromWidening(element, type); - return getWidenedType(type); + return checkExpressionCached(element.initializer); } if (ts.isBindingPattern(element.name)) { - return getTypeFromBindingPattern(element.name, includePatternInType); + return getTypeFromBindingPattern(element.name, includePatternInType, reportErrors); } - if (compilerOptions.noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) { + if (reportErrors && compilerOptions.noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) { reportImplicitAnyError(element, anyType); } return anyType; } - function getTypeFromObjectBindingPattern(pattern, includePatternInType) { + function getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors) { var members = ts.createMap(); var hasComputedProperties = false; ts.forEach(pattern.elements, function (e) { @@ -15556,7 +15583,7 @@ var ts; var text = getTextOfPropertyName(name); var flags = 4 | 67108864 | (e.initializer ? 536870912 : 0); var symbol = createSymbol(flags, text); - symbol.type = getTypeFromBindingElement(e, includePatternInType); + symbol.type = getTypeFromBindingElement(e, includePatternInType, reportErrors); symbol.bindingElement = e; members[symbol.name] = symbol; }); @@ -15569,12 +15596,12 @@ var ts; } return result; } - function getTypeFromArrayBindingPattern(pattern, includePatternInType) { + function getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors) { var elements = pattern.elements; if (elements.length === 0 || elements[elements.length - 1].dotDotDotToken) { return languageVersion >= 2 ? createIterableType(anyType) : anyArrayType; } - var elementTypes = ts.map(elements, function (e) { return e.kind === 193 ? anyType : getTypeFromBindingElement(e, includePatternInType); }); + var elementTypes = ts.map(elements, function (e) { return e.kind === 193 ? anyType : getTypeFromBindingElement(e, includePatternInType, reportErrors); }); if (includePatternInType) { var result = createNewTupleType(elementTypes); result.pattern = pattern; @@ -15582,10 +15609,10 @@ var ts; } return createTupleType(elementTypes); } - function getTypeFromBindingPattern(pattern, includePatternInType) { + function getTypeFromBindingPattern(pattern, includePatternInType, reportErrors) { return pattern.kind === 167 - ? getTypeFromObjectBindingPattern(pattern, includePatternInType) - : getTypeFromArrayBindingPattern(pattern, includePatternInType); + ? getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors) + : getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors); } function getWidenedTypeForVariableLikeDeclaration(declaration, reportErrors) { var type = getTypeForVariableLikeDeclaration(declaration, true); @@ -20649,7 +20676,7 @@ var ts; } } if (ts.isBindingPattern(declaration.name)) { - return getTypeFromBindingPattern(declaration.name, true); + return getTypeFromBindingPattern(declaration.name, true, false); } if (ts.isBindingPattern(declaration.parent)) { var parentDeclaration = declaration.parent.parent; @@ -24016,12 +24043,7 @@ var ts; checkSignatureDeclaration(node); if (node.kind === 149) { if (!ts.isInAmbientContext(node) && ts.nodeIsPresent(node.body) && (node.flags & 32768)) { - if (node.flags & 65536) { - if (compilerOptions.noImplicitReturns) { - error(node.name, ts.Diagnostics.Not_all_code_paths_return_a_value); - } - } - else { + if (!(node.flags & 65536)) { error(node.name, ts.Diagnostics.A_get_accessor_must_return_a_value); } } @@ -24043,7 +24065,10 @@ var ts; checkAccessorDeclarationTypesIdentical(node, otherAccessor, getThisTypeOfDeclaration, ts.Diagnostics.get_and_set_accessor_must_have_the_same_this_type); } } - getTypeOfAccessors(getSymbolOfNode(node)); + var returnType = getTypeOfAccessors(getSymbolOfNode(node)); + if (node.kind === 149) { + checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnType); + } } if (node.parent.kind !== 171) { checkSourceElement(node.body); @@ -36934,9 +36959,9 @@ var ts; } ts.directoryProbablyExists = directoryProbablyExists; function loadModuleFromFile(candidate, extensions, failedLookupLocation, onlyRecordFailures, state) { - var resolvedByAddingOrKeepingExtension = loadModuleFromFileWorker(candidate, extensions, failedLookupLocation, onlyRecordFailures, state); - if (resolvedByAddingOrKeepingExtension) { - return resolvedByAddingOrKeepingExtension; + var resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocation, onlyRecordFailures, state); + if (resolvedByAddingExtension) { + return resolvedByAddingExtension; } if (ts.hasJavaScriptFileExtension(candidate)) { var extensionless = ts.removeFileExtension(candidate); @@ -36944,35 +36969,33 @@ var ts; var extension = candidate.substring(extensionless.length); trace(state.host, ts.Diagnostics.File_name_0_has_a_1_extension_stripping_it, candidate, extension); } - return loadModuleFromFileWorker(extensionless, extensions, failedLookupLocation, onlyRecordFailures, state); + return tryAddingExtensions(extensionless, extensions, failedLookupLocation, onlyRecordFailures, state); } } - function loadModuleFromFileWorker(candidate, extensions, failedLookupLocation, onlyRecordFailures, state) { + function tryAddingExtensions(candidate, extensions, failedLookupLocation, onlyRecordFailures, state) { if (!onlyRecordFailures) { var directory = ts.getDirectoryPath(candidate); if (directory) { onlyRecordFailures = !directoryProbablyExists(directory, state.host); } } - return ts.forEach(extensions, tryLoad); - function tryLoad(ext) { - if (state.skipTsx && ts.isJsxOrTsxExtension(ext)) { - return undefined; + return ts.forEach(extensions, function (ext) { + return !(state.skipTsx && ts.isJsxOrTsxExtension(ext)) && tryFile(candidate + ext, failedLookupLocation, onlyRecordFailures, state); + }); + } + function tryFile(fileName, failedLookupLocation, onlyRecordFailures, state) { + if (!onlyRecordFailures && state.host.fileExists(fileName)) { + if (state.traceEnabled) { + trace(state.host, ts.Diagnostics.File_0_exist_use_it_as_a_name_resolution_result, fileName); } - var fileName = ts.fileExtensionIs(candidate, ext) ? candidate : candidate + ext; - if (!onlyRecordFailures && state.host.fileExists(fileName)) { - if (state.traceEnabled) { - trace(state.host, ts.Diagnostics.File_0_exist_use_it_as_a_name_resolution_result, fileName); - } - return fileName; - } - else { - if (state.traceEnabled) { - trace(state.host, ts.Diagnostics.File_0_does_not_exist, fileName); - } - failedLookupLocation.push(fileName); - return undefined; + return fileName; + } + else { + if (state.traceEnabled) { + trace(state.host, ts.Diagnostics.File_0_does_not_exist, fileName); } + failedLookupLocation.push(fileName); + return undefined; } } function loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocation, onlyRecordFailures, state) { @@ -36984,7 +37007,8 @@ var ts; } var typesFile = tryReadTypesSection(packageJsonPath, candidate, state); if (typesFile) { - var result = loadModuleFromFile(typesFile, extensions, failedLookupLocation, !directoryProbablyExists(ts.getDirectoryPath(typesFile), state.host), state); + var onlyRecordFailures_1 = !directoryProbablyExists(ts.getDirectoryPath(typesFile), state.host); + var result = tryFile(typesFile, failedLookupLocation, onlyRecordFailures_1, state); if (result) { return result; } diff --git a/lib/tsserver.js b/lib/tsserver.js index d5c4ddfe8c7..d754a623488 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -196,7 +196,17 @@ var ts; return undefined; } ts.forEach = forEach; - function find(array, callback) { + function find(array, predicate) { + for (var i = 0, len = array.length; i < len; i++) { + var value = array[i]; + if (predicate(value, i)) { + return value; + } + } + return undefined; + } + ts.find = find; + function findMap(array, callback) { for (var i = 0, len = array.length; i < len; i++) { var result = callback(array[i], i); if (result) { @@ -205,7 +215,7 @@ var ts; } Debug.fail(); } - ts.find = find; + ts.findMap = findMap; function contains(array, value) { if (array) { for (var _i = 0, array_1 = array; _i < array_1.length; _i++) { @@ -1163,6 +1173,7 @@ var ts; } ts.getScriptKindFromFileName = getScriptKindFromFileName; ts.supportedTypeScriptExtensions = [".ts", ".tsx", ".d.ts"]; + ts.supportedTypescriptExtensionsForExtractExtension = [".d.ts", ".ts", ".tsx"]; ts.supportedJavascriptExtensions = [".js", ".jsx"]; var allSupportedExtensions = ts.supportedTypeScriptExtensions.concat(ts.supportedJavascriptExtensions); function getSupportedExtensions(options) { @@ -1225,9 +1236,13 @@ var ts; } ts.removeFileExtension = removeFileExtension; function tryRemoveExtension(path, extension) { - return fileExtensionIs(path, extension) ? path.substring(0, path.length - extension.length) : undefined; + return fileExtensionIs(path, extension) ? removeExtension(path, extension) : undefined; } ts.tryRemoveExtension = tryRemoveExtension; + function removeExtension(path, extension) { + return path.substring(0, path.length - extension.length); + } + ts.removeExtension = removeExtension; function isJsxOrTsxExtension(ext) { return ext === ".jsx" || ext === ".tsx"; } @@ -2232,6 +2247,7 @@ var ts; Cannot_find_type_definition_file_for_0: { code: 2688, category: ts.DiagnosticCategory.Error, key: "Cannot_find_type_definition_file_for_0_2688", message: "Cannot find type definition file for '{0}'." }, Cannot_extend_an_interface_0_Did_you_mean_implements: { code: 2689, category: ts.DiagnosticCategory.Error, key: "Cannot_extend_an_interface_0_Did_you_mean_implements_2689", message: "Cannot extend an interface '{0}'. Did you mean 'implements'?" }, A_class_must_be_declared_after_its_base_class: { code: 2690, category: ts.DiagnosticCategory.Error, key: "A_class_must_be_declared_after_its_base_class_2690", message: "A class must be declared after its base class." }, + An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead: { code: 2691, category: ts.DiagnosticCategory.Error, key: "An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead_2691", message: "An import path cannot end with a '{0}' extension. Consider importing '{1}' instead." }, 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}'." }, @@ -7226,6 +7242,10 @@ var ts; return ts.forEach(ts.supportedTypeScriptExtensions, function (extension) { return ts.fileExtensionIs(fileName, extension); }); } ts.hasTypeScriptFileExtension = hasTypeScriptFileExtension; + function tryExtractTypeScriptExtension(fileName) { + return ts.find(ts.supportedTypescriptExtensionsForExtractExtension, function (extension) { return ts.fileExtensionIs(fileName, extension); }); + } + ts.tryExtractTypeScriptExtension = tryExtractTypeScriptExtension; function getExpandedCharCodes(input) { var output = []; var length = input.length; @@ -9833,6 +9853,8 @@ var ts; return parseTypeOfExpression(); case 103: return parseVoidExpression(); + case 119: + return parseAwaitExpression(); case 25: return parseTypeAssertion(); default: @@ -14898,7 +14920,7 @@ var ts; } } function getDeclarationOfAliasSymbol(symbol) { - return ts.find(symbol.declarations, function (d) { return ts.isAliasSymbolDeclaration(d) ? d : undefined; }); + return ts.findMap(symbol.declarations, function (d) { return ts.isAliasSymbolDeclaration(d) ? d : undefined; }); } function getTargetOfImportEqualsDeclaration(node) { if (node.moduleReference.kind === 240) { @@ -15158,7 +15180,14 @@ var ts; } } if (moduleNotFoundError) { - error(moduleReferenceLiteral, moduleNotFoundError, moduleName); + var tsExtension = ts.tryExtractTypeScriptExtension(moduleName); + if (tsExtension) { + var diag = ts.Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead; + error(moduleReferenceLiteral, diag, tsExtension, ts.removeExtension(moduleName, tsExtension)); + } + else { + error(moduleReferenceLiteral, moduleNotFoundError, moduleName); + } } return undefined; } @@ -16522,25 +16551,23 @@ var ts; return checkIdentifier(declaration.name); } if (ts.isBindingPattern(declaration.name)) { - return getTypeFromBindingPattern(declaration.name, false); + return getTypeFromBindingPattern(declaration.name, false, true); } return undefined; } - function getTypeFromBindingElement(element, includePatternInType) { + function getTypeFromBindingElement(element, includePatternInType, reportErrors) { if (element.initializer) { - var type = checkExpressionCached(element.initializer); - reportErrorsFromWidening(element, type); - return getWidenedType(type); + return checkExpressionCached(element.initializer); } if (ts.isBindingPattern(element.name)) { - return getTypeFromBindingPattern(element.name, includePatternInType); + return getTypeFromBindingPattern(element.name, includePatternInType, reportErrors); } - if (compilerOptions.noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) { + if (reportErrors && compilerOptions.noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) { reportImplicitAnyError(element, anyType); } return anyType; } - function getTypeFromObjectBindingPattern(pattern, includePatternInType) { + function getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors) { var members = ts.createMap(); var hasComputedProperties = false; ts.forEach(pattern.elements, function (e) { @@ -16552,7 +16579,7 @@ var ts; var text = getTextOfPropertyName(name); var flags = 4 | 67108864 | (e.initializer ? 536870912 : 0); var symbol = createSymbol(flags, text); - symbol.type = getTypeFromBindingElement(e, includePatternInType); + symbol.type = getTypeFromBindingElement(e, includePatternInType, reportErrors); symbol.bindingElement = e; members[symbol.name] = symbol; }); @@ -16565,12 +16592,12 @@ var ts; } return result; } - function getTypeFromArrayBindingPattern(pattern, includePatternInType) { + function getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors) { var elements = pattern.elements; if (elements.length === 0 || elements[elements.length - 1].dotDotDotToken) { return languageVersion >= 2 ? createIterableType(anyType) : anyArrayType; } - var elementTypes = ts.map(elements, function (e) { return e.kind === 193 ? anyType : getTypeFromBindingElement(e, includePatternInType); }); + var elementTypes = ts.map(elements, function (e) { return e.kind === 193 ? anyType : getTypeFromBindingElement(e, includePatternInType, reportErrors); }); if (includePatternInType) { var result = createNewTupleType(elementTypes); result.pattern = pattern; @@ -16578,10 +16605,10 @@ var ts; } return createTupleType(elementTypes); } - function getTypeFromBindingPattern(pattern, includePatternInType) { + function getTypeFromBindingPattern(pattern, includePatternInType, reportErrors) { return pattern.kind === 167 - ? getTypeFromObjectBindingPattern(pattern, includePatternInType) - : getTypeFromArrayBindingPattern(pattern, includePatternInType); + ? getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors) + : getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors); } function getWidenedTypeForVariableLikeDeclaration(declaration, reportErrors) { var type = getTypeForVariableLikeDeclaration(declaration, true); @@ -21645,7 +21672,7 @@ var ts; } } if (ts.isBindingPattern(declaration.name)) { - return getTypeFromBindingPattern(declaration.name, true); + return getTypeFromBindingPattern(declaration.name, true, false); } if (ts.isBindingPattern(declaration.parent)) { var parentDeclaration = declaration.parent.parent; @@ -25012,12 +25039,7 @@ var ts; checkSignatureDeclaration(node); if (node.kind === 149) { if (!ts.isInAmbientContext(node) && ts.nodeIsPresent(node.body) && (node.flags & 32768)) { - if (node.flags & 65536) { - if (compilerOptions.noImplicitReturns) { - error(node.name, ts.Diagnostics.Not_all_code_paths_return_a_value); - } - } - else { + if (!(node.flags & 65536)) { error(node.name, ts.Diagnostics.A_get_accessor_must_return_a_value); } } @@ -25039,7 +25061,10 @@ var ts; checkAccessorDeclarationTypesIdentical(node, otherAccessor, getThisTypeOfDeclaration, ts.Diagnostics.get_and_set_accessor_must_have_the_same_this_type); } } - getTypeOfAccessors(getSymbolOfNode(node)); + var returnType = getTypeOfAccessors(getSymbolOfNode(node)); + if (node.kind === 149) { + checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnType); + } } if (node.parent.kind !== 171) { checkSourceElement(node.body); @@ -37930,9 +37955,9 @@ var ts; } ts.directoryProbablyExists = directoryProbablyExists; function loadModuleFromFile(candidate, extensions, failedLookupLocation, onlyRecordFailures, state) { - var resolvedByAddingOrKeepingExtension = loadModuleFromFileWorker(candidate, extensions, failedLookupLocation, onlyRecordFailures, state); - if (resolvedByAddingOrKeepingExtension) { - return resolvedByAddingOrKeepingExtension; + var resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocation, onlyRecordFailures, state); + if (resolvedByAddingExtension) { + return resolvedByAddingExtension; } if (ts.hasJavaScriptFileExtension(candidate)) { var extensionless = ts.removeFileExtension(candidate); @@ -37940,35 +37965,33 @@ var ts; var extension = candidate.substring(extensionless.length); trace(state.host, ts.Diagnostics.File_name_0_has_a_1_extension_stripping_it, candidate, extension); } - return loadModuleFromFileWorker(extensionless, extensions, failedLookupLocation, onlyRecordFailures, state); + return tryAddingExtensions(extensionless, extensions, failedLookupLocation, onlyRecordFailures, state); } } - function loadModuleFromFileWorker(candidate, extensions, failedLookupLocation, onlyRecordFailures, state) { + function tryAddingExtensions(candidate, extensions, failedLookupLocation, onlyRecordFailures, state) { if (!onlyRecordFailures) { var directory = ts.getDirectoryPath(candidate); if (directory) { onlyRecordFailures = !directoryProbablyExists(directory, state.host); } } - return ts.forEach(extensions, tryLoad); - function tryLoad(ext) { - if (state.skipTsx && ts.isJsxOrTsxExtension(ext)) { - return undefined; + return ts.forEach(extensions, function (ext) { + return !(state.skipTsx && ts.isJsxOrTsxExtension(ext)) && tryFile(candidate + ext, failedLookupLocation, onlyRecordFailures, state); + }); + } + function tryFile(fileName, failedLookupLocation, onlyRecordFailures, state) { + if (!onlyRecordFailures && state.host.fileExists(fileName)) { + if (state.traceEnabled) { + trace(state.host, ts.Diagnostics.File_0_exist_use_it_as_a_name_resolution_result, fileName); } - var fileName = ts.fileExtensionIs(candidate, ext) ? candidate : candidate + ext; - if (!onlyRecordFailures && state.host.fileExists(fileName)) { - if (state.traceEnabled) { - trace(state.host, ts.Diagnostics.File_0_exist_use_it_as_a_name_resolution_result, fileName); - } - return fileName; - } - else { - if (state.traceEnabled) { - trace(state.host, ts.Diagnostics.File_0_does_not_exist, fileName); - } - failedLookupLocation.push(fileName); - return undefined; + return fileName; + } + else { + if (state.traceEnabled) { + trace(state.host, ts.Diagnostics.File_0_does_not_exist, fileName); } + failedLookupLocation.push(fileName); + return undefined; } } function loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocation, onlyRecordFailures, state) { @@ -37980,7 +38003,8 @@ var ts; } var typesFile = tryReadTypesSection(packageJsonPath, candidate, state); if (typesFile) { - var result = loadModuleFromFile(typesFile, extensions, failedLookupLocation, !directoryProbablyExists(ts.getDirectoryPath(typesFile), state.host), state); + var onlyRecordFailures_1 = !directoryProbablyExists(ts.getDirectoryPath(typesFile), state.host); + var result = tryFile(typesFile, failedLookupLocation, onlyRecordFailures_1, state); if (result) { return result; } @@ -47669,6 +47693,24 @@ var ts; } if (!documentation) { documentation = symbol.getDocumentationComment(); + if (documentation.length === 0 && symbol.flags & 4) { + if (symbol.parent && ts.forEach(symbol.parent.declarations, function (declaration) { return declaration.kind === 256; })) { + for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { + var declaration = _a[_i]; + if (!declaration.parent || declaration.parent.kind !== 187) { + continue; + } + var rhsSymbol = program.getTypeChecker().getSymbolAtLocation(declaration.parent.right); + if (!rhsSymbol) { + continue; + } + documentation = rhsSymbol.getDocumentationComment(); + if (documentation.length > 0) { + break; + } + } + } + } } return { displayParts: displayParts, documentation: documentation, symbolKind: symbolKind }; function addNewLineIfDisplayPartsExist() { diff --git a/lib/tsserverlibrary.d.ts b/lib/tsserverlibrary.d.ts index 16d187657f0..5c7096df482 100644 --- a/lib/tsserverlibrary.d.ts +++ b/lib/tsserverlibrary.d.ts @@ -2150,7 +2150,8 @@ declare namespace ts { GreaterThan = 1, } function forEach(array: T[] | undefined, callback: (element: T, index: number) => U | undefined): U | undefined; - function find(array: T[], callback: (element: T, index: number) => U | undefined): U; + function find(array: T[], predicate: (element: T, index: number) => boolean): T | undefined; + function findMap(array: T[], callback: (element: T, index: number) => U | undefined): U; function contains(array: T[], value: T): boolean; function indexOf(array: T[], value: T): number; function indexOfAnyCharCode(text: string, charCodes: number[], start?: number): number; @@ -2237,6 +2238,7 @@ declare namespace ts { function ensureScriptKind(fileName: string, scriptKind?: ScriptKind): ScriptKind; function getScriptKindFromFileName(fileName: string): ScriptKind; const supportedTypeScriptExtensions: string[]; + const supportedTypescriptExtensionsForExtractExtension: string[]; const supportedJavascriptExtensions: string[]; function getSupportedExtensions(options?: CompilerOptions): string[]; function isSupportedSourceFileName(fileName: string, compilerOptions?: CompilerOptions): boolean; @@ -2251,7 +2253,8 @@ declare namespace ts { function adjustExtensionPriority(extensionPriority: ExtensionPriority): ExtensionPriority; function getNextLowestExtensionPriority(extensionPriority: ExtensionPriority): ExtensionPriority; function removeFileExtension(path: string): string; - function tryRemoveExtension(path: string, extension: string): string; + function tryRemoveExtension(path: string, extension: string): string | undefined; + function removeExtension(path: string, extension: string): string; function isJsxOrTsxExtension(ext: string): boolean; function changeExtension(path: T, newExtension: string): T; interface ObjectAllocator { @@ -5249,6 +5252,12 @@ declare namespace ts { key: string; message: string; }; + An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead: { + code: number; + category: DiagnosticCategory; + key: string; + message: string; + }; Import_declaration_0_is_using_private_name_1: { code: number; category: DiagnosticCategory; @@ -7208,6 +7217,7 @@ declare namespace ts { function getLocalSymbolForExportDefault(symbol: Symbol): Symbol; function hasJavaScriptFileExtension(fileName: string): boolean; function hasTypeScriptFileExtension(fileName: string): boolean; + function tryExtractTypeScriptExtension(fileName: string): string | undefined; const stringify: (value: any) => string; function convertToBase64(input: string): string; function convertToRelativePath(absoluteOrRelativePath: string, basePath: string, getCanonicalFileName: (path: string) => string): string; diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js index 9a1ae13d058..a7fb4b6b2f8 100644 --- a/lib/tsserverlibrary.js +++ b/lib/tsserverlibrary.js @@ -196,7 +196,17 @@ var ts; return undefined; } ts.forEach = forEach; - function find(array, callback) { + function find(array, predicate) { + for (var i = 0, len = array.length; i < len; i++) { + var value = array[i]; + if (predicate(value, i)) { + return value; + } + } + return undefined; + } + ts.find = find; + function findMap(array, callback) { for (var i = 0, len = array.length; i < len; i++) { var result = callback(array[i], i); if (result) { @@ -205,7 +215,7 @@ var ts; } Debug.fail(); } - ts.find = find; + ts.findMap = findMap; function contains(array, value) { if (array) { for (var _i = 0, array_1 = array; _i < array_1.length; _i++) { @@ -1163,6 +1173,7 @@ var ts; } ts.getScriptKindFromFileName = getScriptKindFromFileName; ts.supportedTypeScriptExtensions = [".ts", ".tsx", ".d.ts"]; + ts.supportedTypescriptExtensionsForExtractExtension = [".d.ts", ".ts", ".tsx"]; ts.supportedJavascriptExtensions = [".js", ".jsx"]; var allSupportedExtensions = ts.supportedTypeScriptExtensions.concat(ts.supportedJavascriptExtensions); function getSupportedExtensions(options) { @@ -1225,9 +1236,13 @@ var ts; } ts.removeFileExtension = removeFileExtension; function tryRemoveExtension(path, extension) { - return fileExtensionIs(path, extension) ? path.substring(0, path.length - extension.length) : undefined; + return fileExtensionIs(path, extension) ? removeExtension(path, extension) : undefined; } ts.tryRemoveExtension = tryRemoveExtension; + function removeExtension(path, extension) { + return path.substring(0, path.length - extension.length); + } + ts.removeExtension = removeExtension; function isJsxOrTsxExtension(ext) { return ext === ".jsx" || ext === ".tsx"; } @@ -2232,6 +2247,7 @@ var ts; Cannot_find_type_definition_file_for_0: { code: 2688, category: ts.DiagnosticCategory.Error, key: "Cannot_find_type_definition_file_for_0_2688", message: "Cannot find type definition file for '{0}'." }, Cannot_extend_an_interface_0_Did_you_mean_implements: { code: 2689, category: ts.DiagnosticCategory.Error, key: "Cannot_extend_an_interface_0_Did_you_mean_implements_2689", message: "Cannot extend an interface '{0}'. Did you mean 'implements'?" }, A_class_must_be_declared_after_its_base_class: { code: 2690, category: ts.DiagnosticCategory.Error, key: "A_class_must_be_declared_after_its_base_class_2690", message: "A class must be declared after its base class." }, + An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead: { code: 2691, category: ts.DiagnosticCategory.Error, key: "An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead_2691", message: "An import path cannot end with a '{0}' extension. Consider importing '{1}' instead." }, 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}'." }, @@ -7226,6 +7242,10 @@ var ts; return ts.forEach(ts.supportedTypeScriptExtensions, function (extension) { return ts.fileExtensionIs(fileName, extension); }); } ts.hasTypeScriptFileExtension = hasTypeScriptFileExtension; + function tryExtractTypeScriptExtension(fileName) { + return ts.find(ts.supportedTypescriptExtensionsForExtractExtension, function (extension) { return ts.fileExtensionIs(fileName, extension); }); + } + ts.tryExtractTypeScriptExtension = tryExtractTypeScriptExtension; function getExpandedCharCodes(input) { var output = []; var length = input.length; @@ -9833,6 +9853,8 @@ var ts; return parseTypeOfExpression(); case 103: return parseVoidExpression(); + case 119: + return parseAwaitExpression(); case 25: return parseTypeAssertion(); default: @@ -14898,7 +14920,7 @@ var ts; } } function getDeclarationOfAliasSymbol(symbol) { - return ts.find(symbol.declarations, function (d) { return ts.isAliasSymbolDeclaration(d) ? d : undefined; }); + return ts.findMap(symbol.declarations, function (d) { return ts.isAliasSymbolDeclaration(d) ? d : undefined; }); } function getTargetOfImportEqualsDeclaration(node) { if (node.moduleReference.kind === 240) { @@ -15158,7 +15180,14 @@ var ts; } } if (moduleNotFoundError) { - error(moduleReferenceLiteral, moduleNotFoundError, moduleName); + var tsExtension = ts.tryExtractTypeScriptExtension(moduleName); + if (tsExtension) { + var diag = ts.Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead; + error(moduleReferenceLiteral, diag, tsExtension, ts.removeExtension(moduleName, tsExtension)); + } + else { + error(moduleReferenceLiteral, moduleNotFoundError, moduleName); + } } return undefined; } @@ -16522,25 +16551,23 @@ var ts; return checkIdentifier(declaration.name); } if (ts.isBindingPattern(declaration.name)) { - return getTypeFromBindingPattern(declaration.name, false); + return getTypeFromBindingPattern(declaration.name, false, true); } return undefined; } - function getTypeFromBindingElement(element, includePatternInType) { + function getTypeFromBindingElement(element, includePatternInType, reportErrors) { if (element.initializer) { - var type = checkExpressionCached(element.initializer); - reportErrorsFromWidening(element, type); - return getWidenedType(type); + return checkExpressionCached(element.initializer); } if (ts.isBindingPattern(element.name)) { - return getTypeFromBindingPattern(element.name, includePatternInType); + return getTypeFromBindingPattern(element.name, includePatternInType, reportErrors); } - if (compilerOptions.noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) { + if (reportErrors && compilerOptions.noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) { reportImplicitAnyError(element, anyType); } return anyType; } - function getTypeFromObjectBindingPattern(pattern, includePatternInType) { + function getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors) { var members = ts.createMap(); var hasComputedProperties = false; ts.forEach(pattern.elements, function (e) { @@ -16552,7 +16579,7 @@ var ts; var text = getTextOfPropertyName(name); var flags = 4 | 67108864 | (e.initializer ? 536870912 : 0); var symbol = createSymbol(flags, text); - symbol.type = getTypeFromBindingElement(e, includePatternInType); + symbol.type = getTypeFromBindingElement(e, includePatternInType, reportErrors); symbol.bindingElement = e; members[symbol.name] = symbol; }); @@ -16565,12 +16592,12 @@ var ts; } return result; } - function getTypeFromArrayBindingPattern(pattern, includePatternInType) { + function getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors) { var elements = pattern.elements; if (elements.length === 0 || elements[elements.length - 1].dotDotDotToken) { return languageVersion >= 2 ? createIterableType(anyType) : anyArrayType; } - var elementTypes = ts.map(elements, function (e) { return e.kind === 193 ? anyType : getTypeFromBindingElement(e, includePatternInType); }); + var elementTypes = ts.map(elements, function (e) { return e.kind === 193 ? anyType : getTypeFromBindingElement(e, includePatternInType, reportErrors); }); if (includePatternInType) { var result = createNewTupleType(elementTypes); result.pattern = pattern; @@ -16578,10 +16605,10 @@ var ts; } return createTupleType(elementTypes); } - function getTypeFromBindingPattern(pattern, includePatternInType) { + function getTypeFromBindingPattern(pattern, includePatternInType, reportErrors) { return pattern.kind === 167 - ? getTypeFromObjectBindingPattern(pattern, includePatternInType) - : getTypeFromArrayBindingPattern(pattern, includePatternInType); + ? getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors) + : getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors); } function getWidenedTypeForVariableLikeDeclaration(declaration, reportErrors) { var type = getTypeForVariableLikeDeclaration(declaration, true); @@ -21645,7 +21672,7 @@ var ts; } } if (ts.isBindingPattern(declaration.name)) { - return getTypeFromBindingPattern(declaration.name, true); + return getTypeFromBindingPattern(declaration.name, true, false); } if (ts.isBindingPattern(declaration.parent)) { var parentDeclaration = declaration.parent.parent; @@ -25012,12 +25039,7 @@ var ts; checkSignatureDeclaration(node); if (node.kind === 149) { if (!ts.isInAmbientContext(node) && ts.nodeIsPresent(node.body) && (node.flags & 32768)) { - if (node.flags & 65536) { - if (compilerOptions.noImplicitReturns) { - error(node.name, ts.Diagnostics.Not_all_code_paths_return_a_value); - } - } - else { + if (!(node.flags & 65536)) { error(node.name, ts.Diagnostics.A_get_accessor_must_return_a_value); } } @@ -25039,7 +25061,10 @@ var ts; checkAccessorDeclarationTypesIdentical(node, otherAccessor, getThisTypeOfDeclaration, ts.Diagnostics.get_and_set_accessor_must_have_the_same_this_type); } } - getTypeOfAccessors(getSymbolOfNode(node)); + var returnType = getTypeOfAccessors(getSymbolOfNode(node)); + if (node.kind === 149) { + checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnType); + } } if (node.parent.kind !== 171) { checkSourceElement(node.body); @@ -37930,9 +37955,9 @@ var ts; } ts.directoryProbablyExists = directoryProbablyExists; function loadModuleFromFile(candidate, extensions, failedLookupLocation, onlyRecordFailures, state) { - var resolvedByAddingOrKeepingExtension = loadModuleFromFileWorker(candidate, extensions, failedLookupLocation, onlyRecordFailures, state); - if (resolvedByAddingOrKeepingExtension) { - return resolvedByAddingOrKeepingExtension; + var resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocation, onlyRecordFailures, state); + if (resolvedByAddingExtension) { + return resolvedByAddingExtension; } if (ts.hasJavaScriptFileExtension(candidate)) { var extensionless = ts.removeFileExtension(candidate); @@ -37940,35 +37965,33 @@ var ts; var extension = candidate.substring(extensionless.length); trace(state.host, ts.Diagnostics.File_name_0_has_a_1_extension_stripping_it, candidate, extension); } - return loadModuleFromFileWorker(extensionless, extensions, failedLookupLocation, onlyRecordFailures, state); + return tryAddingExtensions(extensionless, extensions, failedLookupLocation, onlyRecordFailures, state); } } - function loadModuleFromFileWorker(candidate, extensions, failedLookupLocation, onlyRecordFailures, state) { + function tryAddingExtensions(candidate, extensions, failedLookupLocation, onlyRecordFailures, state) { if (!onlyRecordFailures) { var directory = ts.getDirectoryPath(candidate); if (directory) { onlyRecordFailures = !directoryProbablyExists(directory, state.host); } } - return ts.forEach(extensions, tryLoad); - function tryLoad(ext) { - if (state.skipTsx && ts.isJsxOrTsxExtension(ext)) { - return undefined; + return ts.forEach(extensions, function (ext) { + return !(state.skipTsx && ts.isJsxOrTsxExtension(ext)) && tryFile(candidate + ext, failedLookupLocation, onlyRecordFailures, state); + }); + } + function tryFile(fileName, failedLookupLocation, onlyRecordFailures, state) { + if (!onlyRecordFailures && state.host.fileExists(fileName)) { + if (state.traceEnabled) { + trace(state.host, ts.Diagnostics.File_0_exist_use_it_as_a_name_resolution_result, fileName); } - var fileName = ts.fileExtensionIs(candidate, ext) ? candidate : candidate + ext; - if (!onlyRecordFailures && state.host.fileExists(fileName)) { - if (state.traceEnabled) { - trace(state.host, ts.Diagnostics.File_0_exist_use_it_as_a_name_resolution_result, fileName); - } - return fileName; - } - else { - if (state.traceEnabled) { - trace(state.host, ts.Diagnostics.File_0_does_not_exist, fileName); - } - failedLookupLocation.push(fileName); - return undefined; + return fileName; + } + else { + if (state.traceEnabled) { + trace(state.host, ts.Diagnostics.File_0_does_not_exist, fileName); } + failedLookupLocation.push(fileName); + return undefined; } } function loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocation, onlyRecordFailures, state) { @@ -37980,7 +38003,8 @@ var ts; } var typesFile = tryReadTypesSection(packageJsonPath, candidate, state); if (typesFile) { - var result = loadModuleFromFile(typesFile, extensions, failedLookupLocation, !directoryProbablyExists(ts.getDirectoryPath(typesFile), state.host), state); + var onlyRecordFailures_1 = !directoryProbablyExists(ts.getDirectoryPath(typesFile), state.host); + var result = tryFile(typesFile, failedLookupLocation, onlyRecordFailures_1, state); if (result) { return result; } @@ -47669,6 +47693,24 @@ var ts; } if (!documentation) { documentation = symbol.getDocumentationComment(); + if (documentation.length === 0 && symbol.flags & 4) { + if (symbol.parent && ts.forEach(symbol.parent.declarations, function (declaration) { return declaration.kind === 256; })) { + for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { + var declaration = _a[_i]; + if (!declaration.parent || declaration.parent.kind !== 187) { + continue; + } + var rhsSymbol = program.getTypeChecker().getSymbolAtLocation(declaration.parent.right); + if (!rhsSymbol) { + continue; + } + documentation = rhsSymbol.getDocumentationComment(); + if (documentation.length > 0) { + break; + } + } + } + } } return { displayParts: displayParts, documentation: documentation, symbolKind: symbolKind }; function addNewLineIfDisplayPartsExist() { diff --git a/lib/typescript.js b/lib/typescript.js index 2af3c3b4efd..3e7cc3d90ca 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -1103,8 +1103,22 @@ var ts; return undefined; } ts.forEach = forEach; - /** Like `forEach`, but assumes existence of array and fails if no truthy value is found. */ - function find(array, callback) { + /** Works like Array.prototype.find, returning `undefined` if no element satisfying the predicate is found. */ + function find(array, predicate) { + for (var i = 0, len = array.length; i < len; i++) { + var value = array[i]; + if (predicate(value, i)) { + return value; + } + } + return undefined; + } + ts.find = find; + /** + * Returns the first truthy result of `callback`, or else fails. + * This is like `forEach`, but never returns undefined. + */ + function findMap(array, callback) { for (var i = 0, len = array.length; i < len; i++) { var result = callback(array[i], i); if (result) { @@ -1113,7 +1127,7 @@ var ts; } Debug.fail(); } - ts.find = find; + ts.findMap = findMap; function contains(array, value) { if (array) { for (var _i = 0, array_1 = array; _i < array_1.length; _i++) { @@ -2239,6 +2253,8 @@ var ts; * List of supported extensions in order of file resolution precedence. */ ts.supportedTypeScriptExtensions = [".ts", ".tsx", ".d.ts"]; + /** Must have ".d.ts" first because if ".ts" goes first, that will be detected as the extension instead of ".d.ts". */ + ts.supportedTypescriptExtensionsForExtractExtension = [".d.ts", ".ts", ".tsx"]; ts.supportedJavascriptExtensions = [".js", ".jsx"]; var allSupportedExtensions = ts.supportedTypeScriptExtensions.concat(ts.supportedJavascriptExtensions); function getSupportedExtensions(options) { @@ -2322,9 +2338,13 @@ var ts; } ts.removeFileExtension = removeFileExtension; function tryRemoveExtension(path, extension) { - return fileExtensionIs(path, extension) ? path.substring(0, path.length - extension.length) : undefined; + return fileExtensionIs(path, extension) ? removeExtension(path, extension) : undefined; } ts.tryRemoveExtension = tryRemoveExtension; + function removeExtension(path, extension) { + return path.substring(0, path.length - extension.length); + } + ts.removeExtension = removeExtension; function isJsxOrTsxExtension(ext) { return ext === ".jsx" || ext === ".tsx"; } @@ -3374,6 +3394,7 @@ var ts; Cannot_find_type_definition_file_for_0: { code: 2688, category: ts.DiagnosticCategory.Error, key: "Cannot_find_type_definition_file_for_0_2688", message: "Cannot find type definition file for '{0}'." }, Cannot_extend_an_interface_0_Did_you_mean_implements: { code: 2689, category: ts.DiagnosticCategory.Error, key: "Cannot_extend_an_interface_0_Did_you_mean_implements_2689", message: "Cannot extend an interface '{0}'. Did you mean 'implements'?" }, A_class_must_be_declared_after_its_base_class: { code: 2690, category: ts.DiagnosticCategory.Error, key: "A_class_must_be_declared_after_its_base_class_2690", message: "A class must be declared after its base class." }, + An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead: { code: 2691, category: ts.DiagnosticCategory.Error, key: "An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead_2691", message: "An import path cannot end with a '{0}' extension. Consider importing '{1}' instead." }, 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}'." }, @@ -7813,6 +7834,11 @@ var ts; return ts.forEach(ts.supportedTypeScriptExtensions, function (extension) { return ts.fileExtensionIs(fileName, extension); }); } ts.hasTypeScriptFileExtension = hasTypeScriptFileExtension; + /** Return ".ts", ".d.ts", or ".tsx", if that is the extension. */ + function tryExtractTypeScriptExtension(fileName) { + return ts.find(ts.supportedTypescriptExtensionsForExtractExtension, function (extension) { return ts.fileExtensionIs(fileName, extension); }); + } + ts.tryExtractTypeScriptExtension = tryExtractTypeScriptExtension; /** * Replace each instance of non-ascii characters by one, two, three, or four escape sequences * representing the UTF-8 encoding of the character, and return the expanded char code list. @@ -11188,6 +11214,7 @@ var ts; * 6) - UnaryExpression[?yield] * 7) ~ UnaryExpression[?yield] * 8) ! UnaryExpression[?yield] + * 9) [+Await] await UnaryExpression[?yield] */ function parseSimpleUnaryExpression() { switch (token()) { @@ -11202,6 +11229,8 @@ var ts; return parseTypeOfExpression(); case 103 /* VoidKeyword */: return parseVoidExpression(); + case 119 /* AwaitKeyword */: + return parseAwaitExpression(); case 25 /* LessThanToken */: // This is modified UnaryExpression grammar in TypeScript // UnaryExpression (modified): @@ -17373,7 +17402,7 @@ var ts; } } function getDeclarationOfAliasSymbol(symbol) { - return ts.find(symbol.declarations, function (d) { return ts.isAliasSymbolDeclaration(d) ? d : undefined; }); + return ts.findMap(symbol.declarations, function (d) { return ts.isAliasSymbolDeclaration(d) ? d : undefined; }); } function getTargetOfImportEqualsDeclaration(node) { if (node.moduleReference.kind === 240 /* ExternalModuleReference */) { @@ -17677,7 +17706,14 @@ var ts; } if (moduleNotFoundError) { // report errors only if it was requested - error(moduleReferenceLiteral, moduleNotFoundError, moduleName); + var tsExtension = ts.tryExtractTypeScriptExtension(moduleName); + if (tsExtension) { + var diag = ts.Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead; + error(moduleReferenceLiteral, diag, tsExtension, ts.removeExtension(moduleName, tsExtension)); + } + else { + error(moduleReferenceLiteral, moduleNotFoundError, moduleName); + } } return undefined; } @@ -19227,7 +19263,7 @@ var ts; } // If the declaration specifies a binding pattern, use the type implied by the binding pattern if (ts.isBindingPattern(declaration.name)) { - return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ false); + return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ false, /*reportErrors*/ true); } // No type specified and nothing can be inferred return undefined; @@ -19235,22 +19271,20 @@ var ts; // Return the type implied by a binding pattern element. This is the type of the initializer of the element if // one is present. Otherwise, if the element is itself a binding pattern, it is the type implied by the binding // pattern. Otherwise, it is the type any. - function getTypeFromBindingElement(element, includePatternInType) { + function getTypeFromBindingElement(element, includePatternInType, reportErrors) { if (element.initializer) { - var type = checkExpressionCached(element.initializer); - reportErrorsFromWidening(element, type); - return getWidenedType(type); + return checkExpressionCached(element.initializer); } if (ts.isBindingPattern(element.name)) { - return getTypeFromBindingPattern(element.name, includePatternInType); + return getTypeFromBindingPattern(element.name, includePatternInType, reportErrors); } - if (compilerOptions.noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) { + if (reportErrors && compilerOptions.noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) { reportImplicitAnyError(element, anyType); } return anyType; } // Return the type implied by an object binding pattern - function getTypeFromObjectBindingPattern(pattern, includePatternInType) { + function getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors) { var members = ts.createMap(); var hasComputedProperties = false; ts.forEach(pattern.elements, function (e) { @@ -19263,7 +19297,7 @@ var ts; var text = getTextOfPropertyName(name); var flags = 4 /* Property */ | 67108864 /* Transient */ | (e.initializer ? 536870912 /* Optional */ : 0); var symbol = createSymbol(flags, text); - symbol.type = getTypeFromBindingElement(e, includePatternInType); + symbol.type = getTypeFromBindingElement(e, includePatternInType, reportErrors); symbol.bindingElement = e; members[symbol.name] = symbol; }); @@ -19277,13 +19311,13 @@ var ts; return result; } // Return the type implied by an array binding pattern - function getTypeFromArrayBindingPattern(pattern, includePatternInType) { + function getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors) { var elements = pattern.elements; if (elements.length === 0 || elements[elements.length - 1].dotDotDotToken) { return languageVersion >= 2 /* ES6 */ ? createIterableType(anyType) : anyArrayType; } // If the pattern has at least one element, and no rest element, then it should imply a tuple type. - var elementTypes = ts.map(elements, function (e) { return e.kind === 193 /* OmittedExpression */ ? anyType : getTypeFromBindingElement(e, includePatternInType); }); + var elementTypes = ts.map(elements, function (e) { return e.kind === 193 /* OmittedExpression */ ? anyType : getTypeFromBindingElement(e, includePatternInType, reportErrors); }); if (includePatternInType) { var result = createNewTupleType(elementTypes); result.pattern = pattern; @@ -19298,10 +19332,10 @@ var ts; // used as the contextual type of an initializer associated with the binding pattern. Also, for a destructuring // parameter with no type annotation or initializer, the type implied by the binding pattern becomes the type of // the parameter. - function getTypeFromBindingPattern(pattern, includePatternInType) { + function getTypeFromBindingPattern(pattern, includePatternInType, reportErrors) { return pattern.kind === 167 /* ObjectBindingPattern */ - ? getTypeFromObjectBindingPattern(pattern, includePatternInType) - : getTypeFromArrayBindingPattern(pattern, includePatternInType); + ? getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors) + : getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors); } // Return the type associated with a variable, parameter, or property declaration. In the simple case this is the type // specified in a type annotation or inferred from an initializer. However, in the case of a destructuring declaration it @@ -25069,7 +25103,7 @@ var ts; } } if (ts.isBindingPattern(declaration.name)) { - return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ true); + return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ true, /*reportErrors*/ false); } if (ts.isBindingPattern(declaration.parent)) { var parentDeclaration = declaration.parent.parent; @@ -29299,12 +29333,7 @@ var ts; checkSignatureDeclaration(node); if (node.kind === 149 /* GetAccessor */) { if (!ts.isInAmbientContext(node) && ts.nodeIsPresent(node.body) && (node.flags & 32768 /* HasImplicitReturn */)) { - if (node.flags & 65536 /* HasExplicitReturn */) { - if (compilerOptions.noImplicitReturns) { - error(node.name, ts.Diagnostics.Not_all_code_paths_return_a_value); - } - } - else { + if (!(node.flags & 65536 /* HasExplicitReturn */)) { error(node.name, ts.Diagnostics.A_get_accessor_must_return_a_value); } } @@ -29333,7 +29362,10 @@ var ts; checkAccessorDeclarationTypesIdentical(node, otherAccessor, getThisTypeOfDeclaration, ts.Diagnostics.get_and_set_accessor_must_have_the_same_this_type); } } - getTypeOfAccessors(getSymbolOfNode(node)); + var returnType = getTypeOfAccessors(getSymbolOfNode(node)); + if (node.kind === 149 /* GetAccessor */) { + checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnType); + } } if (node.parent.kind !== 171 /* ObjectLiteralExpression */) { checkSourceElement(node.body); @@ -44413,22 +44445,24 @@ var ts; * in cases when we know upfront that all load attempts will fail (because containing folder does not exists) however we still need to record all failed lookup locations. */ function loadModuleFromFile(candidate, extensions, failedLookupLocation, onlyRecordFailures, state) { - // First try to keep/add an extension: importing "./foo.ts" can be matched by a file "./foo.ts", and "./foo" by "./foo.d.ts" - var resolvedByAddingOrKeepingExtension = loadModuleFromFileWorker(candidate, extensions, failedLookupLocation, onlyRecordFailures, state); - if (resolvedByAddingOrKeepingExtension) { - return resolvedByAddingOrKeepingExtension; + // First, try adding an extension. An import of "foo" could be matched by a file "foo.ts", or "foo.js" by "foo.js.ts" + var resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocation, onlyRecordFailures, state); + if (resolvedByAddingExtension) { + return resolvedByAddingExtension; } - // Then try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one, e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts" + // If that didn't work, try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one; + // e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts" if (ts.hasJavaScriptFileExtension(candidate)) { var extensionless = ts.removeFileExtension(candidate); if (state.traceEnabled) { var extension = candidate.substring(extensionless.length); trace(state.host, ts.Diagnostics.File_name_0_has_a_1_extension_stripping_it, candidate, extension); } - return loadModuleFromFileWorker(extensionless, extensions, failedLookupLocation, onlyRecordFailures, state); + return tryAddingExtensions(extensionless, extensions, failedLookupLocation, onlyRecordFailures, state); } } - function loadModuleFromFileWorker(candidate, extensions, failedLookupLocation, onlyRecordFailures, state) { + /** Try to return an existing file that adds one of the `extensions` to `candidate`. */ + function tryAddingExtensions(candidate, extensions, failedLookupLocation, onlyRecordFailures, state) { if (!onlyRecordFailures) { // check if containing folder exists - if it doesn't then just record failures for all supported extensions without disk probing var directory = ts.getDirectoryPath(candidate); @@ -44436,25 +44470,24 @@ var ts; onlyRecordFailures = !directoryProbablyExists(directory, state.host); } } - return ts.forEach(extensions, tryLoad); - function tryLoad(ext) { - if (state.skipTsx && ts.isJsxOrTsxExtension(ext)) { - return undefined; + return ts.forEach(extensions, function (ext) { + return !(state.skipTsx && ts.isJsxOrTsxExtension(ext)) && tryFile(candidate + ext, failedLookupLocation, onlyRecordFailures, state); + }); + } + /** Return the file if it exists. */ + function tryFile(fileName, failedLookupLocation, onlyRecordFailures, state) { + if (!onlyRecordFailures && state.host.fileExists(fileName)) { + if (state.traceEnabled) { + trace(state.host, ts.Diagnostics.File_0_exist_use_it_as_a_name_resolution_result, fileName); } - var fileName = ts.fileExtensionIs(candidate, ext) ? candidate : candidate + ext; - if (!onlyRecordFailures && state.host.fileExists(fileName)) { - if (state.traceEnabled) { - trace(state.host, ts.Diagnostics.File_0_exist_use_it_as_a_name_resolution_result, fileName); - } - return fileName; - } - else { - if (state.traceEnabled) { - trace(state.host, ts.Diagnostics.File_0_does_not_exist, fileName); - } - failedLookupLocation.push(fileName); - return undefined; + return fileName; + } + else { + if (state.traceEnabled) { + trace(state.host, ts.Diagnostics.File_0_does_not_exist, fileName); } + failedLookupLocation.push(fileName); + return undefined; } } function loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocation, onlyRecordFailures, state) { @@ -44466,7 +44499,9 @@ var ts; } var typesFile = tryReadTypesSection(packageJsonPath, candidate, state); if (typesFile) { - var result = loadModuleFromFile(typesFile, extensions, failedLookupLocation, !directoryProbablyExists(ts.getDirectoryPath(typesFile), state.host), state); + var onlyRecordFailures_1 = !directoryProbablyExists(ts.getDirectoryPath(typesFile), state.host); + // The package.json "typings" property must specify the file with extension, so just try that exact filename. + var result = tryFile(typesFile, failedLookupLocation, onlyRecordFailures_1, state); if (result) { return result; } @@ -56673,6 +56708,27 @@ var ts; } if (!documentation) { documentation = symbol.getDocumentationComment(); + if (documentation.length === 0 && symbol.flags & 4 /* Property */) { + // For some special property access expressions like `experts.foo = foo` or `module.exports.foo = foo` + // there documentation comments might be attached to the right hand side symbol of their declarations. + // The pattern of such special property access is that the parent symbol is the symbol of the file. + if (symbol.parent && ts.forEach(symbol.parent.declarations, function (declaration) { return declaration.kind === 256 /* SourceFile */; })) { + for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { + var declaration = _a[_i]; + if (!declaration.parent || declaration.parent.kind !== 187 /* BinaryExpression */) { + continue; + } + var rhsSymbol = program.getTypeChecker().getSymbolAtLocation(declaration.parent.right); + if (!rhsSymbol) { + continue; + } + documentation = rhsSymbol.getDocumentationComment(); + if (documentation.length > 0) { + break; + } + } + } + } } return { displayParts: displayParts, documentation: documentation, symbolKind: symbolKind }; function addNewLineIfDisplayPartsExist() { diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index 2af3c3b4efd..3e7cc3d90ca 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -1103,8 +1103,22 @@ var ts; return undefined; } ts.forEach = forEach; - /** Like `forEach`, but assumes existence of array and fails if no truthy value is found. */ - function find(array, callback) { + /** Works like Array.prototype.find, returning `undefined` if no element satisfying the predicate is found. */ + function find(array, predicate) { + for (var i = 0, len = array.length; i < len; i++) { + var value = array[i]; + if (predicate(value, i)) { + return value; + } + } + return undefined; + } + ts.find = find; + /** + * Returns the first truthy result of `callback`, or else fails. + * This is like `forEach`, but never returns undefined. + */ + function findMap(array, callback) { for (var i = 0, len = array.length; i < len; i++) { var result = callback(array[i], i); if (result) { @@ -1113,7 +1127,7 @@ var ts; } Debug.fail(); } - ts.find = find; + ts.findMap = findMap; function contains(array, value) { if (array) { for (var _i = 0, array_1 = array; _i < array_1.length; _i++) { @@ -2239,6 +2253,8 @@ var ts; * List of supported extensions in order of file resolution precedence. */ ts.supportedTypeScriptExtensions = [".ts", ".tsx", ".d.ts"]; + /** Must have ".d.ts" first because if ".ts" goes first, that will be detected as the extension instead of ".d.ts". */ + ts.supportedTypescriptExtensionsForExtractExtension = [".d.ts", ".ts", ".tsx"]; ts.supportedJavascriptExtensions = [".js", ".jsx"]; var allSupportedExtensions = ts.supportedTypeScriptExtensions.concat(ts.supportedJavascriptExtensions); function getSupportedExtensions(options) { @@ -2322,9 +2338,13 @@ var ts; } ts.removeFileExtension = removeFileExtension; function tryRemoveExtension(path, extension) { - return fileExtensionIs(path, extension) ? path.substring(0, path.length - extension.length) : undefined; + return fileExtensionIs(path, extension) ? removeExtension(path, extension) : undefined; } ts.tryRemoveExtension = tryRemoveExtension; + function removeExtension(path, extension) { + return path.substring(0, path.length - extension.length); + } + ts.removeExtension = removeExtension; function isJsxOrTsxExtension(ext) { return ext === ".jsx" || ext === ".tsx"; } @@ -3374,6 +3394,7 @@ var ts; Cannot_find_type_definition_file_for_0: { code: 2688, category: ts.DiagnosticCategory.Error, key: "Cannot_find_type_definition_file_for_0_2688", message: "Cannot find type definition file for '{0}'." }, Cannot_extend_an_interface_0_Did_you_mean_implements: { code: 2689, category: ts.DiagnosticCategory.Error, key: "Cannot_extend_an_interface_0_Did_you_mean_implements_2689", message: "Cannot extend an interface '{0}'. Did you mean 'implements'?" }, A_class_must_be_declared_after_its_base_class: { code: 2690, category: ts.DiagnosticCategory.Error, key: "A_class_must_be_declared_after_its_base_class_2690", message: "A class must be declared after its base class." }, + An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead: { code: 2691, category: ts.DiagnosticCategory.Error, key: "An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead_2691", message: "An import path cannot end with a '{0}' extension. Consider importing '{1}' instead." }, 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}'." }, @@ -7813,6 +7834,11 @@ var ts; return ts.forEach(ts.supportedTypeScriptExtensions, function (extension) { return ts.fileExtensionIs(fileName, extension); }); } ts.hasTypeScriptFileExtension = hasTypeScriptFileExtension; + /** Return ".ts", ".d.ts", or ".tsx", if that is the extension. */ + function tryExtractTypeScriptExtension(fileName) { + return ts.find(ts.supportedTypescriptExtensionsForExtractExtension, function (extension) { return ts.fileExtensionIs(fileName, extension); }); + } + ts.tryExtractTypeScriptExtension = tryExtractTypeScriptExtension; /** * Replace each instance of non-ascii characters by one, two, three, or four escape sequences * representing the UTF-8 encoding of the character, and return the expanded char code list. @@ -11188,6 +11214,7 @@ var ts; * 6) - UnaryExpression[?yield] * 7) ~ UnaryExpression[?yield] * 8) ! UnaryExpression[?yield] + * 9) [+Await] await UnaryExpression[?yield] */ function parseSimpleUnaryExpression() { switch (token()) { @@ -11202,6 +11229,8 @@ var ts; return parseTypeOfExpression(); case 103 /* VoidKeyword */: return parseVoidExpression(); + case 119 /* AwaitKeyword */: + return parseAwaitExpression(); case 25 /* LessThanToken */: // This is modified UnaryExpression grammar in TypeScript // UnaryExpression (modified): @@ -17373,7 +17402,7 @@ var ts; } } function getDeclarationOfAliasSymbol(symbol) { - return ts.find(symbol.declarations, function (d) { return ts.isAliasSymbolDeclaration(d) ? d : undefined; }); + return ts.findMap(symbol.declarations, function (d) { return ts.isAliasSymbolDeclaration(d) ? d : undefined; }); } function getTargetOfImportEqualsDeclaration(node) { if (node.moduleReference.kind === 240 /* ExternalModuleReference */) { @@ -17677,7 +17706,14 @@ var ts; } if (moduleNotFoundError) { // report errors only if it was requested - error(moduleReferenceLiteral, moduleNotFoundError, moduleName); + var tsExtension = ts.tryExtractTypeScriptExtension(moduleName); + if (tsExtension) { + var diag = ts.Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead; + error(moduleReferenceLiteral, diag, tsExtension, ts.removeExtension(moduleName, tsExtension)); + } + else { + error(moduleReferenceLiteral, moduleNotFoundError, moduleName); + } } return undefined; } @@ -19227,7 +19263,7 @@ var ts; } // If the declaration specifies a binding pattern, use the type implied by the binding pattern if (ts.isBindingPattern(declaration.name)) { - return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ false); + return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ false, /*reportErrors*/ true); } // No type specified and nothing can be inferred return undefined; @@ -19235,22 +19271,20 @@ var ts; // Return the type implied by a binding pattern element. This is the type of the initializer of the element if // one is present. Otherwise, if the element is itself a binding pattern, it is the type implied by the binding // pattern. Otherwise, it is the type any. - function getTypeFromBindingElement(element, includePatternInType) { + function getTypeFromBindingElement(element, includePatternInType, reportErrors) { if (element.initializer) { - var type = checkExpressionCached(element.initializer); - reportErrorsFromWidening(element, type); - return getWidenedType(type); + return checkExpressionCached(element.initializer); } if (ts.isBindingPattern(element.name)) { - return getTypeFromBindingPattern(element.name, includePatternInType); + return getTypeFromBindingPattern(element.name, includePatternInType, reportErrors); } - if (compilerOptions.noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) { + if (reportErrors && compilerOptions.noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) { reportImplicitAnyError(element, anyType); } return anyType; } // Return the type implied by an object binding pattern - function getTypeFromObjectBindingPattern(pattern, includePatternInType) { + function getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors) { var members = ts.createMap(); var hasComputedProperties = false; ts.forEach(pattern.elements, function (e) { @@ -19263,7 +19297,7 @@ var ts; var text = getTextOfPropertyName(name); var flags = 4 /* Property */ | 67108864 /* Transient */ | (e.initializer ? 536870912 /* Optional */ : 0); var symbol = createSymbol(flags, text); - symbol.type = getTypeFromBindingElement(e, includePatternInType); + symbol.type = getTypeFromBindingElement(e, includePatternInType, reportErrors); symbol.bindingElement = e; members[symbol.name] = symbol; }); @@ -19277,13 +19311,13 @@ var ts; return result; } // Return the type implied by an array binding pattern - function getTypeFromArrayBindingPattern(pattern, includePatternInType) { + function getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors) { var elements = pattern.elements; if (elements.length === 0 || elements[elements.length - 1].dotDotDotToken) { return languageVersion >= 2 /* ES6 */ ? createIterableType(anyType) : anyArrayType; } // If the pattern has at least one element, and no rest element, then it should imply a tuple type. - var elementTypes = ts.map(elements, function (e) { return e.kind === 193 /* OmittedExpression */ ? anyType : getTypeFromBindingElement(e, includePatternInType); }); + var elementTypes = ts.map(elements, function (e) { return e.kind === 193 /* OmittedExpression */ ? anyType : getTypeFromBindingElement(e, includePatternInType, reportErrors); }); if (includePatternInType) { var result = createNewTupleType(elementTypes); result.pattern = pattern; @@ -19298,10 +19332,10 @@ var ts; // used as the contextual type of an initializer associated with the binding pattern. Also, for a destructuring // parameter with no type annotation or initializer, the type implied by the binding pattern becomes the type of // the parameter. - function getTypeFromBindingPattern(pattern, includePatternInType) { + function getTypeFromBindingPattern(pattern, includePatternInType, reportErrors) { return pattern.kind === 167 /* ObjectBindingPattern */ - ? getTypeFromObjectBindingPattern(pattern, includePatternInType) - : getTypeFromArrayBindingPattern(pattern, includePatternInType); + ? getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors) + : getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors); } // Return the type associated with a variable, parameter, or property declaration. In the simple case this is the type // specified in a type annotation or inferred from an initializer. However, in the case of a destructuring declaration it @@ -25069,7 +25103,7 @@ var ts; } } if (ts.isBindingPattern(declaration.name)) { - return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ true); + return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ true, /*reportErrors*/ false); } if (ts.isBindingPattern(declaration.parent)) { var parentDeclaration = declaration.parent.parent; @@ -29299,12 +29333,7 @@ var ts; checkSignatureDeclaration(node); if (node.kind === 149 /* GetAccessor */) { if (!ts.isInAmbientContext(node) && ts.nodeIsPresent(node.body) && (node.flags & 32768 /* HasImplicitReturn */)) { - if (node.flags & 65536 /* HasExplicitReturn */) { - if (compilerOptions.noImplicitReturns) { - error(node.name, ts.Diagnostics.Not_all_code_paths_return_a_value); - } - } - else { + if (!(node.flags & 65536 /* HasExplicitReturn */)) { error(node.name, ts.Diagnostics.A_get_accessor_must_return_a_value); } } @@ -29333,7 +29362,10 @@ var ts; checkAccessorDeclarationTypesIdentical(node, otherAccessor, getThisTypeOfDeclaration, ts.Diagnostics.get_and_set_accessor_must_have_the_same_this_type); } } - getTypeOfAccessors(getSymbolOfNode(node)); + var returnType = getTypeOfAccessors(getSymbolOfNode(node)); + if (node.kind === 149 /* GetAccessor */) { + checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnType); + } } if (node.parent.kind !== 171 /* ObjectLiteralExpression */) { checkSourceElement(node.body); @@ -44413,22 +44445,24 @@ var ts; * in cases when we know upfront that all load attempts will fail (because containing folder does not exists) however we still need to record all failed lookup locations. */ function loadModuleFromFile(candidate, extensions, failedLookupLocation, onlyRecordFailures, state) { - // First try to keep/add an extension: importing "./foo.ts" can be matched by a file "./foo.ts", and "./foo" by "./foo.d.ts" - var resolvedByAddingOrKeepingExtension = loadModuleFromFileWorker(candidate, extensions, failedLookupLocation, onlyRecordFailures, state); - if (resolvedByAddingOrKeepingExtension) { - return resolvedByAddingOrKeepingExtension; + // First, try adding an extension. An import of "foo" could be matched by a file "foo.ts", or "foo.js" by "foo.js.ts" + var resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocation, onlyRecordFailures, state); + if (resolvedByAddingExtension) { + return resolvedByAddingExtension; } - // Then try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one, e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts" + // If that didn't work, try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one; + // e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts" if (ts.hasJavaScriptFileExtension(candidate)) { var extensionless = ts.removeFileExtension(candidate); if (state.traceEnabled) { var extension = candidate.substring(extensionless.length); trace(state.host, ts.Diagnostics.File_name_0_has_a_1_extension_stripping_it, candidate, extension); } - return loadModuleFromFileWorker(extensionless, extensions, failedLookupLocation, onlyRecordFailures, state); + return tryAddingExtensions(extensionless, extensions, failedLookupLocation, onlyRecordFailures, state); } } - function loadModuleFromFileWorker(candidate, extensions, failedLookupLocation, onlyRecordFailures, state) { + /** Try to return an existing file that adds one of the `extensions` to `candidate`. */ + function tryAddingExtensions(candidate, extensions, failedLookupLocation, onlyRecordFailures, state) { if (!onlyRecordFailures) { // check if containing folder exists - if it doesn't then just record failures for all supported extensions without disk probing var directory = ts.getDirectoryPath(candidate); @@ -44436,25 +44470,24 @@ var ts; onlyRecordFailures = !directoryProbablyExists(directory, state.host); } } - return ts.forEach(extensions, tryLoad); - function tryLoad(ext) { - if (state.skipTsx && ts.isJsxOrTsxExtension(ext)) { - return undefined; + return ts.forEach(extensions, function (ext) { + return !(state.skipTsx && ts.isJsxOrTsxExtension(ext)) && tryFile(candidate + ext, failedLookupLocation, onlyRecordFailures, state); + }); + } + /** Return the file if it exists. */ + function tryFile(fileName, failedLookupLocation, onlyRecordFailures, state) { + if (!onlyRecordFailures && state.host.fileExists(fileName)) { + if (state.traceEnabled) { + trace(state.host, ts.Diagnostics.File_0_exist_use_it_as_a_name_resolution_result, fileName); } - var fileName = ts.fileExtensionIs(candidate, ext) ? candidate : candidate + ext; - if (!onlyRecordFailures && state.host.fileExists(fileName)) { - if (state.traceEnabled) { - trace(state.host, ts.Diagnostics.File_0_exist_use_it_as_a_name_resolution_result, fileName); - } - return fileName; - } - else { - if (state.traceEnabled) { - trace(state.host, ts.Diagnostics.File_0_does_not_exist, fileName); - } - failedLookupLocation.push(fileName); - return undefined; + return fileName; + } + else { + if (state.traceEnabled) { + trace(state.host, ts.Diagnostics.File_0_does_not_exist, fileName); } + failedLookupLocation.push(fileName); + return undefined; } } function loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocation, onlyRecordFailures, state) { @@ -44466,7 +44499,9 @@ var ts; } var typesFile = tryReadTypesSection(packageJsonPath, candidate, state); if (typesFile) { - var result = loadModuleFromFile(typesFile, extensions, failedLookupLocation, !directoryProbablyExists(ts.getDirectoryPath(typesFile), state.host), state); + var onlyRecordFailures_1 = !directoryProbablyExists(ts.getDirectoryPath(typesFile), state.host); + // The package.json "typings" property must specify the file with extension, so just try that exact filename. + var result = tryFile(typesFile, failedLookupLocation, onlyRecordFailures_1, state); if (result) { return result; } @@ -56673,6 +56708,27 @@ var ts; } if (!documentation) { documentation = symbol.getDocumentationComment(); + if (documentation.length === 0 && symbol.flags & 4 /* Property */) { + // For some special property access expressions like `experts.foo = foo` or `module.exports.foo = foo` + // there documentation comments might be attached to the right hand side symbol of their declarations. + // The pattern of such special property access is that the parent symbol is the symbol of the file. + if (symbol.parent && ts.forEach(symbol.parent.declarations, function (declaration) { return declaration.kind === 256 /* SourceFile */; })) { + for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { + var declaration = _a[_i]; + if (!declaration.parent || declaration.parent.kind !== 187 /* BinaryExpression */) { + continue; + } + var rhsSymbol = program.getTypeChecker().getSymbolAtLocation(declaration.parent.right); + if (!rhsSymbol) { + continue; + } + documentation = rhsSymbol.getDocumentationComment(); + if (documentation.length > 0) { + break; + } + } + } + } } return { displayParts: displayParts, documentation: documentation, symbolKind: symbolKind }; function addNewLineIfDisplayPartsExist() {