diff --git a/lib/enu/diagnosticMessages.generated.json.lcg b/lib/enu/diagnosticMessages.generated.json.lcg index 9461d804a55..08cdefa406b 100644 --- a/lib/enu/diagnosticMessages.generated.json.lcg +++ b/lib/enu/diagnosticMessages.generated.json.lcg @@ -2829,6 +2829,12 @@ + + + + + + diff --git a/lib/tsc.js b/lib/tsc.js index f3a0d54a123..3ac2732a3a7 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -170,7 +170,7 @@ var ts; var ts; (function (ts) { ts.versionMajorMinor = "2.8"; - ts.version = ts.versionMajorMinor + ".0"; + ts.version = ts.versionMajorMinor + ".1"; })(ts || (ts = {})); (function (ts) { function isExternalModuleNameRelative(moduleName) { @@ -3149,10 +3149,14 @@ var ts; close: function () { return _fs.unwatchFile(fileName, fileChanged); } }; function fileChanged(curr, prev) { + var isPreviouslyDeleted = +prev.mtime === 0 || eventKind === FileWatcherEventKind.Deleted; if (+curr.mtime === 0) { + if (isPreviouslyDeleted) { + return; + } eventKind = FileWatcherEventKind.Deleted; } - else if (+prev.mtime === 0 || eventKind === FileWatcherEventKind.Deleted) { + else if (isPreviouslyDeleted) { eventKind = FileWatcherEventKind.Created; } else if (+curr.mtime === +prev.mtime) { @@ -4363,6 +4367,7 @@ var ts; Expected_0_type_arguments_provide_these_with_an_extends_tag: diag(8026, ts.DiagnosticCategory.Error, "Expected_0_type_arguments_provide_these_with_an_extends_tag_8026", "Expected {0} type arguments; provide these with an '@extends' tag."), Expected_0_1_type_arguments_provide_these_with_an_extends_tag: diag(8027, ts.DiagnosticCategory.Error, "Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027", "Expected {0}-{1} type arguments; provide these with an '@extends' tag."), JSDoc_may_only_appear_in_the_last_parameter_of_a_signature: diag(8028, ts.DiagnosticCategory.Error, "JSDoc_may_only_appear_in_the_last_parameter_of_a_signature_8028", "JSDoc '...' may only appear in the last parameter of a signature."), + JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type: diag(8029, ts.DiagnosticCategory.Error, "JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_h_8029", "JSDoc '@param' tag has name '{0}', but there is no parameter with that name. It would match 'arguments' if it had an array type."), Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clause: diag(9002, ts.DiagnosticCategory.Error, "Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_clas_9002", "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause."), class_expressions_are_not_currently_supported: diag(9003, ts.DiagnosticCategory.Error, "class_expressions_are_not_currently_supported_9003", "'class' expressions are not currently supported."), Language_service_is_disabled: diag(9004, ts.DiagnosticCategory.Error, "Language_service_is_disabled_9004", "Language service is disabled."), @@ -16596,7 +16601,6 @@ var ts; var parent; var container; var blockScopeContainer; - var inferenceContainer; var lastContainer; var seenThisKeyword; var currentFlow; @@ -16640,7 +16644,6 @@ var ts; parent = undefined; container = undefined; blockScopeContainer = undefined; - inferenceContainer = undefined; lastContainer = undefined; seenThisKeyword = false; currentFlow = undefined; @@ -16900,13 +16903,6 @@ var ts; bindChildren(node); node.flags = seenThisKeyword ? node.flags | 64 : node.flags & ~64; } - else if (containerFlags & 256) { - var saveInferenceContainer = inferenceContainer; - inferenceContainer = node; - node.locals = undefined; - bindChildren(node); - inferenceContainer = saveInferenceContainer; - } else { bindChildren(node); } @@ -17656,8 +17652,6 @@ var ts; case 235: case 176: return 1 | 32; - case 170: - return 256; case 272: return 1 | 4 | 32; case 153: @@ -18533,13 +18527,24 @@ var ts; ? bindAnonymousDeclaration(node, symbolFlags, "__computed") : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); } + function getInferTypeContainer(node) { + while (node) { + var parent_2 = node.parent; + if (parent_2 && parent_2.kind === 170 && parent_2.extendsType === node) { + return parent_2; + } + node = parent_2; + } + return undefined; + } function bindTypeParameter(node) { if (node.parent.kind === 171) { - if (inferenceContainer) { - if (!inferenceContainer.locals) { - inferenceContainer.locals = ts.createSymbolTable(); + var container_1 = getInferTypeContainer(node.parent); + if (container_1) { + if (!container_1.locals) { + container_1.locals = ts.createSymbolTable(); } - declareSymbol(inferenceContainer.locals, undefined, node, 262144, 67639784); + declareSymbol(container_1.locals, undefined, node, 262144, 67639784); } else { bindAnonymousDeclaration(node, 262144, getDeclarationName(node)); @@ -21902,6 +21907,7 @@ var ts; } if (namespace.valueDeclaration && ts.isVariableDeclaration(namespace.valueDeclaration) && + namespace.valueDeclaration.initializer && isCommonJsRequire(namespace.valueDeclaration.initializer)) { var moduleName = namespace.valueDeclaration.initializer.arguments[0]; var moduleSym = resolveExternalModuleName(moduleName, moduleName); @@ -22570,7 +22576,8 @@ var ts; flags: flags, tracker: tracker && tracker.trackSymbol ? tracker : { trackSymbol: ts.noop }, encounteredError: false, - symbolStack: undefined + symbolStack: undefined, + inferTypeParameters: undefined }; } function typeToTypeNodeHelper(type, context) { @@ -22657,6 +22664,9 @@ var ts; return typeReferenceToTypeNode(type); } if (type.flags & 32768 || objectFlags & 3) { + if (type.flags & 32768 && ts.contains(context.inferTypeParameters, type)) { + return ts.createInferTypeNode(ts.createTypeParameterDeclaration(getNameOfSymbolAsWritten(type.symbol))); + } var name = type.symbol ? symbolToName(type.symbol, context, 67901928, false) : ts.createIdentifier("?"); return ts.createTypeReferenceNode(name, undefined); } @@ -22695,13 +22705,16 @@ var ts; } if (type.flags & 2097152) { var checkTypeNode = typeToTypeNodeHelper(type.checkType, context); + var saveInferTypeParameters = context.inferTypeParameters; + context.inferTypeParameters = type.root.inferTypeParameters; var extendsTypeNode = typeToTypeNodeHelper(type.extendsType, context); + context.inferTypeParameters = saveInferTypeParameters; var trueTypeNode = typeToTypeNodeHelper(getTrueTypeFromConditionalType(type), context); var falseTypeNode = typeToTypeNodeHelper(getFalseTypeFromConditionalType(type), context); return ts.createConditionalTypeNode(checkTypeNode, extendsTypeNode, trueTypeNode, falseTypeNode); } if (type.flags & 4194304) { - return typeToTypeNodeHelper(type.typeParameter, context); + return typeToTypeNodeHelper(type.typeVariable, context); } ts.Debug.fail("Should be unreachable."); function createMappedTypeNodeFromType(type) { @@ -23616,7 +23629,16 @@ var ts; if (ts.isBindingPattern(declaration.parent)) { return getTypeForBindingElement(declaration); } - var isOptional = !ts.isBindingElement(declaration) && !ts.isVariableDeclaration(declaration) && !!declaration.questionToken && includeOptionality; + var isOptional = false; + if (includeOptionality) { + if (ts.isInJavaScriptFile(declaration) && ts.isParameter(declaration)) { + var parameterTags = ts.getJSDocParameterTags(declaration); + isOptional = !!(parameterTags && parameterTags.length > 0 && ts.find(parameterTags, function (tag) { return tag.isBracketed; })); + } + if (!ts.isBindingElement(declaration) && !ts.isVariableDeclaration(declaration) && !!declaration.questionToken) { + isOptional = true; + } + } var declaredType = tryGetTypeFromEffectiveTypeNode(declaration); if (declaredType) { return addOptionality(declaredType, isOptional); @@ -25674,14 +25696,14 @@ var ts; return links.resolvedSignature; } function maybeAddJsSyntheticRestParameter(declaration, parameters) { + if (!containsArgumentsReference(declaration)) { + return false; + } var lastParam = ts.lastOrUndefined(declaration.parameters); - var lastParamTags = lastParam && ts.getJSDocParameterTags(lastParam); + var lastParamTags = lastParam ? ts.getJSDocParameterTags(lastParam) : ts.getJSDocTags(declaration).filter(ts.isJSDocParameterTag); var lastParamVariadicType = ts.firstDefined(lastParamTags, function (p) { return p.typeExpression && ts.isJSDocVariadicType(p.typeExpression.type) ? p.typeExpression.type : undefined; }); - if (!lastParamVariadicType && !containsArgumentsReference(declaration)) { - return false; - } var syntheticArgsSymbol = createSymbol(3, "args"); syntheticArgsSymbol.type = lastParamVariadicType ? createArrayType(getTypeFromTypeNode(lastParamVariadicType.type)) : anyArrayType; syntheticArgsSymbol.isRestParameter = true; @@ -26121,7 +26143,7 @@ var ts; var res = tryGetDeclaredTypeOfSymbol(symbol); if (res) { return checkNoTypeArguments(node, symbol) ? - res.flags & 32768 ? getConstrainedTypeParameter(res, node) : res : + res.flags & 32768 ? getConstrainedTypeVariable(res, node) : res : unknownType; } if (!(symbol.flags & 67216319 && isJSDocTypeReference(node))) { @@ -26149,24 +26171,33 @@ var ts; return getInferredClassType(symbol); } } - function getSubstitutionType(typeParameter, substitute) { + function getSubstitutionType(typeVariable, substitute) { var result = createType(4194304); - result.typeParameter = typeParameter; + result.typeVariable = typeVariable; result.substitute = substitute; return result; } - function getConstrainedTypeParameter(typeParameter, node) { + function isUnaryTupleTypeNode(node) { + return node.kind === 167 && node.elementTypes.length === 1; + } + function getImpliedConstraint(typeVariable, checkNode, extendsNode) { + return isUnaryTupleTypeNode(checkNode) && isUnaryTupleTypeNode(extendsNode) ? getImpliedConstraint(typeVariable, checkNode.elementTypes[0], extendsNode.elementTypes[0]) : + getActualTypeVariable(getTypeFromTypeNode(checkNode)) === typeVariable ? getTypeFromTypeNode(extendsNode) : + undefined; + } + function getConstrainedTypeVariable(typeVariable, node) { var constraints; while (ts.isPartOfTypeNode(node)) { var parent = node.parent; if (parent.kind === 170 && node === parent.trueType) { - if (getTypeFromTypeNode(parent.checkType) === typeParameter) { - constraints = ts.append(constraints, getTypeFromTypeNode(parent.extendsType)); + var constraint = getImpliedConstraint(typeVariable, parent.checkType, parent.extendsType); + if (constraint) { + constraints = ts.append(constraints, constraint); } } node = parent; } - return constraints ? getSubstitutionType(typeParameter, getIntersectionType(ts.append(constraints, typeParameter))) : typeParameter; + return constraints ? getSubstitutionType(typeVariable, getIntersectionType(ts.append(constraints, typeVariable))) : typeVariable; } function isJSDocTypeReference(node) { return node.flags & 1048576 && node.kind === 161; @@ -26919,7 +26950,13 @@ var ts; function getTypeFromIndexedAccessTypeNode(node) { var links = getNodeLinks(node); if (!links.resolvedType) { - links.resolvedType = getIndexedAccessType(getTypeFromTypeNode(node.objectType), getTypeFromTypeNode(node.indexType), node); + var objectType = getTypeFromTypeNode(node.objectType); + var indexType = getTypeFromTypeNode(node.indexType); + var resolved = getIndexedAccessType(objectType, indexType, node); + links.resolvedType = resolved.flags & 1048576 && + resolved.objectType === objectType && + resolved.indexType === indexType ? + getConstrainedTypeVariable(resolved, node) : resolved; } return links.resolvedType; } @@ -26935,8 +26972,8 @@ var ts; } return links.resolvedType; } - function getActualTypeParameter(type) { - return type.flags & 4194304 ? type.typeParameter : type; + function getActualTypeVariable(type) { + return type.flags & 4194304 ? type.typeVariable : type; } function getConditionalType(root, mapper) { var checkType = instantiateType(root.checkType, mapper); @@ -26948,7 +26985,7 @@ var ts; var combinedMapper = void 0; if (root.inferTypeParameters) { var context = createInferenceContext(root.inferTypeParameters, undefined, 0); - inferTypes(context.inferences, checkType, extendsType, 16 | 32); + inferTypes(context.inferences, checkType, extendsType, 32 | 64); combinedMapper = combineTypeMappers(mapper, context); } if (checkType.flags & 1) { @@ -26962,7 +26999,7 @@ var ts; return instantiateType(root.trueType, combinedMapper || mapper); } } - var erasedCheckType = getActualTypeParameter(checkType); + var erasedCheckType = getActualTypeVariable(checkType); var result = createType(2097152); result.root = root; result.checkType = erasedCheckType; @@ -27257,9 +27294,10 @@ var ts; return getTypeFromIntersectionTypeNode(node); case 277: return getTypeFromJSDocNullableTypeNode(node); + case 279: + return addOptionality(getTypeFromTypeNode(node.type)); case 172: case 278: - case 279: case 274: return getTypeFromTypeNode(node.type); case 281: @@ -27452,8 +27490,8 @@ var ts; } function isTypeParameterPossiblyReferenced(tp, node) { if (tp.symbol && tp.symbol.declarations && tp.symbol.declarations.length === 1) { - var container_1 = tp.symbol.declarations[0].parent; - if (ts.findAncestor(node, function (n) { return n.kind === 211 ? "quit" : n === container_1; })) { + var container_2 = tp.symbol.declarations[0].parent; + if (ts.findAncestor(node, function (n) { return n.kind === 211 ? "quit" : n === container_2; })) { return ts.forEachChild(node, containsReference); } } @@ -27566,7 +27604,7 @@ var ts; return getConditionalTypeInstantiation(type, combineTypeMappers(type.mapper, mapper)); } if (type.flags & 4194304) { - return mapper(type.typeParameter); + return instantiateType(type.typeVariable, mapper); } } return type; @@ -28030,10 +28068,10 @@ var ts; target = target.regularType; } if (source.flags & 4194304) { - source = relation === definitelyAssignableRelation ? source.typeParameter : source.substitute; + source = relation === definitelyAssignableRelation ? source.typeVariable : source.substitute; } if (target.flags & 4194304) { - target = target.typeParameter; + target = target.typeVariable; } if (source === target) return -1; @@ -29634,7 +29672,7 @@ var ts; if (!couldContainTypeVariables(target)) { return; } - if (source.flags & 1) { + if (source === wildcardType) { var savePropagationType = propagationType; propagationType = source; inferFromTypes(target, target); @@ -29727,7 +29765,10 @@ var ts; else if ((isLiteralType(source) || source.flags & 2) && target.flags & 524288) { var empty = createEmptyObjectTypeFromStringLiteral(source); contravariant = !contravariant; + var savePriority = priority; + priority |= 16; inferFromTypes(empty, target.type); + priority = savePriority; contravariant = !contravariant; } else if (source.flags & 1048576 && target.flags & 1048576) { @@ -29769,7 +29810,7 @@ var ts; } } else { - if (!(priority & 16 && source.flags & (262144 | 7897088))) { + if (!(priority & 32 && source.flags & (262144 | 7897088))) { source = getApparentType(source); } if (source.flags & (65536 | 262144)) { @@ -29796,7 +29837,7 @@ var ts; } } function inferFromContravariantTypes(source, target) { - if (strictFunctionTypes || priority & 32) { + if (strictFunctionTypes || priority & 64) { contravariant = !contravariant; inferFromTypes(source, target); contravariant = !contravariant; @@ -29939,6 +29980,20 @@ var ts; } return candidates; } + function getContravariantInference(inference) { + return inference.priority & 28 ? getIntersectionType(inference.contraCandidates) : getCommonSubtype(inference.contraCandidates); + } + function getCovariantInference(inference, context, signature) { + var candidates = widenObjectLiteralCandidates(inference.candidates); + var widenLiteralTypes = inference.topLevel && + !hasPrimitiveConstraint(inference.typeParameter) && + (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter)); + var baseCandidates = widenLiteralTypes ? ts.sameMap(candidates, getWidenedLiteralType) : candidates; + var unwidenedType = context.flags & 1 || inference.priority & 28 ? + getUnionType(baseCandidates, 2) : + getCommonSupertype(baseCandidates); + return getWidenedType(unwidenedType); + } function getInferredType(context, index) { var inference = context.inferences[index]; var inferredType = inference.inferredType; @@ -29946,21 +30001,13 @@ var ts; var signature = context.signature; if (signature) { if (inference.candidates) { - var candidates = widenObjectLiteralCandidates(inference.candidates); - var widenLiteralTypes = inference.topLevel && - !hasPrimitiveConstraint(inference.typeParameter) && - (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter)); - var baseCandidates = widenLiteralTypes ? ts.sameMap(candidates, getWidenedLiteralType) : candidates; - var unwidenedType = context.flags & 1 || inference.priority & 12 ? - getUnionType(baseCandidates, 2) : - getCommonSupertype(baseCandidates); - inferredType = getWidenedType(unwidenedType); + inferredType = getCovariantInference(inference, context, signature); if (inferredType.flags & 16384 && inference.contraCandidates) { - inferredType = getCommonSubtype(inference.contraCandidates); + inferredType = getContravariantInference(inference); } } else if (inference.contraCandidates) { - inferredType = getCommonSubtype(inference.contraCandidates); + inferredType = getContravariantInference(inference); } else if (context.flags & 2) { inferredType = silentNeverType; @@ -36926,7 +36973,17 @@ var ts; function checkJSDocParameterTag(node) { checkSourceElement(node.typeExpression); if (!ts.getParameterSymbolFromJSDoc(node)) { - error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name, ts.idText(node.name.kind === 145 ? node.name.right : node.name)); + var decl = ts.getHostSignatureFromJSDoc(node); + if (decl) { + if (!containsArgumentsReference(decl)) { + error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name, ts.idText(node.name.kind === 145 ? node.name.right : node.name)); + } + else if (ts.findLast(ts.getJSDocTags(decl), ts.isJSDocParameterTag) === node && + node.typeExpression && node.typeExpression.type && + !isArrayType(getTypeFromTypeNode(node.typeExpression.type))) { + error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type, ts.idText(node.name.kind === 145 ? node.name.right : node.name)); + } + } } } function checkJSDocAugmentsTag(node) { @@ -39262,11 +39319,12 @@ var ts; var parent = node.parent; var paramTag = parent.parent; if (ts.isJSDocTypeExpression(parent) && ts.isJSDocParameterTag(paramTag)) { - var param = ts.getParameterSymbolFromJSDoc(paramTag); - if (param) { - var host_1 = ts.getHostSignatureFromJSDoc(paramTag); - var lastParamDeclaration = host_1 && ts.last(host_1.parameters); - if (lastParamDeclaration.symbol === param && ts.isRestParameter(lastParamDeclaration)) { + var host_1 = ts.getHostSignatureFromJSDoc(paramTag); + if (host_1) { + var lastParamDeclaration = ts.lastOrUndefined(host_1.parameters); + var symbol = ts.getParameterSymbolFromJSDoc(paramTag); + if (!lastParamDeclaration || + symbol && lastParamDeclaration.symbol === symbol && ts.isRestParameter(lastParamDeclaration)) { return createArrayType(type); } } @@ -63224,7 +63282,8 @@ var ts; } else { var dirOfFileOrDirectory = ts.getDirectoryPath(fileOrDirectoryPath); - if (isNodeModulesAtTypesDirectory(dirOfFileOrDirectory) || isNodeModulesDirectory(dirOfFileOrDirectory)) { + if (isNodeModulesAtTypesDirectory(fileOrDirectoryPath) || isNodeModulesDirectory(fileOrDirectoryPath) || + isNodeModulesAtTypesDirectory(dirOfFileOrDirectory) || isNodeModulesDirectory(dirOfFileOrDirectory)) { isChangedFailedLookupLocation = function (location) { var locationPath = resolutionHost.toPath(location); return locationPath === fileOrDirectoryPath || ts.startsWith(resolutionHost.toPath(location), fileOrDirectoryPath); diff --git a/lib/tsserver.js b/lib/tsserver.js index 2403ffe6232..3487eea899a 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -829,9 +829,10 @@ var ts; InferencePriority[InferencePriority["HomomorphicMappedType"] = 2] = "HomomorphicMappedType"; InferencePriority[InferencePriority["MappedTypeConstraint"] = 4] = "MappedTypeConstraint"; InferencePriority[InferencePriority["ReturnType"] = 8] = "ReturnType"; - InferencePriority[InferencePriority["NoConstraints"] = 16] = "NoConstraints"; - InferencePriority[InferencePriority["AlwaysStrict"] = 32] = "AlwaysStrict"; - InferencePriority[InferencePriority["PriorityImpliesUnion"] = 12] = "PriorityImpliesUnion"; + InferencePriority[InferencePriority["LiteralKeyof"] = 16] = "LiteralKeyof"; + InferencePriority[InferencePriority["NoConstraints"] = 32] = "NoConstraints"; + InferencePriority[InferencePriority["AlwaysStrict"] = 64] = "AlwaysStrict"; + InferencePriority[InferencePriority["PriorityImpliesCombination"] = 28] = "PriorityImpliesCombination"; })(InferencePriority = ts.InferencePriority || (ts.InferencePriority = {})); var InferenceFlags; (function (InferenceFlags) { @@ -1365,7 +1366,7 @@ var ts; var ts; (function (ts) { ts.versionMajorMinor = "2.8"; - ts.version = ts.versionMajorMinor + ".0"; + ts.version = ts.versionMajorMinor + ".1"; })(ts || (ts = {})); (function (ts) { function isExternalModuleNameRelative(moduleName) { @@ -4363,10 +4364,14 @@ var ts; close: function () { return _fs.unwatchFile(fileName, fileChanged); } }; function fileChanged(curr, prev) { + var isPreviouslyDeleted = +prev.mtime === 0 || eventKind === FileWatcherEventKind.Deleted; if (+curr.mtime === 0) { + if (isPreviouslyDeleted) { + return; + } eventKind = FileWatcherEventKind.Deleted; } - else if (+prev.mtime === 0 || eventKind === FileWatcherEventKind.Deleted) { + else if (isPreviouslyDeleted) { eventKind = FileWatcherEventKind.Created; } else if (+curr.mtime === +prev.mtime) { @@ -5577,6 +5582,7 @@ var ts; Expected_0_type_arguments_provide_these_with_an_extends_tag: diag(8026, ts.DiagnosticCategory.Error, "Expected_0_type_arguments_provide_these_with_an_extends_tag_8026", "Expected {0} type arguments; provide these with an '@extends' tag."), Expected_0_1_type_arguments_provide_these_with_an_extends_tag: diag(8027, ts.DiagnosticCategory.Error, "Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027", "Expected {0}-{1} type arguments; provide these with an '@extends' tag."), JSDoc_may_only_appear_in_the_last_parameter_of_a_signature: diag(8028, ts.DiagnosticCategory.Error, "JSDoc_may_only_appear_in_the_last_parameter_of_a_signature_8028", "JSDoc '...' may only appear in the last parameter of a signature."), + JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type: diag(8029, ts.DiagnosticCategory.Error, "JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_h_8029", "JSDoc '@param' tag has name '{0}', but there is no parameter with that name. It would match 'arguments' if it had an array type."), Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clause: diag(9002, ts.DiagnosticCategory.Error, "Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_clas_9002", "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause."), class_expressions_are_not_currently_supported: diag(9003, ts.DiagnosticCategory.Error, "class_expressions_are_not_currently_supported_9003", "'class' expressions are not currently supported."), Language_service_is_disabled: diag(9004, ts.DiagnosticCategory.Error, "Language_service_is_disabled_9004", "Language service is disabled."), @@ -18793,7 +18799,6 @@ var ts; ContainerFlags[ContainerFlags["HasLocals"] = 32] = "HasLocals"; ContainerFlags[ContainerFlags["IsInterface"] = 64] = "IsInterface"; ContainerFlags[ContainerFlags["IsObjectLiteralOrClassExpressionMethod"] = 128] = "IsObjectLiteralOrClassExpressionMethod"; - ContainerFlags[ContainerFlags["IsInferenceContainer"] = 256] = "IsInferenceContainer"; })(ContainerFlags || (ContainerFlags = {})); var binder = createBinder(); function bindSourceFile(file, options) { @@ -18810,7 +18815,6 @@ var ts; var parent; var container; var blockScopeContainer; - var inferenceContainer; var lastContainer; var seenThisKeyword; var currentFlow; @@ -18854,7 +18858,6 @@ var ts; parent = undefined; container = undefined; blockScopeContainer = undefined; - inferenceContainer = undefined; lastContainer = undefined; seenThisKeyword = false; currentFlow = undefined; @@ -19114,13 +19117,6 @@ var ts; bindChildren(node); node.flags = seenThisKeyword ? node.flags | 64 : node.flags & ~64; } - else if (containerFlags & 256) { - var saveInferenceContainer = inferenceContainer; - inferenceContainer = node; - node.locals = undefined; - bindChildren(node); - inferenceContainer = saveInferenceContainer; - } else { bindChildren(node); } @@ -19870,8 +19866,6 @@ var ts; case 235: case 176: return 1 | 32; - case 170: - return 256; case 272: return 1 | 4 | 32; case 153: @@ -20752,13 +20746,24 @@ var ts; ? bindAnonymousDeclaration(node, symbolFlags, "__computed") : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); } + function getInferTypeContainer(node) { + while (node) { + var parent_2 = node.parent; + if (parent_2 && parent_2.kind === 170 && parent_2.extendsType === node) { + return parent_2; + } + node = parent_2; + } + return undefined; + } function bindTypeParameter(node) { if (node.parent.kind === 171) { - if (inferenceContainer) { - if (!inferenceContainer.locals) { - inferenceContainer.locals = ts.createSymbolTable(); + var container_1 = getInferTypeContainer(node.parent); + if (container_1) { + if (!container_1.locals) { + container_1.locals = ts.createSymbolTable(); } - declareSymbol(inferenceContainer.locals, undefined, node, 262144, 67639784); + declareSymbol(container_1.locals, undefined, node, 262144, 67639784); } else { bindAnonymousDeclaration(node, 262144, getDeclarationName(node)); @@ -23338,6 +23343,7 @@ var ts; } if (namespace.valueDeclaration && ts.isVariableDeclaration(namespace.valueDeclaration) && + namespace.valueDeclaration.initializer && isCommonJsRequire(namespace.valueDeclaration.initializer)) { var moduleName = namespace.valueDeclaration.initializer.arguments[0]; var moduleSym = resolveExternalModuleName(moduleName, moduleName); @@ -24006,7 +24012,8 @@ var ts; flags: flags, tracker: tracker && tracker.trackSymbol ? tracker : { trackSymbol: ts.noop }, encounteredError: false, - symbolStack: undefined + symbolStack: undefined, + inferTypeParameters: undefined }; } function typeToTypeNodeHelper(type, context) { @@ -24093,6 +24100,9 @@ var ts; return typeReferenceToTypeNode(type); } if (type.flags & 32768 || objectFlags & 3) { + if (type.flags & 32768 && ts.contains(context.inferTypeParameters, type)) { + return ts.createInferTypeNode(ts.createTypeParameterDeclaration(getNameOfSymbolAsWritten(type.symbol))); + } var name = type.symbol ? symbolToName(type.symbol, context, 67901928, false) : ts.createIdentifier("?"); return ts.createTypeReferenceNode(name, undefined); } @@ -24131,13 +24141,16 @@ var ts; } if (type.flags & 2097152) { var checkTypeNode = typeToTypeNodeHelper(type.checkType, context); + var saveInferTypeParameters = context.inferTypeParameters; + context.inferTypeParameters = type.root.inferTypeParameters; var extendsTypeNode = typeToTypeNodeHelper(type.extendsType, context); + context.inferTypeParameters = saveInferTypeParameters; var trueTypeNode = typeToTypeNodeHelper(getTrueTypeFromConditionalType(type), context); var falseTypeNode = typeToTypeNodeHelper(getFalseTypeFromConditionalType(type), context); return ts.createConditionalTypeNode(checkTypeNode, extendsTypeNode, trueTypeNode, falseTypeNode); } if (type.flags & 4194304) { - return typeToTypeNodeHelper(type.typeParameter, context); + return typeToTypeNodeHelper(type.typeVariable, context); } ts.Debug.fail("Should be unreachable."); function createMappedTypeNodeFromType(type) { @@ -25052,7 +25065,16 @@ var ts; if (ts.isBindingPattern(declaration.parent)) { return getTypeForBindingElement(declaration); } - var isOptional = !ts.isBindingElement(declaration) && !ts.isVariableDeclaration(declaration) && !!declaration.questionToken && includeOptionality; + var isOptional = false; + if (includeOptionality) { + if (ts.isInJavaScriptFile(declaration) && ts.isParameter(declaration)) { + var parameterTags = ts.getJSDocParameterTags(declaration); + isOptional = !!(parameterTags && parameterTags.length > 0 && ts.find(parameterTags, function (tag) { return tag.isBracketed; })); + } + if (!ts.isBindingElement(declaration) && !ts.isVariableDeclaration(declaration) && !!declaration.questionToken) { + isOptional = true; + } + } var declaredType = tryGetTypeFromEffectiveTypeNode(declaration); if (declaredType) { return addOptionality(declaredType, isOptional); @@ -27110,14 +27132,14 @@ var ts; return links.resolvedSignature; } function maybeAddJsSyntheticRestParameter(declaration, parameters) { + if (!containsArgumentsReference(declaration)) { + return false; + } var lastParam = ts.lastOrUndefined(declaration.parameters); - var lastParamTags = lastParam && ts.getJSDocParameterTags(lastParam); + var lastParamTags = lastParam ? ts.getJSDocParameterTags(lastParam) : ts.getJSDocTags(declaration).filter(ts.isJSDocParameterTag); var lastParamVariadicType = ts.firstDefined(lastParamTags, function (p) { return p.typeExpression && ts.isJSDocVariadicType(p.typeExpression.type) ? p.typeExpression.type : undefined; }); - if (!lastParamVariadicType && !containsArgumentsReference(declaration)) { - return false; - } var syntheticArgsSymbol = createSymbol(3, "args"); syntheticArgsSymbol.type = lastParamVariadicType ? createArrayType(getTypeFromTypeNode(lastParamVariadicType.type)) : anyArrayType; syntheticArgsSymbol.isRestParameter = true; @@ -27557,7 +27579,7 @@ var ts; var res = tryGetDeclaredTypeOfSymbol(symbol); if (res) { return checkNoTypeArguments(node, symbol) ? - res.flags & 32768 ? getConstrainedTypeParameter(res, node) : res : + res.flags & 32768 ? getConstrainedTypeVariable(res, node) : res : unknownType; } if (!(symbol.flags & 67216319 && isJSDocTypeReference(node))) { @@ -27585,24 +27607,33 @@ var ts; return getInferredClassType(symbol); } } - function getSubstitutionType(typeParameter, substitute) { + function getSubstitutionType(typeVariable, substitute) { var result = createType(4194304); - result.typeParameter = typeParameter; + result.typeVariable = typeVariable; result.substitute = substitute; return result; } - function getConstrainedTypeParameter(typeParameter, node) { + function isUnaryTupleTypeNode(node) { + return node.kind === 167 && node.elementTypes.length === 1; + } + function getImpliedConstraint(typeVariable, checkNode, extendsNode) { + return isUnaryTupleTypeNode(checkNode) && isUnaryTupleTypeNode(extendsNode) ? getImpliedConstraint(typeVariable, checkNode.elementTypes[0], extendsNode.elementTypes[0]) : + getActualTypeVariable(getTypeFromTypeNode(checkNode)) === typeVariable ? getTypeFromTypeNode(extendsNode) : + undefined; + } + function getConstrainedTypeVariable(typeVariable, node) { var constraints; while (ts.isPartOfTypeNode(node)) { var parent = node.parent; if (parent.kind === 170 && node === parent.trueType) { - if (getTypeFromTypeNode(parent.checkType) === typeParameter) { - constraints = ts.append(constraints, getTypeFromTypeNode(parent.extendsType)); + var constraint = getImpliedConstraint(typeVariable, parent.checkType, parent.extendsType); + if (constraint) { + constraints = ts.append(constraints, constraint); } } node = parent; } - return constraints ? getSubstitutionType(typeParameter, getIntersectionType(ts.append(constraints, typeParameter))) : typeParameter; + return constraints ? getSubstitutionType(typeVariable, getIntersectionType(ts.append(constraints, typeVariable))) : typeVariable; } function isJSDocTypeReference(node) { return node.flags & 1048576 && node.kind === 161; @@ -28355,7 +28386,13 @@ var ts; function getTypeFromIndexedAccessTypeNode(node) { var links = getNodeLinks(node); if (!links.resolvedType) { - links.resolvedType = getIndexedAccessType(getTypeFromTypeNode(node.objectType), getTypeFromTypeNode(node.indexType), node); + var objectType = getTypeFromTypeNode(node.objectType); + var indexType = getTypeFromTypeNode(node.indexType); + var resolved = getIndexedAccessType(objectType, indexType, node); + links.resolvedType = resolved.flags & 1048576 && + resolved.objectType === objectType && + resolved.indexType === indexType ? + getConstrainedTypeVariable(resolved, node) : resolved; } return links.resolvedType; } @@ -28371,8 +28408,8 @@ var ts; } return links.resolvedType; } - function getActualTypeParameter(type) { - return type.flags & 4194304 ? type.typeParameter : type; + function getActualTypeVariable(type) { + return type.flags & 4194304 ? type.typeVariable : type; } function getConditionalType(root, mapper) { var checkType = instantiateType(root.checkType, mapper); @@ -28384,7 +28421,7 @@ var ts; var combinedMapper = void 0; if (root.inferTypeParameters) { var context = createInferenceContext(root.inferTypeParameters, undefined, 0); - inferTypes(context.inferences, checkType, extendsType, 16 | 32); + inferTypes(context.inferences, checkType, extendsType, 32 | 64); combinedMapper = combineTypeMappers(mapper, context); } if (checkType.flags & 1) { @@ -28398,7 +28435,7 @@ var ts; return instantiateType(root.trueType, combinedMapper || mapper); } } - var erasedCheckType = getActualTypeParameter(checkType); + var erasedCheckType = getActualTypeVariable(checkType); var result = createType(2097152); result.root = root; result.checkType = erasedCheckType; @@ -28693,9 +28730,10 @@ var ts; return getTypeFromIntersectionTypeNode(node); case 277: return getTypeFromJSDocNullableTypeNode(node); + case 279: + return addOptionality(getTypeFromTypeNode(node.type)); case 172: case 278: - case 279: case 274: return getTypeFromTypeNode(node.type); case 281: @@ -28888,8 +28926,8 @@ var ts; } function isTypeParameterPossiblyReferenced(tp, node) { if (tp.symbol && tp.symbol.declarations && tp.symbol.declarations.length === 1) { - var container_1 = tp.symbol.declarations[0].parent; - if (ts.findAncestor(node, function (n) { return n.kind === 211 ? "quit" : n === container_1; })) { + var container_2 = tp.symbol.declarations[0].parent; + if (ts.findAncestor(node, function (n) { return n.kind === 211 ? "quit" : n === container_2; })) { return ts.forEachChild(node, containsReference); } } @@ -29002,7 +29040,7 @@ var ts; return getConditionalTypeInstantiation(type, combineTypeMappers(type.mapper, mapper)); } if (type.flags & 4194304) { - return mapper(type.typeParameter); + return instantiateType(type.typeVariable, mapper); } } return type; @@ -29466,10 +29504,10 @@ var ts; target = target.regularType; } if (source.flags & 4194304) { - source = relation === definitelyAssignableRelation ? source.typeParameter : source.substitute; + source = relation === definitelyAssignableRelation ? source.typeVariable : source.substitute; } if (target.flags & 4194304) { - target = target.typeParameter; + target = target.typeVariable; } if (source === target) return -1; @@ -31070,7 +31108,7 @@ var ts; if (!couldContainTypeVariables(target)) { return; } - if (source.flags & 1) { + if (source === wildcardType) { var savePropagationType = propagationType; propagationType = source; inferFromTypes(target, target); @@ -31163,7 +31201,10 @@ var ts; else if ((isLiteralType(source) || source.flags & 2) && target.flags & 524288) { var empty = createEmptyObjectTypeFromStringLiteral(source); contravariant = !contravariant; + var savePriority = priority; + priority |= 16; inferFromTypes(empty, target.type); + priority = savePriority; contravariant = !contravariant; } else if (source.flags & 1048576 && target.flags & 1048576) { @@ -31205,7 +31246,7 @@ var ts; } } else { - if (!(priority & 16 && source.flags & (262144 | 7897088))) { + if (!(priority & 32 && source.flags & (262144 | 7897088))) { source = getApparentType(source); } if (source.flags & (65536 | 262144)) { @@ -31232,7 +31273,7 @@ var ts; } } function inferFromContravariantTypes(source, target) { - if (strictFunctionTypes || priority & 32) { + if (strictFunctionTypes || priority & 64) { contravariant = !contravariant; inferFromTypes(source, target); contravariant = !contravariant; @@ -31375,6 +31416,20 @@ var ts; } return candidates; } + function getContravariantInference(inference) { + return inference.priority & 28 ? getIntersectionType(inference.contraCandidates) : getCommonSubtype(inference.contraCandidates); + } + function getCovariantInference(inference, context, signature) { + var candidates = widenObjectLiteralCandidates(inference.candidates); + var widenLiteralTypes = inference.topLevel && + !hasPrimitiveConstraint(inference.typeParameter) && + (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter)); + var baseCandidates = widenLiteralTypes ? ts.sameMap(candidates, getWidenedLiteralType) : candidates; + var unwidenedType = context.flags & 1 || inference.priority & 28 ? + getUnionType(baseCandidates, 2) : + getCommonSupertype(baseCandidates); + return getWidenedType(unwidenedType); + } function getInferredType(context, index) { var inference = context.inferences[index]; var inferredType = inference.inferredType; @@ -31382,21 +31437,13 @@ var ts; var signature = context.signature; if (signature) { if (inference.candidates) { - var candidates = widenObjectLiteralCandidates(inference.candidates); - var widenLiteralTypes = inference.topLevel && - !hasPrimitiveConstraint(inference.typeParameter) && - (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter)); - var baseCandidates = widenLiteralTypes ? ts.sameMap(candidates, getWidenedLiteralType) : candidates; - var unwidenedType = context.flags & 1 || inference.priority & 12 ? - getUnionType(baseCandidates, 2) : - getCommonSupertype(baseCandidates); - inferredType = getWidenedType(unwidenedType); + inferredType = getCovariantInference(inference, context, signature); if (inferredType.flags & 16384 && inference.contraCandidates) { - inferredType = getCommonSubtype(inference.contraCandidates); + inferredType = getContravariantInference(inference); } } else if (inference.contraCandidates) { - inferredType = getCommonSubtype(inference.contraCandidates); + inferredType = getContravariantInference(inference); } else if (context.flags & 2) { inferredType = silentNeverType; @@ -38376,7 +38423,17 @@ var ts; function checkJSDocParameterTag(node) { checkSourceElement(node.typeExpression); if (!ts.getParameterSymbolFromJSDoc(node)) { - error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name, ts.idText(node.name.kind === 145 ? node.name.right : node.name)); + var decl = ts.getHostSignatureFromJSDoc(node); + if (decl) { + if (!containsArgumentsReference(decl)) { + error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name, ts.idText(node.name.kind === 145 ? node.name.right : node.name)); + } + else if (ts.findLast(ts.getJSDocTags(decl), ts.isJSDocParameterTag) === node && + node.typeExpression && node.typeExpression.type && + !isArrayType(getTypeFromTypeNode(node.typeExpression.type))) { + error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type, ts.idText(node.name.kind === 145 ? node.name.right : node.name)); + } + } } } function checkJSDocAugmentsTag(node) { @@ -40712,11 +40769,12 @@ var ts; var parent = node.parent; var paramTag = parent.parent; if (ts.isJSDocTypeExpression(parent) && ts.isJSDocParameterTag(paramTag)) { - var param = ts.getParameterSymbolFromJSDoc(paramTag); - if (param) { - var host_1 = ts.getHostSignatureFromJSDoc(paramTag); - var lastParamDeclaration = host_1 && ts.last(host_1.parameters); - if (lastParamDeclaration.symbol === param && ts.isRestParameter(lastParamDeclaration)) { + var host_1 = ts.getHostSignatureFromJSDoc(paramTag); + if (host_1) { + var lastParamDeclaration = ts.lastOrUndefined(host_1.parameters); + var symbol = ts.getParameterSymbolFromJSDoc(paramTag); + if (!lastParamDeclaration || + symbol && lastParamDeclaration.symbol === symbol && ts.isRestParameter(lastParamDeclaration)) { return createArrayType(type); } } @@ -87152,7 +87210,8 @@ var ts; } else { var dirOfFileOrDirectory = ts.getDirectoryPath(fileOrDirectoryPath); - if (isNodeModulesAtTypesDirectory(dirOfFileOrDirectory) || isNodeModulesDirectory(dirOfFileOrDirectory)) { + if (isNodeModulesAtTypesDirectory(fileOrDirectoryPath) || isNodeModulesDirectory(fileOrDirectoryPath) || + isNodeModulesAtTypesDirectory(dirOfFileOrDirectory) || isNodeModulesDirectory(dirOfFileOrDirectory)) { isChangedFailedLookupLocation = function (location) { var locationPath = resolutionHost.toPath(location); return locationPath === fileOrDirectoryPath || ts.startsWith(resolutionHost.toPath(location), fileOrDirectoryPath); diff --git a/lib/tsserverlibrary.d.ts b/lib/tsserverlibrary.d.ts index 1048f338d92..a2f9506dc1c 100644 --- a/lib/tsserverlibrary.d.ts +++ b/lib/tsserverlibrary.d.ts @@ -2190,6 +2190,7 @@ declare namespace ts { indexType: Type; constraint?: Type; } + type TypeVariable = TypeParameter | IndexedAccessType; interface IndexType extends InstantiableType { type: InstantiableType | UnionOrIntersectionType; } @@ -2214,7 +2215,7 @@ declare namespace ts { resolvedFalseType?: Type; } interface SubstitutionType extends InstantiableType { - typeParameter: TypeParameter; + typeVariable: TypeVariable; substitute: Type; } enum SignatureKind { @@ -2240,9 +2241,10 @@ declare namespace ts { HomomorphicMappedType = 2, MappedTypeConstraint = 4, ReturnType = 8, - NoConstraints = 16, - AlwaysStrict = 32, - PriorityImpliesUnion = 12, + LiteralKeyof = 16, + NoConstraints = 32, + AlwaysStrict = 64, + PriorityImpliesCombination = 28, } interface JsFileExtensionInfo { extension: string; diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js index c791561538c..8e80f66642e 100644 --- a/lib/tsserverlibrary.js +++ b/lib/tsserverlibrary.js @@ -952,9 +952,10 @@ var ts; InferencePriority[InferencePriority["HomomorphicMappedType"] = 2] = "HomomorphicMappedType"; InferencePriority[InferencePriority["MappedTypeConstraint"] = 4] = "MappedTypeConstraint"; InferencePriority[InferencePriority["ReturnType"] = 8] = "ReturnType"; - InferencePriority[InferencePriority["NoConstraints"] = 16] = "NoConstraints"; - InferencePriority[InferencePriority["AlwaysStrict"] = 32] = "AlwaysStrict"; - InferencePriority[InferencePriority["PriorityImpliesUnion"] = 12] = "PriorityImpliesUnion"; + InferencePriority[InferencePriority["LiteralKeyof"] = 16] = "LiteralKeyof"; + InferencePriority[InferencePriority["NoConstraints"] = 32] = "NoConstraints"; + InferencePriority[InferencePriority["AlwaysStrict"] = 64] = "AlwaysStrict"; + InferencePriority[InferencePriority["PriorityImpliesCombination"] = 28] = "PriorityImpliesCombination"; })(InferencePriority = ts.InferencePriority || (ts.InferencePriority = {})); /* @internal */ var InferenceFlags; @@ -1604,7 +1605,7 @@ var ts; // If changing the text in this section, be sure to test `configureNightly` too. ts.versionMajorMinor = "2.8"; /** The version of the TypeScript compiler release */ - ts.version = ts.versionMajorMinor + ".0"; + ts.version = ts.versionMajorMinor + ".1"; })(ts || (ts = {})); (function (ts) { function isExternalModuleNameRelative(moduleName) { @@ -5070,12 +5071,17 @@ var ts; close: function () { return _fs.unwatchFile(fileName, fileChanged); } }; function fileChanged(curr, prev) { + // previous event kind check is to ensure we recongnize the file as previously also missing when it is restored or renamed twice (that is it disappears and reappears) + // In such case, prevTime returned is same as prev time of event when file was deleted as per node documentation + var isPreviouslyDeleted = +prev.mtime === 0 || eventKind === FileWatcherEventKind.Deleted; if (+curr.mtime === 0) { + if (isPreviouslyDeleted) { + // Already deleted file, no need to callback again + return; + } eventKind = FileWatcherEventKind.Deleted; } - // previous event kind check is to ensure we send created event when file is restored or renamed twice (that is it disappears and reappears) - // since in that case the prevTime returned is same as prev time of event when file was deleted as per node documentation - else if (+prev.mtime === 0 || eventKind === FileWatcherEventKind.Deleted) { + else if (isPreviouslyDeleted) { eventKind = FileWatcherEventKind.Created; } // If there is no change in modified time, ignore the event @@ -6344,6 +6350,7 @@ var ts; Expected_0_type_arguments_provide_these_with_an_extends_tag: diag(8026, ts.DiagnosticCategory.Error, "Expected_0_type_arguments_provide_these_with_an_extends_tag_8026", "Expected {0} type arguments; provide these with an '@extends' tag."), Expected_0_1_type_arguments_provide_these_with_an_extends_tag: diag(8027, ts.DiagnosticCategory.Error, "Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027", "Expected {0}-{1} type arguments; provide these with an '@extends' tag."), JSDoc_may_only_appear_in_the_last_parameter_of_a_signature: diag(8028, ts.DiagnosticCategory.Error, "JSDoc_may_only_appear_in_the_last_parameter_of_a_signature_8028", "JSDoc '...' may only appear in the last parameter of a signature."), + JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type: diag(8029, ts.DiagnosticCategory.Error, "JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_h_8029", "JSDoc '@param' tag has name '{0}', but there is no parameter with that name. It would match 'arguments' if it had an array type."), Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clause: diag(9002, ts.DiagnosticCategory.Error, "Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_clas_9002", "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause."), class_expressions_are_not_currently_supported: diag(9003, ts.DiagnosticCategory.Error, "class_expressions_are_not_currently_supported_9003", "'class' expressions are not currently supported."), Language_service_is_disabled: diag(9004, ts.DiagnosticCategory.Error, "Language_service_is_disabled_9004", "Language service is disabled."), @@ -23992,7 +23999,6 @@ var ts; ContainerFlags[ContainerFlags["HasLocals"] = 32] = "HasLocals"; ContainerFlags[ContainerFlags["IsInterface"] = 64] = "IsInterface"; ContainerFlags[ContainerFlags["IsObjectLiteralOrClassExpressionMethod"] = 128] = "IsObjectLiteralOrClassExpressionMethod"; - ContainerFlags[ContainerFlags["IsInferenceContainer"] = 256] = "IsInferenceContainer"; })(ContainerFlags || (ContainerFlags = {})); var binder = createBinder(); function bindSourceFile(file, options) { @@ -24009,7 +24015,6 @@ var ts; var parent; var container; var blockScopeContainer; - var inferenceContainer; var lastContainer; var seenThisKeyword; // state used by control flow analysis @@ -24065,7 +24070,6 @@ var ts; parent = undefined; container = undefined; blockScopeContainer = undefined; - inferenceContainer = undefined; lastContainer = undefined; seenThisKeyword = false; currentFlow = undefined; @@ -24419,13 +24423,6 @@ var ts; bindChildren(node); node.flags = seenThisKeyword ? node.flags | 64 /* ContainsThis */ : node.flags & ~64 /* ContainsThis */; } - else if (containerFlags & 256 /* IsInferenceContainer */) { - var saveInferenceContainer = inferenceContainer; - inferenceContainer = node; - node.locals = undefined; - bindChildren(node); - inferenceContainer = saveInferenceContainer; - } else { bindChildren(node); } @@ -25223,8 +25220,6 @@ var ts; case 235 /* TypeAliasDeclaration */: case 176 /* MappedType */: return 1 /* IsContainer */ | 32 /* HasLocals */; - case 170 /* ConditionalType */: - return 256 /* IsInferenceContainer */; case 272 /* SourceFile */: return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */; case 153 /* MethodDeclaration */: @@ -26292,13 +26287,24 @@ var ts; ? bindAnonymousDeclaration(node, symbolFlags, "__computed" /* Computed */) : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); } + function getInferTypeContainer(node) { + while (node) { + var parent_2 = node.parent; + if (parent_2 && parent_2.kind === 170 /* ConditionalType */ && parent_2.extendsType === node) { + return parent_2; + } + node = parent_2; + } + return undefined; + } function bindTypeParameter(node) { if (node.parent.kind === 171 /* InferType */) { - if (inferenceContainer) { - if (!inferenceContainer.locals) { - inferenceContainer.locals = ts.createSymbolTable(); + var container_1 = getInferTypeContainer(node.parent); + if (container_1) { + if (!container_1.locals) { + container_1.locals = ts.createSymbolTable(); } - declareSymbol(inferenceContainer.locals, /*parent*/ undefined, node, 262144 /* TypeParameter */, 67639784 /* TypeParameterExcludes */); + declareSymbol(container_1.locals, /*parent*/ undefined, node, 262144 /* TypeParameter */, 67639784 /* TypeParameterExcludes */); } else { bindAnonymousDeclaration(node, 262144 /* TypeParameter */, getDeclarationName(node)); @@ -29292,6 +29298,7 @@ var ts; } if (namespace.valueDeclaration && ts.isVariableDeclaration(namespace.valueDeclaration) && + namespace.valueDeclaration.initializer && isCommonJsRequire(namespace.valueDeclaration.initializer)) { var moduleName = namespace.valueDeclaration.initializer.arguments[0]; var moduleSym = resolveExternalModuleName(moduleName, moduleName); @@ -30044,7 +30051,8 @@ var ts; flags: flags, tracker: tracker && tracker.trackSymbol ? tracker : { trackSymbol: ts.noop }, encounteredError: false, - symbolStack: undefined + symbolStack: undefined, + inferTypeParameters: undefined }; } function typeToTypeNodeHelper(type, context) { @@ -30131,6 +30139,9 @@ var ts; return typeReferenceToTypeNode(type); } if (type.flags & 32768 /* TypeParameter */ || objectFlags & 3 /* ClassOrInterface */) { + if (type.flags & 32768 /* TypeParameter */ && ts.contains(context.inferTypeParameters, type)) { + return ts.createInferTypeNode(ts.createTypeParameterDeclaration(getNameOfSymbolAsWritten(type.symbol))); + } var name = type.symbol ? symbolToName(type.symbol, context, 67901928 /* Type */, /*expectsIdentifier*/ false) : ts.createIdentifier("?"); // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. return ts.createTypeReferenceNode(name, /*typeArguments*/ undefined); @@ -30171,13 +30182,16 @@ var ts; } if (type.flags & 2097152 /* Conditional */) { var checkTypeNode = typeToTypeNodeHelper(type.checkType, context); + var saveInferTypeParameters = context.inferTypeParameters; + context.inferTypeParameters = type.root.inferTypeParameters; var extendsTypeNode = typeToTypeNodeHelper(type.extendsType, context); + context.inferTypeParameters = saveInferTypeParameters; var trueTypeNode = typeToTypeNodeHelper(getTrueTypeFromConditionalType(type), context); var falseTypeNode = typeToTypeNodeHelper(getFalseTypeFromConditionalType(type), context); return ts.createConditionalTypeNode(checkTypeNode, extendsTypeNode, trueTypeNode, falseTypeNode); } if (type.flags & 4194304 /* Substitution */) { - return typeToTypeNodeHelper(type.typeParameter, context); + return typeToTypeNodeHelper(type.typeVariable, context); } ts.Debug.fail("Should be unreachable."); function createMappedTypeNodeFromType(type) { @@ -31188,7 +31202,16 @@ var ts; if (ts.isBindingPattern(declaration.parent)) { return getTypeForBindingElement(declaration); } - var isOptional = !ts.isBindingElement(declaration) && !ts.isVariableDeclaration(declaration) && !!declaration.questionToken && includeOptionality; + var isOptional = false; + if (includeOptionality) { + if (ts.isInJavaScriptFile(declaration) && ts.isParameter(declaration)) { + var parameterTags = ts.getJSDocParameterTags(declaration); + isOptional = !!(parameterTags && parameterTags.length > 0 && ts.find(parameterTags, function (tag) { return tag.isBracketed; })); + } + if (!ts.isBindingElement(declaration) && !ts.isVariableDeclaration(declaration) && !!declaration.questionToken) { + isOptional = true; + } + } // Use type from type annotation if one is present var declaredType = tryGetTypeFromEffectiveTypeNode(declaration); if (declaredType) { @@ -33609,18 +33632,21 @@ var ts; } return links.resolvedSignature; } + /** + * A JS function gets a synthetic rest parameter if it references `arguments` AND: + * 1. It has no parameters but at least one `@param` with a type that starts with `...` + * OR + * 2. It has at least one parameter, and the last parameter has a matching `@param` with a type that starts with `...` + */ function maybeAddJsSyntheticRestParameter(declaration, parameters) { - // JS functions get a free rest parameter if: - // a) The last parameter has `...` preceding its type - // b) It references `arguments` somewhere + if (!containsArgumentsReference(declaration)) { + return false; + } var lastParam = ts.lastOrUndefined(declaration.parameters); - var lastParamTags = lastParam && ts.getJSDocParameterTags(lastParam); + var lastParamTags = lastParam ? ts.getJSDocParameterTags(lastParam) : ts.getJSDocTags(declaration).filter(ts.isJSDocParameterTag); var lastParamVariadicType = ts.firstDefined(lastParamTags, function (p) { return p.typeExpression && ts.isJSDocVariadicType(p.typeExpression.type) ? p.typeExpression.type : undefined; }); - if (!lastParamVariadicType && !containsArgumentsReference(declaration)) { - return false; - } var syntheticArgsSymbol = createSymbol(3 /* Variable */, "args"); syntheticArgsSymbol.type = lastParamVariadicType ? createArrayType(getTypeFromTypeNode(lastParamVariadicType.type)) : anyArrayType; syntheticArgsSymbol.isRestParameter = true; @@ -34107,7 +34133,7 @@ var ts; var res = tryGetDeclaredTypeOfSymbol(symbol); if (res) { return checkNoTypeArguments(node, symbol) ? - res.flags & 32768 /* TypeParameter */ ? getConstrainedTypeParameter(res, node) : res : + res.flags & 32768 /* TypeParameter */ ? getConstrainedTypeVariable(res, node) : res : unknownType; } if (!(symbol.flags & 67216319 /* Value */ && isJSDocTypeReference(node))) { @@ -34139,24 +34165,33 @@ var ts; return getInferredClassType(symbol); } } - function getSubstitutionType(typeParameter, substitute) { + function getSubstitutionType(typeVariable, substitute) { var result = createType(4194304 /* Substitution */); - result.typeParameter = typeParameter; + result.typeVariable = typeVariable; result.substitute = substitute; return result; } - function getConstrainedTypeParameter(typeParameter, node) { + function isUnaryTupleTypeNode(node) { + return node.kind === 167 /* TupleType */ && node.elementTypes.length === 1; + } + function getImpliedConstraint(typeVariable, checkNode, extendsNode) { + return isUnaryTupleTypeNode(checkNode) && isUnaryTupleTypeNode(extendsNode) ? getImpliedConstraint(typeVariable, checkNode.elementTypes[0], extendsNode.elementTypes[0]) : + getActualTypeVariable(getTypeFromTypeNode(checkNode)) === typeVariable ? getTypeFromTypeNode(extendsNode) : + undefined; + } + function getConstrainedTypeVariable(typeVariable, node) { var constraints; while (ts.isPartOfTypeNode(node)) { var parent = node.parent; if (parent.kind === 170 /* ConditionalType */ && node === parent.trueType) { - if (getTypeFromTypeNode(parent.checkType) === typeParameter) { - constraints = ts.append(constraints, getTypeFromTypeNode(parent.extendsType)); + var constraint = getImpliedConstraint(typeVariable, parent.checkType, parent.extendsType); + if (constraint) { + constraints = ts.append(constraints, constraint); } } node = parent; } - return constraints ? getSubstitutionType(typeParameter, getIntersectionType(ts.append(constraints, typeParameter))) : typeParameter; + return constraints ? getSubstitutionType(typeVariable, getIntersectionType(ts.append(constraints, typeVariable))) : typeVariable; } function isJSDocTypeReference(node) { return node.flags & 1048576 /* JSDoc */ && node.kind === 161 /* TypeReference */; @@ -34988,7 +35023,13 @@ var ts; function getTypeFromIndexedAccessTypeNode(node) { var links = getNodeLinks(node); if (!links.resolvedType) { - links.resolvedType = getIndexedAccessType(getTypeFromTypeNode(node.objectType), getTypeFromTypeNode(node.indexType), node); + var objectType = getTypeFromTypeNode(node.objectType); + var indexType = getTypeFromTypeNode(node.indexType); + var resolved = getIndexedAccessType(objectType, indexType, node); + links.resolvedType = resolved.flags & 1048576 /* IndexedAccess */ && + resolved.objectType === objectType && + resolved.indexType === indexType ? + getConstrainedTypeVariable(resolved, node) : resolved; } return links.resolvedType; } @@ -35006,8 +35047,8 @@ var ts; } return links.resolvedType; } - function getActualTypeParameter(type) { - return type.flags & 4194304 /* Substitution */ ? type.typeParameter : type; + function getActualTypeVariable(type) { + return type.flags & 4194304 /* Substitution */ ? type.typeVariable : type; } function getConditionalType(root, mapper) { var checkType = instantiateType(root.checkType, mapper); @@ -35025,7 +35066,7 @@ var ts; // We don't want inferences from constraints as they may cause us to eagerly resolve the // conditional type instead of deferring resolution. Also, we always want strict function // types rules (i.e. proper contravariance) for inferences. - inferTypes(context.inferences, checkType, extendsType, 16 /* NoConstraints */ | 32 /* AlwaysStrict */); + inferTypes(context.inferences, checkType, extendsType, 32 /* NoConstraints */ | 64 /* AlwaysStrict */); combinedMapper = combineTypeMappers(mapper, context); } // Return union of trueType and falseType for 'any' since it matches anything @@ -35050,7 +35091,7 @@ var ts; } } // Return a deferred type for a check that is neither definitely true nor definitely false - var erasedCheckType = getActualTypeParameter(checkType); + var erasedCheckType = getActualTypeVariable(checkType); var result = createType(2097152 /* Conditional */); result.root = root; result.checkType = erasedCheckType; @@ -35357,9 +35398,10 @@ var ts; return getTypeFromIntersectionTypeNode(node); case 277 /* JSDocNullableType */: return getTypeFromJSDocNullableTypeNode(node); + case 279 /* JSDocOptionalType */: + return addOptionality(getTypeFromTypeNode(node.type)); case 172 /* ParenthesizedType */: case 278 /* JSDocNonNullableType */: - case 279 /* JSDocOptionalType */: case 274 /* JSDocTypeExpression */: return getTypeFromTypeNode(node.type); case 281 /* JSDocVariadicType */: @@ -35583,8 +35625,8 @@ var ts; // between the node and the type parameter declaration, if the node contains actual references to the // type parameter, or if the node contains type queries, we consider the type parameter possibly referenced. if (tp.symbol && tp.symbol.declarations && tp.symbol.declarations.length === 1) { - var container_1 = tp.symbol.declarations[0].parent; - if (ts.findAncestor(node, function (n) { return n.kind === 211 /* Block */ ? "quit" : n === container_1; })) { + var container_2 = tp.symbol.declarations[0].parent; + if (ts.findAncestor(node, function (n) { return n.kind === 211 /* Block */ ? "quit" : n === container_2; })) { return ts.forEachChild(node, containsReference); } } @@ -35711,7 +35753,7 @@ var ts; return getConditionalTypeInstantiation(type, combineTypeMappers(type.mapper, mapper)); } if (type.flags & 4194304 /* Substitution */) { - return mapper(type.typeParameter); + return instantiateType(type.typeVariable, mapper); } } return type; @@ -36252,10 +36294,10 @@ var ts; target = target.regularType; } if (source.flags & 4194304 /* Substitution */) { - source = relation === definitelyAssignableRelation ? source.typeParameter : source.substitute; + source = relation === definitelyAssignableRelation ? source.typeVariable : source.substitute; } if (target.flags & 4194304 /* Substitution */) { - target = target.typeParameter; + target = target.typeVariable; } // both types are the same - covers 'they are the same primitive type or both are Any' or the same type parameter cases if (source === target) @@ -38102,7 +38144,7 @@ var ts; if (!couldContainTypeVariables(target)) { return; } - if (source.flags & 1 /* Any */) { + if (source === wildcardType) { // We are inferring from an 'any' type. We want to infer this type for every type parameter // referenced in the target type, so we record it as the propagation type and infer from the // target to itself. Then, as we find candidates we substitute the propagation type. @@ -38219,7 +38261,10 @@ var ts; else if ((isLiteralType(source) || source.flags & 2 /* String */) && target.flags & 524288 /* Index */) { var empty = createEmptyObjectTypeFromStringLiteral(source); contravariant = !contravariant; + var savePriority = priority; + priority |= 16 /* LiteralKeyof */; inferFromTypes(empty, target.type); + priority = savePriority; contravariant = !contravariant; } else if (source.flags & 1048576 /* IndexedAccess */ && target.flags & 1048576 /* IndexedAccess */) { @@ -38266,7 +38311,7 @@ var ts; } } else { - if (!(priority & 16 /* NoConstraints */ && source.flags & (262144 /* Intersection */ | 7897088 /* Instantiable */))) { + if (!(priority & 32 /* NoConstraints */ && source.flags & (262144 /* Intersection */ | 7897088 /* Instantiable */))) { source = getApparentType(source); } if (source.flags & (65536 /* Object */ | 262144 /* Intersection */)) { @@ -38297,7 +38342,7 @@ var ts; } } function inferFromContravariantTypes(source, target) { - if (strictFunctionTypes || priority & 32 /* AlwaysStrict */) { + if (strictFunctionTypes || priority & 64 /* AlwaysStrict */) { contravariant = !contravariant; inferFromTypes(source, target); contravariant = !contravariant; @@ -38454,6 +38499,28 @@ var ts; } return candidates; } + function getContravariantInference(inference) { + return inference.priority & 28 /* PriorityImpliesCombination */ ? getIntersectionType(inference.contraCandidates) : getCommonSubtype(inference.contraCandidates); + } + function getCovariantInference(inference, context, signature) { + // Extract all object literal types and replace them with a single widened and normalized type. + var candidates = widenObjectLiteralCandidates(inference.candidates); + // We widen inferred literal types if + // all inferences were made to top-level occurrences of the type parameter, and + // the type parameter has no constraint or its constraint includes no primitive or literal types, and + // the type parameter was fixed during inference or does not occur at top-level in the return type. + var widenLiteralTypes = inference.topLevel && + !hasPrimitiveConstraint(inference.typeParameter) && + (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter)); + var baseCandidates = widenLiteralTypes ? ts.sameMap(candidates, getWidenedLiteralType) : candidates; + // If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if + // union types were requested or if all inferences were made from the return type position, infer a + // union type. Otherwise, infer a common supertype. + var unwidenedType = context.flags & 1 /* InferUnionTypes */ || inference.priority & 28 /* PriorityImpliesCombination */ ? + getUnionType(baseCandidates, 2 /* Subtype */) : + getCommonSupertype(baseCandidates); + return getWidenedType(unwidenedType); + } function getInferredType(context, index) { var inference = context.inferences[index]; var inferredType = inference.inferredType; @@ -38461,32 +38528,16 @@ var ts; var signature = context.signature; if (signature) { if (inference.candidates) { - // Extract all object literal types and replace them with a single widened and normalized type. - var candidates = widenObjectLiteralCandidates(inference.candidates); - // We widen inferred literal types if - // all inferences were made to top-level ocurrences of the type parameter, and - // the type parameter has no constraint or its constraint includes no primitive or literal types, and - // the type parameter was fixed during inference or does not occur at top-level in the return type. - var widenLiteralTypes = inference.topLevel && - !hasPrimitiveConstraint(inference.typeParameter) && - (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter)); - var baseCandidates = widenLiteralTypes ? ts.sameMap(candidates, getWidenedLiteralType) : candidates; - // If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if - // union types were requested or if all inferences were made from the return type position, infer a - // union type. Otherwise, infer a common supertype. - var unwidenedType = context.flags & 1 /* InferUnionTypes */ || inference.priority & 12 /* PriorityImpliesUnion */ ? - getUnionType(baseCandidates, 2 /* Subtype */) : - getCommonSupertype(baseCandidates); - inferredType = getWidenedType(unwidenedType); + inferredType = getCovariantInference(inference, context, signature); // If we have inferred 'never' but have contravariant candidates. To get a more specific type we // infer from the contravariant candidates instead. if (inferredType.flags & 16384 /* Never */ && inference.contraCandidates) { - inferredType = getCommonSubtype(inference.contraCandidates); + inferredType = getContravariantInference(inference); } } else if (inference.contraCandidates) { // We only have contravariant inferences, infer the best common subtype of those - inferredType = getCommonSubtype(inference.contraCandidates); + inferredType = getContravariantInference(inference); } else if (context.flags & 2 /* NoDefault */) { // We use silentNeverType as the wildcard that signals no inferences. @@ -47040,7 +47091,20 @@ var ts; function checkJSDocParameterTag(node) { checkSourceElement(node.typeExpression); if (!ts.getParameterSymbolFromJSDoc(node)) { - error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name, ts.idText(node.name.kind === 145 /* QualifiedName */ ? node.name.right : node.name)); + var decl = ts.getHostSignatureFromJSDoc(node); + // don't issue an error for invalid hosts -- just functions -- + // and give a better error message when the host function mentions `arguments` + // but the tag doesn't have an array type + if (decl) { + if (!containsArgumentsReference(decl)) { + error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name, ts.idText(node.name.kind === 145 /* QualifiedName */ ? node.name.right : node.name)); + } + else if (ts.findLast(ts.getJSDocTags(decl), ts.isJSDocParameterTag) === node && + node.typeExpression && node.typeExpression.type && + !isArrayType(getTypeFromTypeNode(node.typeExpression.type))) { + error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type, ts.idText(node.name.kind === 145 /* QualifiedName */ ? node.name.right : node.name)); + } + } } } function checkJSDocAugmentsTag(node) { @@ -49782,18 +49846,19 @@ var ts; var paramTag = parent.parent; if (ts.isJSDocTypeExpression(parent) && ts.isJSDocParameterTag(paramTag)) { // Else we will add a diagnostic, see `checkJSDocVariadicType`. - var param = ts.getParameterSymbolFromJSDoc(paramTag); - if (param) { - var host_1 = ts.getHostSignatureFromJSDoc(paramTag); + var host_1 = ts.getHostSignatureFromJSDoc(paramTag); + if (host_1) { /* - Only return an array type if the corresponding parameter is marked as a rest parameter. + Only return an array type if the corresponding parameter is marked as a rest parameter, or if there are no parameters. So in the following situation we will not create an array type: /** @param {...number} a * / function f(a) {} Because `a` will just be of type `number | undefined`. A synthetic `...args` will also be added, which *will* get an array type. */ - var lastParamDeclaration = host_1 && ts.last(host_1.parameters); - if (lastParamDeclaration.symbol === param && ts.isRestParameter(lastParamDeclaration)) { + var lastParamDeclaration = ts.lastOrUndefined(host_1.parameters); + var symbol = ts.getParameterSymbolFromJSDoc(paramTag); + if (!lastParamDeclaration || + symbol && lastParamDeclaration.symbol === symbol && ts.isRestParameter(lastParamDeclaration)) { return createArrayType(type); } } @@ -106540,7 +106605,8 @@ var ts; // Some file or directory in the watching directory is created // Return early if it does not have any of the watching extension or not the custom failed lookup path var dirOfFileOrDirectory = ts.getDirectoryPath(fileOrDirectoryPath); - if (isNodeModulesAtTypesDirectory(dirOfFileOrDirectory) || isNodeModulesDirectory(dirOfFileOrDirectory)) { + if (isNodeModulesAtTypesDirectory(fileOrDirectoryPath) || isNodeModulesDirectory(fileOrDirectoryPath) || + isNodeModulesAtTypesDirectory(dirOfFileOrDirectory) || isNodeModulesDirectory(dirOfFileOrDirectory)) { // Invalidate any resolution from this directory isChangedFailedLookupLocation = function (location) { var locationPath = resolutionHost.toPath(location); diff --git a/lib/typescript.d.ts b/lib/typescript.d.ts index 99a9bd99a60..3e6fe31c001 100644 --- a/lib/typescript.d.ts +++ b/lib/typescript.d.ts @@ -2190,6 +2190,7 @@ declare namespace ts { indexType: Type; constraint?: Type; } + type TypeVariable = TypeParameter | IndexedAccessType; interface IndexType extends InstantiableType { type: InstantiableType | UnionOrIntersectionType; } @@ -2214,7 +2215,7 @@ declare namespace ts { resolvedFalseType?: Type; } interface SubstitutionType extends InstantiableType { - typeParameter: TypeParameter; + typeVariable: TypeVariable; substitute: Type; } enum SignatureKind { @@ -2240,9 +2241,10 @@ declare namespace ts { HomomorphicMappedType = 2, MappedTypeConstraint = 4, ReturnType = 8, - NoConstraints = 16, - AlwaysStrict = 32, - PriorityImpliesUnion = 12, + LiteralKeyof = 16, + NoConstraints = 32, + AlwaysStrict = 64, + PriorityImpliesCombination = 28, } interface JsFileExtensionInfo { extension: string; diff --git a/lib/typescript.js b/lib/typescript.js index 7722f68970c..34735735e8c 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -952,9 +952,10 @@ var ts; InferencePriority[InferencePriority["HomomorphicMappedType"] = 2] = "HomomorphicMappedType"; InferencePriority[InferencePriority["MappedTypeConstraint"] = 4] = "MappedTypeConstraint"; InferencePriority[InferencePriority["ReturnType"] = 8] = "ReturnType"; - InferencePriority[InferencePriority["NoConstraints"] = 16] = "NoConstraints"; - InferencePriority[InferencePriority["AlwaysStrict"] = 32] = "AlwaysStrict"; - InferencePriority[InferencePriority["PriorityImpliesUnion"] = 12] = "PriorityImpliesUnion"; + InferencePriority[InferencePriority["LiteralKeyof"] = 16] = "LiteralKeyof"; + InferencePriority[InferencePriority["NoConstraints"] = 32] = "NoConstraints"; + InferencePriority[InferencePriority["AlwaysStrict"] = 64] = "AlwaysStrict"; + InferencePriority[InferencePriority["PriorityImpliesCombination"] = 28] = "PriorityImpliesCombination"; })(InferencePriority = ts.InferencePriority || (ts.InferencePriority = {})); /* @internal */ var InferenceFlags; @@ -1604,7 +1605,7 @@ var ts; // If changing the text in this section, be sure to test `configureNightly` too. ts.versionMajorMinor = "2.8"; /** The version of the TypeScript compiler release */ - ts.version = ts.versionMajorMinor + ".0"; + ts.version = ts.versionMajorMinor + ".1"; })(ts || (ts = {})); (function (ts) { function isExternalModuleNameRelative(moduleName) { @@ -5070,12 +5071,17 @@ var ts; close: function () { return _fs.unwatchFile(fileName, fileChanged); } }; function fileChanged(curr, prev) { + // previous event kind check is to ensure we recongnize the file as previously also missing when it is restored or renamed twice (that is it disappears and reappears) + // In such case, prevTime returned is same as prev time of event when file was deleted as per node documentation + var isPreviouslyDeleted = +prev.mtime === 0 || eventKind === FileWatcherEventKind.Deleted; if (+curr.mtime === 0) { + if (isPreviouslyDeleted) { + // Already deleted file, no need to callback again + return; + } eventKind = FileWatcherEventKind.Deleted; } - // previous event kind check is to ensure we send created event when file is restored or renamed twice (that is it disappears and reappears) - // since in that case the prevTime returned is same as prev time of event when file was deleted as per node documentation - else if (+prev.mtime === 0 || eventKind === FileWatcherEventKind.Deleted) { + else if (isPreviouslyDeleted) { eventKind = FileWatcherEventKind.Created; } // If there is no change in modified time, ignore the event @@ -6344,6 +6350,7 @@ var ts; Expected_0_type_arguments_provide_these_with_an_extends_tag: diag(8026, ts.DiagnosticCategory.Error, "Expected_0_type_arguments_provide_these_with_an_extends_tag_8026", "Expected {0} type arguments; provide these with an '@extends' tag."), Expected_0_1_type_arguments_provide_these_with_an_extends_tag: diag(8027, ts.DiagnosticCategory.Error, "Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027", "Expected {0}-{1} type arguments; provide these with an '@extends' tag."), JSDoc_may_only_appear_in_the_last_parameter_of_a_signature: diag(8028, ts.DiagnosticCategory.Error, "JSDoc_may_only_appear_in_the_last_parameter_of_a_signature_8028", "JSDoc '...' may only appear in the last parameter of a signature."), + JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type: diag(8029, ts.DiagnosticCategory.Error, "JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_h_8029", "JSDoc '@param' tag has name '{0}', but there is no parameter with that name. It would match 'arguments' if it had an array type."), Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clause: diag(9002, ts.DiagnosticCategory.Error, "Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_clas_9002", "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause."), class_expressions_are_not_currently_supported: diag(9003, ts.DiagnosticCategory.Error, "class_expressions_are_not_currently_supported_9003", "'class' expressions are not currently supported."), Language_service_is_disabled: diag(9004, ts.DiagnosticCategory.Error, "Language_service_is_disabled_9004", "Language service is disabled."), @@ -20873,7 +20880,6 @@ var ts; ContainerFlags[ContainerFlags["HasLocals"] = 32] = "HasLocals"; ContainerFlags[ContainerFlags["IsInterface"] = 64] = "IsInterface"; ContainerFlags[ContainerFlags["IsObjectLiteralOrClassExpressionMethod"] = 128] = "IsObjectLiteralOrClassExpressionMethod"; - ContainerFlags[ContainerFlags["IsInferenceContainer"] = 256] = "IsInferenceContainer"; })(ContainerFlags || (ContainerFlags = {})); var binder = createBinder(); function bindSourceFile(file, options) { @@ -20890,7 +20896,6 @@ var ts; var parent; var container; var blockScopeContainer; - var inferenceContainer; var lastContainer; var seenThisKeyword; // state used by control flow analysis @@ -20946,7 +20951,6 @@ var ts; parent = undefined; container = undefined; blockScopeContainer = undefined; - inferenceContainer = undefined; lastContainer = undefined; seenThisKeyword = false; currentFlow = undefined; @@ -21300,13 +21304,6 @@ var ts; bindChildren(node); node.flags = seenThisKeyword ? node.flags | 64 /* ContainsThis */ : node.flags & ~64 /* ContainsThis */; } - else if (containerFlags & 256 /* IsInferenceContainer */) { - var saveInferenceContainer = inferenceContainer; - inferenceContainer = node; - node.locals = undefined; - bindChildren(node); - inferenceContainer = saveInferenceContainer; - } else { bindChildren(node); } @@ -22104,8 +22101,6 @@ var ts; case 235 /* TypeAliasDeclaration */: case 176 /* MappedType */: return 1 /* IsContainer */ | 32 /* HasLocals */; - case 170 /* ConditionalType */: - return 256 /* IsInferenceContainer */; case 272 /* SourceFile */: return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */; case 153 /* MethodDeclaration */: @@ -23173,13 +23168,24 @@ var ts; ? bindAnonymousDeclaration(node, symbolFlags, "__computed" /* Computed */) : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); } + function getInferTypeContainer(node) { + while (node) { + var parent_2 = node.parent; + if (parent_2 && parent_2.kind === 170 /* ConditionalType */ && parent_2.extendsType === node) { + return parent_2; + } + node = parent_2; + } + return undefined; + } function bindTypeParameter(node) { if (node.parent.kind === 171 /* InferType */) { - if (inferenceContainer) { - if (!inferenceContainer.locals) { - inferenceContainer.locals = ts.createSymbolTable(); + var container_1 = getInferTypeContainer(node.parent); + if (container_1) { + if (!container_1.locals) { + container_1.locals = ts.createSymbolTable(); } - declareSymbol(inferenceContainer.locals, /*parent*/ undefined, node, 262144 /* TypeParameter */, 67639784 /* TypeParameterExcludes */); + declareSymbol(container_1.locals, /*parent*/ undefined, node, 262144 /* TypeParameter */, 67639784 /* TypeParameterExcludes */); } else { bindAnonymousDeclaration(node, 262144 /* TypeParameter */, getDeclarationName(node)); @@ -27255,6 +27261,7 @@ var ts; } if (namespace.valueDeclaration && ts.isVariableDeclaration(namespace.valueDeclaration) && + namespace.valueDeclaration.initializer && isCommonJsRequire(namespace.valueDeclaration.initializer)) { var moduleName = namespace.valueDeclaration.initializer.arguments[0]; var moduleSym = resolveExternalModuleName(moduleName, moduleName); @@ -28007,7 +28014,8 @@ var ts; flags: flags, tracker: tracker && tracker.trackSymbol ? tracker : { trackSymbol: ts.noop }, encounteredError: false, - symbolStack: undefined + symbolStack: undefined, + inferTypeParameters: undefined }; } function typeToTypeNodeHelper(type, context) { @@ -28094,6 +28102,9 @@ var ts; return typeReferenceToTypeNode(type); } if (type.flags & 32768 /* TypeParameter */ || objectFlags & 3 /* ClassOrInterface */) { + if (type.flags & 32768 /* TypeParameter */ && ts.contains(context.inferTypeParameters, type)) { + return ts.createInferTypeNode(ts.createTypeParameterDeclaration(getNameOfSymbolAsWritten(type.symbol))); + } var name = type.symbol ? symbolToName(type.symbol, context, 67901928 /* Type */, /*expectsIdentifier*/ false) : ts.createIdentifier("?"); // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. return ts.createTypeReferenceNode(name, /*typeArguments*/ undefined); @@ -28134,13 +28145,16 @@ var ts; } if (type.flags & 2097152 /* Conditional */) { var checkTypeNode = typeToTypeNodeHelper(type.checkType, context); + var saveInferTypeParameters = context.inferTypeParameters; + context.inferTypeParameters = type.root.inferTypeParameters; var extendsTypeNode = typeToTypeNodeHelper(type.extendsType, context); + context.inferTypeParameters = saveInferTypeParameters; var trueTypeNode = typeToTypeNodeHelper(getTrueTypeFromConditionalType(type), context); var falseTypeNode = typeToTypeNodeHelper(getFalseTypeFromConditionalType(type), context); return ts.createConditionalTypeNode(checkTypeNode, extendsTypeNode, trueTypeNode, falseTypeNode); } if (type.flags & 4194304 /* Substitution */) { - return typeToTypeNodeHelper(type.typeParameter, context); + return typeToTypeNodeHelper(type.typeVariable, context); } ts.Debug.fail("Should be unreachable."); function createMappedTypeNodeFromType(type) { @@ -29151,7 +29165,16 @@ var ts; if (ts.isBindingPattern(declaration.parent)) { return getTypeForBindingElement(declaration); } - var isOptional = !ts.isBindingElement(declaration) && !ts.isVariableDeclaration(declaration) && !!declaration.questionToken && includeOptionality; + var isOptional = false; + if (includeOptionality) { + if (ts.isInJavaScriptFile(declaration) && ts.isParameter(declaration)) { + var parameterTags = ts.getJSDocParameterTags(declaration); + isOptional = !!(parameterTags && parameterTags.length > 0 && ts.find(parameterTags, function (tag) { return tag.isBracketed; })); + } + if (!ts.isBindingElement(declaration) && !ts.isVariableDeclaration(declaration) && !!declaration.questionToken) { + isOptional = true; + } + } // Use type from type annotation if one is present var declaredType = tryGetTypeFromEffectiveTypeNode(declaration); if (declaredType) { @@ -31572,18 +31595,21 @@ var ts; } return links.resolvedSignature; } + /** + * A JS function gets a synthetic rest parameter if it references `arguments` AND: + * 1. It has no parameters but at least one `@param` with a type that starts with `...` + * OR + * 2. It has at least one parameter, and the last parameter has a matching `@param` with a type that starts with `...` + */ function maybeAddJsSyntheticRestParameter(declaration, parameters) { - // JS functions get a free rest parameter if: - // a) The last parameter has `...` preceding its type - // b) It references `arguments` somewhere + if (!containsArgumentsReference(declaration)) { + return false; + } var lastParam = ts.lastOrUndefined(declaration.parameters); - var lastParamTags = lastParam && ts.getJSDocParameterTags(lastParam); + var lastParamTags = lastParam ? ts.getJSDocParameterTags(lastParam) : ts.getJSDocTags(declaration).filter(ts.isJSDocParameterTag); var lastParamVariadicType = ts.firstDefined(lastParamTags, function (p) { return p.typeExpression && ts.isJSDocVariadicType(p.typeExpression.type) ? p.typeExpression.type : undefined; }); - if (!lastParamVariadicType && !containsArgumentsReference(declaration)) { - return false; - } var syntheticArgsSymbol = createSymbol(3 /* Variable */, "args"); syntheticArgsSymbol.type = lastParamVariadicType ? createArrayType(getTypeFromTypeNode(lastParamVariadicType.type)) : anyArrayType; syntheticArgsSymbol.isRestParameter = true; @@ -32070,7 +32096,7 @@ var ts; var res = tryGetDeclaredTypeOfSymbol(symbol); if (res) { return checkNoTypeArguments(node, symbol) ? - res.flags & 32768 /* TypeParameter */ ? getConstrainedTypeParameter(res, node) : res : + res.flags & 32768 /* TypeParameter */ ? getConstrainedTypeVariable(res, node) : res : unknownType; } if (!(symbol.flags & 67216319 /* Value */ && isJSDocTypeReference(node))) { @@ -32102,24 +32128,33 @@ var ts; return getInferredClassType(symbol); } } - function getSubstitutionType(typeParameter, substitute) { + function getSubstitutionType(typeVariable, substitute) { var result = createType(4194304 /* Substitution */); - result.typeParameter = typeParameter; + result.typeVariable = typeVariable; result.substitute = substitute; return result; } - function getConstrainedTypeParameter(typeParameter, node) { + function isUnaryTupleTypeNode(node) { + return node.kind === 167 /* TupleType */ && node.elementTypes.length === 1; + } + function getImpliedConstraint(typeVariable, checkNode, extendsNode) { + return isUnaryTupleTypeNode(checkNode) && isUnaryTupleTypeNode(extendsNode) ? getImpliedConstraint(typeVariable, checkNode.elementTypes[0], extendsNode.elementTypes[0]) : + getActualTypeVariable(getTypeFromTypeNode(checkNode)) === typeVariable ? getTypeFromTypeNode(extendsNode) : + undefined; + } + function getConstrainedTypeVariable(typeVariable, node) { var constraints; while (ts.isPartOfTypeNode(node)) { var parent = node.parent; if (parent.kind === 170 /* ConditionalType */ && node === parent.trueType) { - if (getTypeFromTypeNode(parent.checkType) === typeParameter) { - constraints = ts.append(constraints, getTypeFromTypeNode(parent.extendsType)); + var constraint = getImpliedConstraint(typeVariable, parent.checkType, parent.extendsType); + if (constraint) { + constraints = ts.append(constraints, constraint); } } node = parent; } - return constraints ? getSubstitutionType(typeParameter, getIntersectionType(ts.append(constraints, typeParameter))) : typeParameter; + return constraints ? getSubstitutionType(typeVariable, getIntersectionType(ts.append(constraints, typeVariable))) : typeVariable; } function isJSDocTypeReference(node) { return node.flags & 1048576 /* JSDoc */ && node.kind === 161 /* TypeReference */; @@ -32951,7 +32986,13 @@ var ts; function getTypeFromIndexedAccessTypeNode(node) { var links = getNodeLinks(node); if (!links.resolvedType) { - links.resolvedType = getIndexedAccessType(getTypeFromTypeNode(node.objectType), getTypeFromTypeNode(node.indexType), node); + var objectType = getTypeFromTypeNode(node.objectType); + var indexType = getTypeFromTypeNode(node.indexType); + var resolved = getIndexedAccessType(objectType, indexType, node); + links.resolvedType = resolved.flags & 1048576 /* IndexedAccess */ && + resolved.objectType === objectType && + resolved.indexType === indexType ? + getConstrainedTypeVariable(resolved, node) : resolved; } return links.resolvedType; } @@ -32969,8 +33010,8 @@ var ts; } return links.resolvedType; } - function getActualTypeParameter(type) { - return type.flags & 4194304 /* Substitution */ ? type.typeParameter : type; + function getActualTypeVariable(type) { + return type.flags & 4194304 /* Substitution */ ? type.typeVariable : type; } function getConditionalType(root, mapper) { var checkType = instantiateType(root.checkType, mapper); @@ -32988,7 +33029,7 @@ var ts; // We don't want inferences from constraints as they may cause us to eagerly resolve the // conditional type instead of deferring resolution. Also, we always want strict function // types rules (i.e. proper contravariance) for inferences. - inferTypes(context.inferences, checkType, extendsType, 16 /* NoConstraints */ | 32 /* AlwaysStrict */); + inferTypes(context.inferences, checkType, extendsType, 32 /* NoConstraints */ | 64 /* AlwaysStrict */); combinedMapper = combineTypeMappers(mapper, context); } // Return union of trueType and falseType for 'any' since it matches anything @@ -33013,7 +33054,7 @@ var ts; } } // Return a deferred type for a check that is neither definitely true nor definitely false - var erasedCheckType = getActualTypeParameter(checkType); + var erasedCheckType = getActualTypeVariable(checkType); var result = createType(2097152 /* Conditional */); result.root = root; result.checkType = erasedCheckType; @@ -33320,9 +33361,10 @@ var ts; return getTypeFromIntersectionTypeNode(node); case 277 /* JSDocNullableType */: return getTypeFromJSDocNullableTypeNode(node); + case 279 /* JSDocOptionalType */: + return addOptionality(getTypeFromTypeNode(node.type)); case 172 /* ParenthesizedType */: case 278 /* JSDocNonNullableType */: - case 279 /* JSDocOptionalType */: case 274 /* JSDocTypeExpression */: return getTypeFromTypeNode(node.type); case 281 /* JSDocVariadicType */: @@ -33546,8 +33588,8 @@ var ts; // between the node and the type parameter declaration, if the node contains actual references to the // type parameter, or if the node contains type queries, we consider the type parameter possibly referenced. if (tp.symbol && tp.symbol.declarations && tp.symbol.declarations.length === 1) { - var container_1 = tp.symbol.declarations[0].parent; - if (ts.findAncestor(node, function (n) { return n.kind === 211 /* Block */ ? "quit" : n === container_1; })) { + var container_2 = tp.symbol.declarations[0].parent; + if (ts.findAncestor(node, function (n) { return n.kind === 211 /* Block */ ? "quit" : n === container_2; })) { return ts.forEachChild(node, containsReference); } } @@ -33674,7 +33716,7 @@ var ts; return getConditionalTypeInstantiation(type, combineTypeMappers(type.mapper, mapper)); } if (type.flags & 4194304 /* Substitution */) { - return mapper(type.typeParameter); + return instantiateType(type.typeVariable, mapper); } } return type; @@ -34215,10 +34257,10 @@ var ts; target = target.regularType; } if (source.flags & 4194304 /* Substitution */) { - source = relation === definitelyAssignableRelation ? source.typeParameter : source.substitute; + source = relation === definitelyAssignableRelation ? source.typeVariable : source.substitute; } if (target.flags & 4194304 /* Substitution */) { - target = target.typeParameter; + target = target.typeVariable; } // both types are the same - covers 'they are the same primitive type or both are Any' or the same type parameter cases if (source === target) @@ -36065,7 +36107,7 @@ var ts; if (!couldContainTypeVariables(target)) { return; } - if (source.flags & 1 /* Any */) { + if (source === wildcardType) { // We are inferring from an 'any' type. We want to infer this type for every type parameter // referenced in the target type, so we record it as the propagation type and infer from the // target to itself. Then, as we find candidates we substitute the propagation type. @@ -36182,7 +36224,10 @@ var ts; else if ((isLiteralType(source) || source.flags & 2 /* String */) && target.flags & 524288 /* Index */) { var empty = createEmptyObjectTypeFromStringLiteral(source); contravariant = !contravariant; + var savePriority = priority; + priority |= 16 /* LiteralKeyof */; inferFromTypes(empty, target.type); + priority = savePriority; contravariant = !contravariant; } else if (source.flags & 1048576 /* IndexedAccess */ && target.flags & 1048576 /* IndexedAccess */) { @@ -36229,7 +36274,7 @@ var ts; } } else { - if (!(priority & 16 /* NoConstraints */ && source.flags & (262144 /* Intersection */ | 7897088 /* Instantiable */))) { + if (!(priority & 32 /* NoConstraints */ && source.flags & (262144 /* Intersection */ | 7897088 /* Instantiable */))) { source = getApparentType(source); } if (source.flags & (65536 /* Object */ | 262144 /* Intersection */)) { @@ -36260,7 +36305,7 @@ var ts; } } function inferFromContravariantTypes(source, target) { - if (strictFunctionTypes || priority & 32 /* AlwaysStrict */) { + if (strictFunctionTypes || priority & 64 /* AlwaysStrict */) { contravariant = !contravariant; inferFromTypes(source, target); contravariant = !contravariant; @@ -36417,6 +36462,28 @@ var ts; } return candidates; } + function getContravariantInference(inference) { + return inference.priority & 28 /* PriorityImpliesCombination */ ? getIntersectionType(inference.contraCandidates) : getCommonSubtype(inference.contraCandidates); + } + function getCovariantInference(inference, context, signature) { + // Extract all object literal types and replace them with a single widened and normalized type. + var candidates = widenObjectLiteralCandidates(inference.candidates); + // We widen inferred literal types if + // all inferences were made to top-level occurrences of the type parameter, and + // the type parameter has no constraint or its constraint includes no primitive or literal types, and + // the type parameter was fixed during inference or does not occur at top-level in the return type. + var widenLiteralTypes = inference.topLevel && + !hasPrimitiveConstraint(inference.typeParameter) && + (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter)); + var baseCandidates = widenLiteralTypes ? ts.sameMap(candidates, getWidenedLiteralType) : candidates; + // If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if + // union types were requested or if all inferences were made from the return type position, infer a + // union type. Otherwise, infer a common supertype. + var unwidenedType = context.flags & 1 /* InferUnionTypes */ || inference.priority & 28 /* PriorityImpliesCombination */ ? + getUnionType(baseCandidates, 2 /* Subtype */) : + getCommonSupertype(baseCandidates); + return getWidenedType(unwidenedType); + } function getInferredType(context, index) { var inference = context.inferences[index]; var inferredType = inference.inferredType; @@ -36424,32 +36491,16 @@ var ts; var signature = context.signature; if (signature) { if (inference.candidates) { - // Extract all object literal types and replace them with a single widened and normalized type. - var candidates = widenObjectLiteralCandidates(inference.candidates); - // We widen inferred literal types if - // all inferences were made to top-level ocurrences of the type parameter, and - // the type parameter has no constraint or its constraint includes no primitive or literal types, and - // the type parameter was fixed during inference or does not occur at top-level in the return type. - var widenLiteralTypes = inference.topLevel && - !hasPrimitiveConstraint(inference.typeParameter) && - (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter)); - var baseCandidates = widenLiteralTypes ? ts.sameMap(candidates, getWidenedLiteralType) : candidates; - // If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if - // union types were requested or if all inferences were made from the return type position, infer a - // union type. Otherwise, infer a common supertype. - var unwidenedType = context.flags & 1 /* InferUnionTypes */ || inference.priority & 12 /* PriorityImpliesUnion */ ? - getUnionType(baseCandidates, 2 /* Subtype */) : - getCommonSupertype(baseCandidates); - inferredType = getWidenedType(unwidenedType); + inferredType = getCovariantInference(inference, context, signature); // If we have inferred 'never' but have contravariant candidates. To get a more specific type we // infer from the contravariant candidates instead. if (inferredType.flags & 16384 /* Never */ && inference.contraCandidates) { - inferredType = getCommonSubtype(inference.contraCandidates); + inferredType = getContravariantInference(inference); } } else if (inference.contraCandidates) { // We only have contravariant inferences, infer the best common subtype of those - inferredType = getCommonSubtype(inference.contraCandidates); + inferredType = getContravariantInference(inference); } else if (context.flags & 2 /* NoDefault */) { // We use silentNeverType as the wildcard that signals no inferences. @@ -45003,7 +45054,20 @@ var ts; function checkJSDocParameterTag(node) { checkSourceElement(node.typeExpression); if (!ts.getParameterSymbolFromJSDoc(node)) { - error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name, ts.idText(node.name.kind === 145 /* QualifiedName */ ? node.name.right : node.name)); + var decl = ts.getHostSignatureFromJSDoc(node); + // don't issue an error for invalid hosts -- just functions -- + // and give a better error message when the host function mentions `arguments` + // but the tag doesn't have an array type + if (decl) { + if (!containsArgumentsReference(decl)) { + error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name, ts.idText(node.name.kind === 145 /* QualifiedName */ ? node.name.right : node.name)); + } + else if (ts.findLast(ts.getJSDocTags(decl), ts.isJSDocParameterTag) === node && + node.typeExpression && node.typeExpression.type && + !isArrayType(getTypeFromTypeNode(node.typeExpression.type))) { + error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type, ts.idText(node.name.kind === 145 /* QualifiedName */ ? node.name.right : node.name)); + } + } } } function checkJSDocAugmentsTag(node) { @@ -47745,18 +47809,19 @@ var ts; var paramTag = parent.parent; if (ts.isJSDocTypeExpression(parent) && ts.isJSDocParameterTag(paramTag)) { // Else we will add a diagnostic, see `checkJSDocVariadicType`. - var param = ts.getParameterSymbolFromJSDoc(paramTag); - if (param) { - var host_1 = ts.getHostSignatureFromJSDoc(paramTag); + var host_1 = ts.getHostSignatureFromJSDoc(paramTag); + if (host_1) { /* - Only return an array type if the corresponding parameter is marked as a rest parameter. + Only return an array type if the corresponding parameter is marked as a rest parameter, or if there are no parameters. So in the following situation we will not create an array type: /** @param {...number} a * / function f(a) {} Because `a` will just be of type `number | undefined`. A synthetic `...args` will also be added, which *will* get an array type. */ - var lastParamDeclaration = host_1 && ts.last(host_1.parameters); - if (lastParamDeclaration.symbol === param && ts.isRestParameter(lastParamDeclaration)) { + var lastParamDeclaration = ts.lastOrUndefined(host_1.parameters); + var symbol = ts.getParameterSymbolFromJSDoc(paramTag); + if (!lastParamDeclaration || + symbol && lastParamDeclaration.symbol === symbol && ts.isRestParameter(lastParamDeclaration)) { return createArrayType(type); } } @@ -78727,7 +78792,8 @@ var ts; // Some file or directory in the watching directory is created // Return early if it does not have any of the watching extension or not the custom failed lookup path var dirOfFileOrDirectory = ts.getDirectoryPath(fileOrDirectoryPath); - if (isNodeModulesAtTypesDirectory(dirOfFileOrDirectory) || isNodeModulesDirectory(dirOfFileOrDirectory)) { + if (isNodeModulesAtTypesDirectory(fileOrDirectoryPath) || isNodeModulesDirectory(fileOrDirectoryPath) || + isNodeModulesAtTypesDirectory(dirOfFileOrDirectory) || isNodeModulesDirectory(dirOfFileOrDirectory)) { // Invalidate any resolution from this directory isChangedFailedLookupLocation = function (location) { var locationPath = resolutionHost.toPath(location); diff --git a/lib/typescriptServices.d.ts b/lib/typescriptServices.d.ts index f3652da61df..0d140a74f51 100644 --- a/lib/typescriptServices.d.ts +++ b/lib/typescriptServices.d.ts @@ -2190,6 +2190,7 @@ declare namespace ts { indexType: Type; constraint?: Type; } + type TypeVariable = TypeParameter | IndexedAccessType; interface IndexType extends InstantiableType { type: InstantiableType | UnionOrIntersectionType; } @@ -2214,7 +2215,7 @@ declare namespace ts { resolvedFalseType?: Type; } interface SubstitutionType extends InstantiableType { - typeParameter: TypeParameter; + typeVariable: TypeVariable; substitute: Type; } enum SignatureKind { @@ -2240,9 +2241,10 @@ declare namespace ts { HomomorphicMappedType = 2, MappedTypeConstraint = 4, ReturnType = 8, - NoConstraints = 16, - AlwaysStrict = 32, - PriorityImpliesUnion = 12, + LiteralKeyof = 16, + NoConstraints = 32, + AlwaysStrict = 64, + PriorityImpliesCombination = 28, } interface JsFileExtensionInfo { extension: string; diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index 7722f68970c..34735735e8c 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -952,9 +952,10 @@ var ts; InferencePriority[InferencePriority["HomomorphicMappedType"] = 2] = "HomomorphicMappedType"; InferencePriority[InferencePriority["MappedTypeConstraint"] = 4] = "MappedTypeConstraint"; InferencePriority[InferencePriority["ReturnType"] = 8] = "ReturnType"; - InferencePriority[InferencePriority["NoConstraints"] = 16] = "NoConstraints"; - InferencePriority[InferencePriority["AlwaysStrict"] = 32] = "AlwaysStrict"; - InferencePriority[InferencePriority["PriorityImpliesUnion"] = 12] = "PriorityImpliesUnion"; + InferencePriority[InferencePriority["LiteralKeyof"] = 16] = "LiteralKeyof"; + InferencePriority[InferencePriority["NoConstraints"] = 32] = "NoConstraints"; + InferencePriority[InferencePriority["AlwaysStrict"] = 64] = "AlwaysStrict"; + InferencePriority[InferencePriority["PriorityImpliesCombination"] = 28] = "PriorityImpliesCombination"; })(InferencePriority = ts.InferencePriority || (ts.InferencePriority = {})); /* @internal */ var InferenceFlags; @@ -1604,7 +1605,7 @@ var ts; // If changing the text in this section, be sure to test `configureNightly` too. ts.versionMajorMinor = "2.8"; /** The version of the TypeScript compiler release */ - ts.version = ts.versionMajorMinor + ".0"; + ts.version = ts.versionMajorMinor + ".1"; })(ts || (ts = {})); (function (ts) { function isExternalModuleNameRelative(moduleName) { @@ -5070,12 +5071,17 @@ var ts; close: function () { return _fs.unwatchFile(fileName, fileChanged); } }; function fileChanged(curr, prev) { + // previous event kind check is to ensure we recongnize the file as previously also missing when it is restored or renamed twice (that is it disappears and reappears) + // In such case, prevTime returned is same as prev time of event when file was deleted as per node documentation + var isPreviouslyDeleted = +prev.mtime === 0 || eventKind === FileWatcherEventKind.Deleted; if (+curr.mtime === 0) { + if (isPreviouslyDeleted) { + // Already deleted file, no need to callback again + return; + } eventKind = FileWatcherEventKind.Deleted; } - // previous event kind check is to ensure we send created event when file is restored or renamed twice (that is it disappears and reappears) - // since in that case the prevTime returned is same as prev time of event when file was deleted as per node documentation - else if (+prev.mtime === 0 || eventKind === FileWatcherEventKind.Deleted) { + else if (isPreviouslyDeleted) { eventKind = FileWatcherEventKind.Created; } // If there is no change in modified time, ignore the event @@ -6344,6 +6350,7 @@ var ts; Expected_0_type_arguments_provide_these_with_an_extends_tag: diag(8026, ts.DiagnosticCategory.Error, "Expected_0_type_arguments_provide_these_with_an_extends_tag_8026", "Expected {0} type arguments; provide these with an '@extends' tag."), Expected_0_1_type_arguments_provide_these_with_an_extends_tag: diag(8027, ts.DiagnosticCategory.Error, "Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027", "Expected {0}-{1} type arguments; provide these with an '@extends' tag."), JSDoc_may_only_appear_in_the_last_parameter_of_a_signature: diag(8028, ts.DiagnosticCategory.Error, "JSDoc_may_only_appear_in_the_last_parameter_of_a_signature_8028", "JSDoc '...' may only appear in the last parameter of a signature."), + JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type: diag(8029, ts.DiagnosticCategory.Error, "JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_h_8029", "JSDoc '@param' tag has name '{0}', but there is no parameter with that name. It would match 'arguments' if it had an array type."), Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clause: diag(9002, ts.DiagnosticCategory.Error, "Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_clas_9002", "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause."), class_expressions_are_not_currently_supported: diag(9003, ts.DiagnosticCategory.Error, "class_expressions_are_not_currently_supported_9003", "'class' expressions are not currently supported."), Language_service_is_disabled: diag(9004, ts.DiagnosticCategory.Error, "Language_service_is_disabled_9004", "Language service is disabled."), @@ -20873,7 +20880,6 @@ var ts; ContainerFlags[ContainerFlags["HasLocals"] = 32] = "HasLocals"; ContainerFlags[ContainerFlags["IsInterface"] = 64] = "IsInterface"; ContainerFlags[ContainerFlags["IsObjectLiteralOrClassExpressionMethod"] = 128] = "IsObjectLiteralOrClassExpressionMethod"; - ContainerFlags[ContainerFlags["IsInferenceContainer"] = 256] = "IsInferenceContainer"; })(ContainerFlags || (ContainerFlags = {})); var binder = createBinder(); function bindSourceFile(file, options) { @@ -20890,7 +20896,6 @@ var ts; var parent; var container; var blockScopeContainer; - var inferenceContainer; var lastContainer; var seenThisKeyword; // state used by control flow analysis @@ -20946,7 +20951,6 @@ var ts; parent = undefined; container = undefined; blockScopeContainer = undefined; - inferenceContainer = undefined; lastContainer = undefined; seenThisKeyword = false; currentFlow = undefined; @@ -21300,13 +21304,6 @@ var ts; bindChildren(node); node.flags = seenThisKeyword ? node.flags | 64 /* ContainsThis */ : node.flags & ~64 /* ContainsThis */; } - else if (containerFlags & 256 /* IsInferenceContainer */) { - var saveInferenceContainer = inferenceContainer; - inferenceContainer = node; - node.locals = undefined; - bindChildren(node); - inferenceContainer = saveInferenceContainer; - } else { bindChildren(node); } @@ -22104,8 +22101,6 @@ var ts; case 235 /* TypeAliasDeclaration */: case 176 /* MappedType */: return 1 /* IsContainer */ | 32 /* HasLocals */; - case 170 /* ConditionalType */: - return 256 /* IsInferenceContainer */; case 272 /* SourceFile */: return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */; case 153 /* MethodDeclaration */: @@ -23173,13 +23168,24 @@ var ts; ? bindAnonymousDeclaration(node, symbolFlags, "__computed" /* Computed */) : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); } + function getInferTypeContainer(node) { + while (node) { + var parent_2 = node.parent; + if (parent_2 && parent_2.kind === 170 /* ConditionalType */ && parent_2.extendsType === node) { + return parent_2; + } + node = parent_2; + } + return undefined; + } function bindTypeParameter(node) { if (node.parent.kind === 171 /* InferType */) { - if (inferenceContainer) { - if (!inferenceContainer.locals) { - inferenceContainer.locals = ts.createSymbolTable(); + var container_1 = getInferTypeContainer(node.parent); + if (container_1) { + if (!container_1.locals) { + container_1.locals = ts.createSymbolTable(); } - declareSymbol(inferenceContainer.locals, /*parent*/ undefined, node, 262144 /* TypeParameter */, 67639784 /* TypeParameterExcludes */); + declareSymbol(container_1.locals, /*parent*/ undefined, node, 262144 /* TypeParameter */, 67639784 /* TypeParameterExcludes */); } else { bindAnonymousDeclaration(node, 262144 /* TypeParameter */, getDeclarationName(node)); @@ -27255,6 +27261,7 @@ var ts; } if (namespace.valueDeclaration && ts.isVariableDeclaration(namespace.valueDeclaration) && + namespace.valueDeclaration.initializer && isCommonJsRequire(namespace.valueDeclaration.initializer)) { var moduleName = namespace.valueDeclaration.initializer.arguments[0]; var moduleSym = resolveExternalModuleName(moduleName, moduleName); @@ -28007,7 +28014,8 @@ var ts; flags: flags, tracker: tracker && tracker.trackSymbol ? tracker : { trackSymbol: ts.noop }, encounteredError: false, - symbolStack: undefined + symbolStack: undefined, + inferTypeParameters: undefined }; } function typeToTypeNodeHelper(type, context) { @@ -28094,6 +28102,9 @@ var ts; return typeReferenceToTypeNode(type); } if (type.flags & 32768 /* TypeParameter */ || objectFlags & 3 /* ClassOrInterface */) { + if (type.flags & 32768 /* TypeParameter */ && ts.contains(context.inferTypeParameters, type)) { + return ts.createInferTypeNode(ts.createTypeParameterDeclaration(getNameOfSymbolAsWritten(type.symbol))); + } var name = type.symbol ? symbolToName(type.symbol, context, 67901928 /* Type */, /*expectsIdentifier*/ false) : ts.createIdentifier("?"); // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. return ts.createTypeReferenceNode(name, /*typeArguments*/ undefined); @@ -28134,13 +28145,16 @@ var ts; } if (type.flags & 2097152 /* Conditional */) { var checkTypeNode = typeToTypeNodeHelper(type.checkType, context); + var saveInferTypeParameters = context.inferTypeParameters; + context.inferTypeParameters = type.root.inferTypeParameters; var extendsTypeNode = typeToTypeNodeHelper(type.extendsType, context); + context.inferTypeParameters = saveInferTypeParameters; var trueTypeNode = typeToTypeNodeHelper(getTrueTypeFromConditionalType(type), context); var falseTypeNode = typeToTypeNodeHelper(getFalseTypeFromConditionalType(type), context); return ts.createConditionalTypeNode(checkTypeNode, extendsTypeNode, trueTypeNode, falseTypeNode); } if (type.flags & 4194304 /* Substitution */) { - return typeToTypeNodeHelper(type.typeParameter, context); + return typeToTypeNodeHelper(type.typeVariable, context); } ts.Debug.fail("Should be unreachable."); function createMappedTypeNodeFromType(type) { @@ -29151,7 +29165,16 @@ var ts; if (ts.isBindingPattern(declaration.parent)) { return getTypeForBindingElement(declaration); } - var isOptional = !ts.isBindingElement(declaration) && !ts.isVariableDeclaration(declaration) && !!declaration.questionToken && includeOptionality; + var isOptional = false; + if (includeOptionality) { + if (ts.isInJavaScriptFile(declaration) && ts.isParameter(declaration)) { + var parameterTags = ts.getJSDocParameterTags(declaration); + isOptional = !!(parameterTags && parameterTags.length > 0 && ts.find(parameterTags, function (tag) { return tag.isBracketed; })); + } + if (!ts.isBindingElement(declaration) && !ts.isVariableDeclaration(declaration) && !!declaration.questionToken) { + isOptional = true; + } + } // Use type from type annotation if one is present var declaredType = tryGetTypeFromEffectiveTypeNode(declaration); if (declaredType) { @@ -31572,18 +31595,21 @@ var ts; } return links.resolvedSignature; } + /** + * A JS function gets a synthetic rest parameter if it references `arguments` AND: + * 1. It has no parameters but at least one `@param` with a type that starts with `...` + * OR + * 2. It has at least one parameter, and the last parameter has a matching `@param` with a type that starts with `...` + */ function maybeAddJsSyntheticRestParameter(declaration, parameters) { - // JS functions get a free rest parameter if: - // a) The last parameter has `...` preceding its type - // b) It references `arguments` somewhere + if (!containsArgumentsReference(declaration)) { + return false; + } var lastParam = ts.lastOrUndefined(declaration.parameters); - var lastParamTags = lastParam && ts.getJSDocParameterTags(lastParam); + var lastParamTags = lastParam ? ts.getJSDocParameterTags(lastParam) : ts.getJSDocTags(declaration).filter(ts.isJSDocParameterTag); var lastParamVariadicType = ts.firstDefined(lastParamTags, function (p) { return p.typeExpression && ts.isJSDocVariadicType(p.typeExpression.type) ? p.typeExpression.type : undefined; }); - if (!lastParamVariadicType && !containsArgumentsReference(declaration)) { - return false; - } var syntheticArgsSymbol = createSymbol(3 /* Variable */, "args"); syntheticArgsSymbol.type = lastParamVariadicType ? createArrayType(getTypeFromTypeNode(lastParamVariadicType.type)) : anyArrayType; syntheticArgsSymbol.isRestParameter = true; @@ -32070,7 +32096,7 @@ var ts; var res = tryGetDeclaredTypeOfSymbol(symbol); if (res) { return checkNoTypeArguments(node, symbol) ? - res.flags & 32768 /* TypeParameter */ ? getConstrainedTypeParameter(res, node) : res : + res.flags & 32768 /* TypeParameter */ ? getConstrainedTypeVariable(res, node) : res : unknownType; } if (!(symbol.flags & 67216319 /* Value */ && isJSDocTypeReference(node))) { @@ -32102,24 +32128,33 @@ var ts; return getInferredClassType(symbol); } } - function getSubstitutionType(typeParameter, substitute) { + function getSubstitutionType(typeVariable, substitute) { var result = createType(4194304 /* Substitution */); - result.typeParameter = typeParameter; + result.typeVariable = typeVariable; result.substitute = substitute; return result; } - function getConstrainedTypeParameter(typeParameter, node) { + function isUnaryTupleTypeNode(node) { + return node.kind === 167 /* TupleType */ && node.elementTypes.length === 1; + } + function getImpliedConstraint(typeVariable, checkNode, extendsNode) { + return isUnaryTupleTypeNode(checkNode) && isUnaryTupleTypeNode(extendsNode) ? getImpliedConstraint(typeVariable, checkNode.elementTypes[0], extendsNode.elementTypes[0]) : + getActualTypeVariable(getTypeFromTypeNode(checkNode)) === typeVariable ? getTypeFromTypeNode(extendsNode) : + undefined; + } + function getConstrainedTypeVariable(typeVariable, node) { var constraints; while (ts.isPartOfTypeNode(node)) { var parent = node.parent; if (parent.kind === 170 /* ConditionalType */ && node === parent.trueType) { - if (getTypeFromTypeNode(parent.checkType) === typeParameter) { - constraints = ts.append(constraints, getTypeFromTypeNode(parent.extendsType)); + var constraint = getImpliedConstraint(typeVariable, parent.checkType, parent.extendsType); + if (constraint) { + constraints = ts.append(constraints, constraint); } } node = parent; } - return constraints ? getSubstitutionType(typeParameter, getIntersectionType(ts.append(constraints, typeParameter))) : typeParameter; + return constraints ? getSubstitutionType(typeVariable, getIntersectionType(ts.append(constraints, typeVariable))) : typeVariable; } function isJSDocTypeReference(node) { return node.flags & 1048576 /* JSDoc */ && node.kind === 161 /* TypeReference */; @@ -32951,7 +32986,13 @@ var ts; function getTypeFromIndexedAccessTypeNode(node) { var links = getNodeLinks(node); if (!links.resolvedType) { - links.resolvedType = getIndexedAccessType(getTypeFromTypeNode(node.objectType), getTypeFromTypeNode(node.indexType), node); + var objectType = getTypeFromTypeNode(node.objectType); + var indexType = getTypeFromTypeNode(node.indexType); + var resolved = getIndexedAccessType(objectType, indexType, node); + links.resolvedType = resolved.flags & 1048576 /* IndexedAccess */ && + resolved.objectType === objectType && + resolved.indexType === indexType ? + getConstrainedTypeVariable(resolved, node) : resolved; } return links.resolvedType; } @@ -32969,8 +33010,8 @@ var ts; } return links.resolvedType; } - function getActualTypeParameter(type) { - return type.flags & 4194304 /* Substitution */ ? type.typeParameter : type; + function getActualTypeVariable(type) { + return type.flags & 4194304 /* Substitution */ ? type.typeVariable : type; } function getConditionalType(root, mapper) { var checkType = instantiateType(root.checkType, mapper); @@ -32988,7 +33029,7 @@ var ts; // We don't want inferences from constraints as they may cause us to eagerly resolve the // conditional type instead of deferring resolution. Also, we always want strict function // types rules (i.e. proper contravariance) for inferences. - inferTypes(context.inferences, checkType, extendsType, 16 /* NoConstraints */ | 32 /* AlwaysStrict */); + inferTypes(context.inferences, checkType, extendsType, 32 /* NoConstraints */ | 64 /* AlwaysStrict */); combinedMapper = combineTypeMappers(mapper, context); } // Return union of trueType and falseType for 'any' since it matches anything @@ -33013,7 +33054,7 @@ var ts; } } // Return a deferred type for a check that is neither definitely true nor definitely false - var erasedCheckType = getActualTypeParameter(checkType); + var erasedCheckType = getActualTypeVariable(checkType); var result = createType(2097152 /* Conditional */); result.root = root; result.checkType = erasedCheckType; @@ -33320,9 +33361,10 @@ var ts; return getTypeFromIntersectionTypeNode(node); case 277 /* JSDocNullableType */: return getTypeFromJSDocNullableTypeNode(node); + case 279 /* JSDocOptionalType */: + return addOptionality(getTypeFromTypeNode(node.type)); case 172 /* ParenthesizedType */: case 278 /* JSDocNonNullableType */: - case 279 /* JSDocOptionalType */: case 274 /* JSDocTypeExpression */: return getTypeFromTypeNode(node.type); case 281 /* JSDocVariadicType */: @@ -33546,8 +33588,8 @@ var ts; // between the node and the type parameter declaration, if the node contains actual references to the // type parameter, or if the node contains type queries, we consider the type parameter possibly referenced. if (tp.symbol && tp.symbol.declarations && tp.symbol.declarations.length === 1) { - var container_1 = tp.symbol.declarations[0].parent; - if (ts.findAncestor(node, function (n) { return n.kind === 211 /* Block */ ? "quit" : n === container_1; })) { + var container_2 = tp.symbol.declarations[0].parent; + if (ts.findAncestor(node, function (n) { return n.kind === 211 /* Block */ ? "quit" : n === container_2; })) { return ts.forEachChild(node, containsReference); } } @@ -33674,7 +33716,7 @@ var ts; return getConditionalTypeInstantiation(type, combineTypeMappers(type.mapper, mapper)); } if (type.flags & 4194304 /* Substitution */) { - return mapper(type.typeParameter); + return instantiateType(type.typeVariable, mapper); } } return type; @@ -34215,10 +34257,10 @@ var ts; target = target.regularType; } if (source.flags & 4194304 /* Substitution */) { - source = relation === definitelyAssignableRelation ? source.typeParameter : source.substitute; + source = relation === definitelyAssignableRelation ? source.typeVariable : source.substitute; } if (target.flags & 4194304 /* Substitution */) { - target = target.typeParameter; + target = target.typeVariable; } // both types are the same - covers 'they are the same primitive type or both are Any' or the same type parameter cases if (source === target) @@ -36065,7 +36107,7 @@ var ts; if (!couldContainTypeVariables(target)) { return; } - if (source.flags & 1 /* Any */) { + if (source === wildcardType) { // We are inferring from an 'any' type. We want to infer this type for every type parameter // referenced in the target type, so we record it as the propagation type and infer from the // target to itself. Then, as we find candidates we substitute the propagation type. @@ -36182,7 +36224,10 @@ var ts; else if ((isLiteralType(source) || source.flags & 2 /* String */) && target.flags & 524288 /* Index */) { var empty = createEmptyObjectTypeFromStringLiteral(source); contravariant = !contravariant; + var savePriority = priority; + priority |= 16 /* LiteralKeyof */; inferFromTypes(empty, target.type); + priority = savePriority; contravariant = !contravariant; } else if (source.flags & 1048576 /* IndexedAccess */ && target.flags & 1048576 /* IndexedAccess */) { @@ -36229,7 +36274,7 @@ var ts; } } else { - if (!(priority & 16 /* NoConstraints */ && source.flags & (262144 /* Intersection */ | 7897088 /* Instantiable */))) { + if (!(priority & 32 /* NoConstraints */ && source.flags & (262144 /* Intersection */ | 7897088 /* Instantiable */))) { source = getApparentType(source); } if (source.flags & (65536 /* Object */ | 262144 /* Intersection */)) { @@ -36260,7 +36305,7 @@ var ts; } } function inferFromContravariantTypes(source, target) { - if (strictFunctionTypes || priority & 32 /* AlwaysStrict */) { + if (strictFunctionTypes || priority & 64 /* AlwaysStrict */) { contravariant = !contravariant; inferFromTypes(source, target); contravariant = !contravariant; @@ -36417,6 +36462,28 @@ var ts; } return candidates; } + function getContravariantInference(inference) { + return inference.priority & 28 /* PriorityImpliesCombination */ ? getIntersectionType(inference.contraCandidates) : getCommonSubtype(inference.contraCandidates); + } + function getCovariantInference(inference, context, signature) { + // Extract all object literal types and replace them with a single widened and normalized type. + var candidates = widenObjectLiteralCandidates(inference.candidates); + // We widen inferred literal types if + // all inferences were made to top-level occurrences of the type parameter, and + // the type parameter has no constraint or its constraint includes no primitive or literal types, and + // the type parameter was fixed during inference or does not occur at top-level in the return type. + var widenLiteralTypes = inference.topLevel && + !hasPrimitiveConstraint(inference.typeParameter) && + (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter)); + var baseCandidates = widenLiteralTypes ? ts.sameMap(candidates, getWidenedLiteralType) : candidates; + // If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if + // union types were requested or if all inferences were made from the return type position, infer a + // union type. Otherwise, infer a common supertype. + var unwidenedType = context.flags & 1 /* InferUnionTypes */ || inference.priority & 28 /* PriorityImpliesCombination */ ? + getUnionType(baseCandidates, 2 /* Subtype */) : + getCommonSupertype(baseCandidates); + return getWidenedType(unwidenedType); + } function getInferredType(context, index) { var inference = context.inferences[index]; var inferredType = inference.inferredType; @@ -36424,32 +36491,16 @@ var ts; var signature = context.signature; if (signature) { if (inference.candidates) { - // Extract all object literal types and replace them with a single widened and normalized type. - var candidates = widenObjectLiteralCandidates(inference.candidates); - // We widen inferred literal types if - // all inferences were made to top-level ocurrences of the type parameter, and - // the type parameter has no constraint or its constraint includes no primitive or literal types, and - // the type parameter was fixed during inference or does not occur at top-level in the return type. - var widenLiteralTypes = inference.topLevel && - !hasPrimitiveConstraint(inference.typeParameter) && - (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter)); - var baseCandidates = widenLiteralTypes ? ts.sameMap(candidates, getWidenedLiteralType) : candidates; - // If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if - // union types were requested or if all inferences were made from the return type position, infer a - // union type. Otherwise, infer a common supertype. - var unwidenedType = context.flags & 1 /* InferUnionTypes */ || inference.priority & 12 /* PriorityImpliesUnion */ ? - getUnionType(baseCandidates, 2 /* Subtype */) : - getCommonSupertype(baseCandidates); - inferredType = getWidenedType(unwidenedType); + inferredType = getCovariantInference(inference, context, signature); // If we have inferred 'never' but have contravariant candidates. To get a more specific type we // infer from the contravariant candidates instead. if (inferredType.flags & 16384 /* Never */ && inference.contraCandidates) { - inferredType = getCommonSubtype(inference.contraCandidates); + inferredType = getContravariantInference(inference); } } else if (inference.contraCandidates) { // We only have contravariant inferences, infer the best common subtype of those - inferredType = getCommonSubtype(inference.contraCandidates); + inferredType = getContravariantInference(inference); } else if (context.flags & 2 /* NoDefault */) { // We use silentNeverType as the wildcard that signals no inferences. @@ -45003,7 +45054,20 @@ var ts; function checkJSDocParameterTag(node) { checkSourceElement(node.typeExpression); if (!ts.getParameterSymbolFromJSDoc(node)) { - error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name, ts.idText(node.name.kind === 145 /* QualifiedName */ ? node.name.right : node.name)); + var decl = ts.getHostSignatureFromJSDoc(node); + // don't issue an error for invalid hosts -- just functions -- + // and give a better error message when the host function mentions `arguments` + // but the tag doesn't have an array type + if (decl) { + if (!containsArgumentsReference(decl)) { + error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name, ts.idText(node.name.kind === 145 /* QualifiedName */ ? node.name.right : node.name)); + } + else if (ts.findLast(ts.getJSDocTags(decl), ts.isJSDocParameterTag) === node && + node.typeExpression && node.typeExpression.type && + !isArrayType(getTypeFromTypeNode(node.typeExpression.type))) { + error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type, ts.idText(node.name.kind === 145 /* QualifiedName */ ? node.name.right : node.name)); + } + } } } function checkJSDocAugmentsTag(node) { @@ -47745,18 +47809,19 @@ var ts; var paramTag = parent.parent; if (ts.isJSDocTypeExpression(parent) && ts.isJSDocParameterTag(paramTag)) { // Else we will add a diagnostic, see `checkJSDocVariadicType`. - var param = ts.getParameterSymbolFromJSDoc(paramTag); - if (param) { - var host_1 = ts.getHostSignatureFromJSDoc(paramTag); + var host_1 = ts.getHostSignatureFromJSDoc(paramTag); + if (host_1) { /* - Only return an array type if the corresponding parameter is marked as a rest parameter. + Only return an array type if the corresponding parameter is marked as a rest parameter, or if there are no parameters. So in the following situation we will not create an array type: /** @param {...number} a * / function f(a) {} Because `a` will just be of type `number | undefined`. A synthetic `...args` will also be added, which *will* get an array type. */ - var lastParamDeclaration = host_1 && ts.last(host_1.parameters); - if (lastParamDeclaration.symbol === param && ts.isRestParameter(lastParamDeclaration)) { + var lastParamDeclaration = ts.lastOrUndefined(host_1.parameters); + var symbol = ts.getParameterSymbolFromJSDoc(paramTag); + if (!lastParamDeclaration || + symbol && lastParamDeclaration.symbol === symbol && ts.isRestParameter(lastParamDeclaration)) { return createArrayType(type); } } @@ -78727,7 +78792,8 @@ var ts; // Some file or directory in the watching directory is created // Return early if it does not have any of the watching extension or not the custom failed lookup path var dirOfFileOrDirectory = ts.getDirectoryPath(fileOrDirectoryPath); - if (isNodeModulesAtTypesDirectory(dirOfFileOrDirectory) || isNodeModulesDirectory(dirOfFileOrDirectory)) { + if (isNodeModulesAtTypesDirectory(fileOrDirectoryPath) || isNodeModulesDirectory(fileOrDirectoryPath) || + isNodeModulesAtTypesDirectory(dirOfFileOrDirectory) || isNodeModulesDirectory(dirOfFileOrDirectory)) { // Invalidate any resolution from this directory isChangedFailedLookupLocation = function (location) { var locationPath = resolutionHost.toPath(location); diff --git a/lib/typingsInstaller.js b/lib/typingsInstaller.js index de3022bbce8..ea853571dd4 100644 --- a/lib/typingsInstaller.js +++ b/lib/typingsInstaller.js @@ -180,7 +180,7 @@ var ts; var ts; (function (ts) { ts.versionMajorMinor = "2.8"; - ts.version = ts.versionMajorMinor + ".0"; + ts.version = ts.versionMajorMinor + ".1"; })(ts || (ts = {})); (function (ts) { function isExternalModuleNameRelative(moduleName) { @@ -3159,10 +3159,14 @@ var ts; close: function () { return _fs.unwatchFile(fileName, fileChanged); } }; function fileChanged(curr, prev) { + var isPreviouslyDeleted = +prev.mtime === 0 || eventKind === FileWatcherEventKind.Deleted; if (+curr.mtime === 0) { + if (isPreviouslyDeleted) { + return; + } eventKind = FileWatcherEventKind.Deleted; } - else if (+prev.mtime === 0 || eventKind === FileWatcherEventKind.Deleted) { + else if (isPreviouslyDeleted) { eventKind = FileWatcherEventKind.Created; } else if (+curr.mtime === +prev.mtime) { @@ -4373,6 +4377,7 @@ var ts; Expected_0_type_arguments_provide_these_with_an_extends_tag: diag(8026, ts.DiagnosticCategory.Error, "Expected_0_type_arguments_provide_these_with_an_extends_tag_8026", "Expected {0} type arguments; provide these with an '@extends' tag."), Expected_0_1_type_arguments_provide_these_with_an_extends_tag: diag(8027, ts.DiagnosticCategory.Error, "Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027", "Expected {0}-{1} type arguments; provide these with an '@extends' tag."), JSDoc_may_only_appear_in_the_last_parameter_of_a_signature: diag(8028, ts.DiagnosticCategory.Error, "JSDoc_may_only_appear_in_the_last_parameter_of_a_signature_8028", "JSDoc '...' may only appear in the last parameter of a signature."), + JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type: diag(8029, ts.DiagnosticCategory.Error, "JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_h_8029", "JSDoc '@param' tag has name '{0}', but there is no parameter with that name. It would match 'arguments' if it had an array type."), Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clause: diag(9002, ts.DiagnosticCategory.Error, "Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_clas_9002", "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause."), class_expressions_are_not_currently_supported: diag(9003, ts.DiagnosticCategory.Error, "class_expressions_are_not_currently_supported_9003", "'class' expressions are not currently supported."), Language_service_is_disabled: diag(9004, ts.DiagnosticCategory.Error, "Language_service_is_disabled_9004", "Language service is disabled."), @@ -19570,10 +19575,7 @@ var ts; } return; } - for (var _i = 0, watchers_1 = watchers; _i < watchers_1.length; _i++) { - var w = watchers_1[_i]; - w.close(); - } + ts.clearMap(watchers, ts.closeFileWatcher); this.projectWatchers.delete(projectName); if (this.log.isEnabled()) { this.log.writeLine("Closing file watchers for project '" + projectName + "' - done."); @@ -19804,25 +19806,38 @@ var ts; TypingsInstaller.prototype.watchFiles = function (projectName, files) { var _this = this; if (!files.length) { + this.closeWatchers(projectName); return; } - this.closeWatchers(projectName); - var isInvoked = false; - var watchers = []; - for (var _i = 0, files_1 = files; _i < files_1.length; _i++) { - var file = files_1[_i]; - var w = this.installTypingHost.watchFile(file, function (f) { - if (_this.log.isEnabled()) { - _this.log.writeLine("Got FS notification for " + f + ", handler is already invoked '" + isInvoked + "'"); - } - if (!isInvoked) { - _this.sendResponse({ projectName: projectName, kind: server.ActionInvalidate }); - isInvoked = true; - } - }, 2000); - watchers.push(w); + var watchers = this.projectWatchers.get(projectName); + if (!watchers) { + watchers = ts.createMap(); + this.projectWatchers.set(projectName, watchers); } - this.projectWatchers.set(projectName, watchers); + var isInvoked = false; + var isLoggingEnabled = this.log.isEnabled(); + ts.mutateMap(watchers, ts.arrayToSet(files), { + createNewValue: function (file) { + if (isLoggingEnabled) { + _this.log.writeLine("FileWatcher:: Added:: WatchInfo: " + file); + } + var watcher = _this.installTypingHost.watchFile(file, function (f, eventKind) { + if (isLoggingEnabled) { + _this.log.writeLine("FileWatcher:: Triggered with " + f + " eventKind: " + ts.FileWatcherEventKind[eventKind] + ":: WatchInfo: " + file + ":: handler is already invoked '" + isInvoked + "'"); + } + if (!isInvoked) { + _this.sendResponse({ projectName: projectName, kind: server.ActionInvalidate }); + isInvoked = true; + } + }, 2000); + return isLoggingEnabled ? { + close: function () { + _this.log.writeLine("FileWatcher:: Closed:: WatchInfo: " + file); + } + } : watcher; + }, + onDeleteValue: ts.closeFileWatcher + }); }; TypingsInstaller.prototype.createSetTypings = function (request, typings) { return {