diff --git a/lib/tsc.js b/lib/tsc.js index d0fb24e1321..2c30bda7bff 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -9917,9 +9917,11 @@ var ts; visitNode(cbNode, node.typeExpression); } case 285: - for (var _i = 0, _a = node.jsDocPropertyTags; _i < _a.length; _i++) { - var tag = _a[_i]; - visitNode(cbNode, tag); + if (node.jsDocPropertyTags) { + for (var _i = 0, _a = node.jsDocPropertyTags; _i < _a.length; _i++) { + var tag = _a[_i]; + visitNode(cbNode, tag); + } } return; case 288: @@ -14290,19 +14292,18 @@ var ts; if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) { var child = void 0; var jsdocTypeLiteral = void 0; - var alreadyHasTypeTag = false; + var childTypeTag = void 0; var start_3 = scanner.getStartPos(); while (child = tryParse(function () { return parseChildParameterOrPropertyTag(0); })) { if (!jsdocTypeLiteral) { jsdocTypeLiteral = createNode(285, start_3); } if (child.kind === 281) { - if (alreadyHasTypeTag) { + if (childTypeTag) { break; } else { - jsdocTypeLiteral.jsDocTypeTag = child; - alreadyHasTypeTag = true; + childTypeTag = child; } } else { @@ -14316,7 +14317,9 @@ var ts; if (typeExpression && typeExpression.type.kind === 164) { jsdocTypeLiteral.isArrayType = true; } - typedefTag.typeExpression = finishNode(jsdocTypeLiteral); + typedefTag.typeExpression = childTypeTag && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ? + childTypeTag.typeExpression : + finishNode(jsdocTypeLiteral); } } return finishNode(typedefTag); @@ -21956,25 +21959,44 @@ var ts; } return typeParameters; } - function appendOuterTypeParameters(typeParameters, node) { + function getOuterTypeParameters(node, includeThisTypes) { while (true) { node = node.parent; if (!node) { - return typeParameters; + return undefined; } - if (node.kind === 229 || node.kind === 199 || - node.kind === 228 || node.kind === 186 || - node.kind === 151 || node.kind === 187) { - var declarations = node.typeParameters; - if (declarations) { - return appendTypeParameters(appendOuterTypeParameters(typeParameters, node), declarations); - } + switch (node.kind) { + case 229: + case 199: + case 230: + case 155: + case 156: + case 150: + case 160: + case 161: + case 273: + case 228: + case 151: + case 186: + case 187: + case 231: + case 282: + case 172: + var outerTypeParameters = getOuterTypeParameters(node, includeThisTypes); + if (node.kind === 172) { + return ts.append(outerTypeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter))); + } + var outerAndOwnTypeParameters = appendTypeParameters(outerTypeParameters, ts.getEffectiveTypeParameterDeclarations(node) || ts.emptyArray); + var thisType = includeThisTypes && + (node.kind === 229 || node.kind === 199 || node.kind === 230) && + getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node)).thisType; + return thisType ? ts.append(outerAndOwnTypeParameters, thisType) : outerAndOwnTypeParameters; } } } function getOuterTypeParametersOfClassOrInterface(symbol) { var declaration = symbol.flags & 32 ? symbol.valueDeclaration : ts.getDeclarationOfKind(symbol, 230); - return appendOuterTypeParameters(undefined, declaration); + return getOuterTypeParameters(declaration); } function getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol) { var result; @@ -23498,12 +23520,20 @@ var ts; return instantiateSignature(signature, createTypeMapper(signature.typeParameters, typeArguments), true); } function getErasedSignature(signature) { - if (!signature.typeParameters) - return signature; - if (!signature.erasedSignatureCache) { - signature.erasedSignatureCache = instantiateSignature(signature, createTypeEraser(signature.typeParameters), true); - } - return signature.erasedSignatureCache; + return signature.typeParameters ? + signature.erasedSignatureCache || (signature.erasedSignatureCache = createErasedSignature(signature)) : + signature; + } + function createErasedSignature(signature) { + return instantiateSignature(signature, createTypeEraser(signature.typeParameters), true); + } + function getCanonicalSignature(signature) { + return signature.typeParameters ? + signature.canonicalSignatureCache || (signature.canonicalSignatureCache = createCanonicalSignature(signature)) : + signature; + } + function createCanonicalSignature(signature) { + return getSignatureInstantiation(signature, ts.map(signature.typeParameters, function (tp) { return tp.target && !getConstraintOfTypeParameter(tp.target) ? tp.target : tp; })); } function getOrCreateTypeFromSignature(signature) { if (!signature.isolatedSignatureType) { @@ -23650,7 +23680,7 @@ var ts; var id = getTypeListId(typeArguments); var instantiation = links.instantiations.get(id); if (!instantiation) { - links.instantiations.set(id, instantiation = instantiateTypeNoAlias(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters))))); + links.instantiations.set(id, instantiation = instantiateType(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters))))); } return instantiation; } @@ -24678,10 +24708,6 @@ var ts; function instantiateSignatures(signatures, mapper) { return instantiateList(signatures, mapper, instantiateSignature); } - function instantiateCached(type, mapper, instantiator) { - var instantiations = mapper.instantiations || (mapper.instantiations = []); - return instantiations[type.id] || (instantiations[type.id] = instantiator(type, mapper)); - } function makeUnaryTypeMapper(source, target) { return function (t) { return t === source ? target : t; }; } @@ -24700,19 +24726,15 @@ var ts; } function createTypeMapper(sources, targets) { ts.Debug.assert(targets === undefined || sources.length === targets.length); - var mapper = sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) : + return sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) : sources.length === 2 ? makeBinaryTypeMapper(sources[0], targets ? targets[0] : anyType, sources[1], targets ? targets[1] : anyType) : makeArrayTypeMapper(sources, targets); - mapper.mappedTypes = sources; - return mapper; } function createTypeEraser(sources) { return createTypeMapper(sources, undefined); } function createBackreferenceMapper(typeParameters, index) { - var mapper = function (t) { return ts.indexOf(typeParameters, t) >= index ? emptyObjectType : t; }; - mapper.mappedTypes = typeParameters; - return mapper; + return function (t) { return ts.indexOf(typeParameters, t) >= index ? emptyObjectType : t; }; } function isInferenceContext(mapper) { return !!mapper.signature; @@ -24726,14 +24748,10 @@ var ts; return type; } function combineTypeMappers(mapper1, mapper2) { - var mapper = function (t) { return instantiateType(mapper1(t), mapper2); }; - mapper.mappedTypes = ts.concatenate(mapper1.mappedTypes, mapper2.mappedTypes); - return mapper; + return function (t) { return instantiateType(mapper1(t), mapper2); }; } function createReplacementMapper(source, target, baseMapper) { - var mapper = function (t) { return t === source ? target : baseMapper(t); }; - mapper.mappedTypes = baseMapper.mappedTypes; - return mapper; + return function (t) { return t === source ? target : baseMapper(t); }; } function cloneTypeParameter(typeParameter) { var result = createType(16384); @@ -24793,13 +24811,45 @@ var ts; } return result; } - function instantiateAnonymousType(type, mapper) { - var result = createObjectType(16 | 64, type.symbol); - result.target = type.objectFlags & 64 ? type.target : type; - result.mapper = type.objectFlags & 64 ? combineTypeMappers(type.mapper, mapper) : mapper; - result.aliasSymbol = type.aliasSymbol; - result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper); - return result; + function getAnonymousTypeInstantiation(type, mapper) { + var target = type.objectFlags & 64 ? type.target : type; + var symbol = target.symbol; + var links = getSymbolLinks(symbol); + var typeParameters = links.typeParameters; + if (!typeParameters) { + var declaration_1 = symbol.declarations[0]; + var outerTypeParameters = getOuterTypeParameters(declaration_1, true) || ts.emptyArray; + typeParameters = symbol.flags & 2048 && !target.aliasTypeArguments ? + ts.filter(outerTypeParameters, function (tp) { return isTypeParameterReferencedWithin(tp, declaration_1); }) : + outerTypeParameters; + links.typeParameters = typeParameters; + if (typeParameters.length) { + links.instantiations = ts.createMap(); + links.instantiations.set(getTypeListId(typeParameters), target); + } + } + if (typeParameters.length) { + var combinedMapper = type.objectFlags & 64 ? combineTypeMappers(type.mapper, mapper) : mapper; + var typeArguments = ts.map(typeParameters, combinedMapper); + var id = getTypeListId(typeArguments); + var result = links.instantiations.get(id); + if (!result) { + var newMapper = createTypeMapper(typeParameters, typeArguments); + result = target.objectFlags & 32 ? instantiateMappedType(target, newMapper) : instantiateAnonymousType(target, newMapper); + links.instantiations.set(id, result); + } + return result; + } + return type; + } + function isTypeParameterReferencedWithin(tp, node) { + return tp.isThisType ? ts.forEachChild(node, checkThis) : ts.forEachChild(node, checkIdentifier); + function checkThis(node) { + return node.kind === 169 || ts.forEachChild(node, checkThis); + } + function checkIdentifier(node) { + return node.kind === 71 && ts.isPartOfTypeNode(node) && getTypeFromTypeNode(node) === tp || ts.forEachChild(node, checkIdentifier); + } } function instantiateMappedType(type, mapper) { var constraintType = getConstraintTypeFromMappedType(type); @@ -24810,134 +24860,58 @@ var ts; if (typeVariable_1 !== mappedTypeVariable) { return mapType(mappedTypeVariable, function (t) { if (isMappableType(t)) { - return instantiateMappedObjectType(type, createReplacementMapper(typeVariable_1, t, mapper)); + return instantiateAnonymousType(type, createReplacementMapper(typeVariable_1, t, mapper)); } return t; }); } } } - return instantiateMappedObjectType(type, mapper); + return instantiateAnonymousType(type, mapper); } function isMappableType(type) { return type.flags & (16384 | 32768 | 131072 | 524288); } - function instantiateMappedObjectType(type, mapper) { - var result = createObjectType(32 | 64, type.symbol); - result.declaration = type.declaration; - result.mapper = type.mapper ? combineTypeMappers(type.mapper, mapper) : mapper; + function instantiateAnonymousType(type, mapper) { + var result = createObjectType(type.objectFlags | 64, type.symbol); + if (type.objectFlags & 32) { + result.declaration = type.declaration; + } + result.target = type; + result.mapper = mapper; result.aliasSymbol = type.aliasSymbol; result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper); return result; } - function isSymbolInScopeOfMappedTypeParameter(symbol, mapper) { - if (!(symbol.declarations && symbol.declarations.length)) { - return false; - } - var mappedTypes = mapper.mappedTypes; - return !!ts.findAncestor(symbol.declarations[0], function (node) { - if (node.kind === 233 || node.kind === 265) { - return "quit"; - } - switch (node.kind) { - case 160: - case 161: - case 228: - case 151: - case 150: - case 152: - case 155: - case 156: - case 157: - case 153: - case 154: - case 186: - case 187: - case 229: - case 199: - case 230: - case 231: - var typeParameters = ts.getEffectiveTypeParameterDeclarations(node); - if (typeParameters) { - for (var _i = 0, typeParameters_1 = typeParameters; _i < typeParameters_1.length; _i++) { - var d = typeParameters_1[_i]; - if (ts.contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode(d)))) { - return true; - } - } - } - if (ts.isClassLike(node) || node.kind === 230) { - var thisType = getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node)).thisType; - if (thisType && ts.contains(mappedTypes, thisType)) { - return true; - } - } - break; - case 172: - if (ts.contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter)))) { - return true; - } - break; - case 273: - var func = node; - for (var _a = 0, _b = func.parameters; _a < _b.length; _a++) { - var p = _b[_a]; - if (ts.contains(mappedTypes, getTypeOfNode(p))) { - return true; - } - } - break; - } - }); - } - function isTopLevelTypeAlias(symbol) { - if (symbol.declarations && symbol.declarations.length) { - var parentKind = symbol.declarations[0].parent.kind; - return parentKind === 265 || parentKind === 234; - } - return false; - } function instantiateType(type, mapper) { if (type && mapper !== identityMapper) { - if (type.aliasSymbol && isTopLevelTypeAlias(type.aliasSymbol)) { - if (type.aliasTypeArguments) { - return getTypeAliasInstantiation(type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); + if (type.flags & 16384) { + return mapper(type); + } + if (type.flags & 32768) { + if (type.objectFlags & 16) { + return type.symbol && type.symbol.flags & (16 | 8192 | 32 | 2048 | 4096) && type.symbol.declarations ? + getAnonymousTypeInstantiation(type, mapper) : type; + } + if (type.objectFlags & 32) { + return getAnonymousTypeInstantiation(type, mapper); + } + if (type.objectFlags & 4) { + return createTypeReference(type.target, instantiateTypes(type.typeArguments, mapper)); } - return type; } - return instantiateTypeNoAlias(type, mapper); - } - return type; - } - function instantiateTypeNoAlias(type, mapper) { - if (type.flags & 16384) { - return mapper(type); - } - if (type.flags & 32768) { - if (type.objectFlags & 16) { - return type.symbol && - type.symbol.flags & (16 | 8192 | 32 | 2048 | 4096) && - (type.objectFlags & 64 || isSymbolInScopeOfMappedTypeParameter(type.symbol, mapper)) ? - instantiateCached(type, mapper, instantiateAnonymousType) : type; + if (type.flags & 65536 && !(type.flags & 8190)) { + return getUnionType(instantiateTypes(type.types, mapper), false, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); } - if (type.objectFlags & 32) { - return instantiateCached(type, mapper, instantiateMappedType); + if (type.flags & 131072) { + return getIntersectionType(instantiateTypes(type.types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); } - if (type.objectFlags & 4) { - return createTypeReference(type.target, instantiateTypes(type.typeArguments, mapper)); + if (type.flags & 262144) { + return getIndexType(instantiateType(type.type, mapper)); + } + if (type.flags & 524288) { + return getIndexedAccessType(instantiateType(type.objectType, mapper), instantiateType(type.indexType, mapper)); } - } - if (type.flags & 65536 && !(type.flags & 8190)) { - return getUnionType(instantiateTypes(type.types, mapper), false, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); - } - if (type.flags & 131072) { - return getIntersectionType(instantiateTypes(type.types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); - } - if (type.flags & 262144) { - return getIndexType(instantiateType(type.type, mapper)); - } - if (type.flags & 524288) { - return getIndexedAccessType(instantiateType(type.objectType, mapper), instantiateType(type.indexType, mapper)); } return type; } @@ -25051,7 +25025,8 @@ var ts; if (!target.hasRestParameter && source.minArgumentCount > target.parameters.length) { return 0; } - if (source.typeParameters) { + if (source.typeParameters && source.typeParameters !== target.typeParameters) { + target = getCanonicalSignature(target); source = instantiateSignatureInContextOf(source, target, undefined, compareTypes); } var result = -1; @@ -26539,7 +26514,6 @@ var ts; function createInferenceContext(signature, flags, compareTypes, baseInferences) { var inferences = baseInferences ? ts.map(baseInferences, cloneInferenceInfo) : ts.map(signature.typeParameters, createInferenceInfo); var context = mapper; - context.mappedTypes = signature.typeParameters; context.signature = signature; context.inferences = inferences; context.flags = flags; diff --git a/lib/tsserver.js b/lib/tsserver.js index c1075eb4971..15bfce1b4d5 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -11787,9 +11787,11 @@ var ts; visitNode(cbNode, node.typeExpression); } case 285: - for (var _i = 0, _a = node.jsDocPropertyTags; _i < _a.length; _i++) { - var tag = _a[_i]; - visitNode(cbNode, tag); + if (node.jsDocPropertyTags) { + for (var _i = 0, _a = node.jsDocPropertyTags; _i < _a.length; _i++) { + var tag = _a[_i]; + visitNode(cbNode, tag); + } } return; case 288: @@ -16204,19 +16206,18 @@ var ts; if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) { var child = void 0; var jsdocTypeLiteral = void 0; - var alreadyHasTypeTag = false; + var childTypeTag = void 0; var start_3 = scanner.getStartPos(); while (child = tryParse(function () { return parseChildParameterOrPropertyTag(0); })) { if (!jsdocTypeLiteral) { jsdocTypeLiteral = createNode(285, start_3); } if (child.kind === 281) { - if (alreadyHasTypeTag) { + if (childTypeTag) { break; } else { - jsdocTypeLiteral.jsDocTypeTag = child; - alreadyHasTypeTag = true; + childTypeTag = child; } } else { @@ -16230,7 +16231,9 @@ var ts; if (typeExpression && typeExpression.type.kind === 164) { jsdocTypeLiteral.isArrayType = true; } - typedefTag.typeExpression = finishNode(jsdocTypeLiteral); + typedefTag.typeExpression = childTypeTag && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ? + childTypeTag.typeExpression : + finishNode(jsdocTypeLiteral); } } return finishNode(typedefTag); @@ -23167,25 +23170,44 @@ var ts; } return typeParameters; } - function appendOuterTypeParameters(typeParameters, node) { + function getOuterTypeParameters(node, includeThisTypes) { while (true) { node = node.parent; if (!node) { - return typeParameters; + return undefined; } - if (node.kind === 229 || node.kind === 199 || - node.kind === 228 || node.kind === 186 || - node.kind === 151 || node.kind === 187) { - var declarations = node.typeParameters; - if (declarations) { - return appendTypeParameters(appendOuterTypeParameters(typeParameters, node), declarations); - } + switch (node.kind) { + case 229: + case 199: + case 230: + case 155: + case 156: + case 150: + case 160: + case 161: + case 273: + case 228: + case 151: + case 186: + case 187: + case 231: + case 282: + case 172: + var outerTypeParameters = getOuterTypeParameters(node, includeThisTypes); + if (node.kind === 172) { + return ts.append(outerTypeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter))); + } + var outerAndOwnTypeParameters = appendTypeParameters(outerTypeParameters, ts.getEffectiveTypeParameterDeclarations(node) || ts.emptyArray); + var thisType = includeThisTypes && + (node.kind === 229 || node.kind === 199 || node.kind === 230) && + getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node)).thisType; + return thisType ? ts.append(outerAndOwnTypeParameters, thisType) : outerAndOwnTypeParameters; } } } function getOuterTypeParametersOfClassOrInterface(symbol) { var declaration = symbol.flags & 32 ? symbol.valueDeclaration : ts.getDeclarationOfKind(symbol, 230); - return appendOuterTypeParameters(undefined, declaration); + return getOuterTypeParameters(declaration); } function getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol) { var result; @@ -24709,12 +24731,20 @@ var ts; return instantiateSignature(signature, createTypeMapper(signature.typeParameters, typeArguments), true); } function getErasedSignature(signature) { - if (!signature.typeParameters) - return signature; - if (!signature.erasedSignatureCache) { - signature.erasedSignatureCache = instantiateSignature(signature, createTypeEraser(signature.typeParameters), true); - } - return signature.erasedSignatureCache; + return signature.typeParameters ? + signature.erasedSignatureCache || (signature.erasedSignatureCache = createErasedSignature(signature)) : + signature; + } + function createErasedSignature(signature) { + return instantiateSignature(signature, createTypeEraser(signature.typeParameters), true); + } + function getCanonicalSignature(signature) { + return signature.typeParameters ? + signature.canonicalSignatureCache || (signature.canonicalSignatureCache = createCanonicalSignature(signature)) : + signature; + } + function createCanonicalSignature(signature) { + return getSignatureInstantiation(signature, ts.map(signature.typeParameters, function (tp) { return tp.target && !getConstraintOfTypeParameter(tp.target) ? tp.target : tp; })); } function getOrCreateTypeFromSignature(signature) { if (!signature.isolatedSignatureType) { @@ -24861,7 +24891,7 @@ var ts; var id = getTypeListId(typeArguments); var instantiation = links.instantiations.get(id); if (!instantiation) { - links.instantiations.set(id, instantiation = instantiateTypeNoAlias(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters))))); + links.instantiations.set(id, instantiation = instantiateType(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters))))); } return instantiation; } @@ -25889,10 +25919,6 @@ var ts; function instantiateSignatures(signatures, mapper) { return instantiateList(signatures, mapper, instantiateSignature); } - function instantiateCached(type, mapper, instantiator) { - var instantiations = mapper.instantiations || (mapper.instantiations = []); - return instantiations[type.id] || (instantiations[type.id] = instantiator(type, mapper)); - } function makeUnaryTypeMapper(source, target) { return function (t) { return t === source ? target : t; }; } @@ -25911,19 +25937,15 @@ var ts; } function createTypeMapper(sources, targets) { ts.Debug.assert(targets === undefined || sources.length === targets.length); - var mapper = sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) : + return sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) : sources.length === 2 ? makeBinaryTypeMapper(sources[0], targets ? targets[0] : anyType, sources[1], targets ? targets[1] : anyType) : makeArrayTypeMapper(sources, targets); - mapper.mappedTypes = sources; - return mapper; } function createTypeEraser(sources) { return createTypeMapper(sources, undefined); } function createBackreferenceMapper(typeParameters, index) { - var mapper = function (t) { return ts.indexOf(typeParameters, t) >= index ? emptyObjectType : t; }; - mapper.mappedTypes = typeParameters; - return mapper; + return function (t) { return ts.indexOf(typeParameters, t) >= index ? emptyObjectType : t; }; } function isInferenceContext(mapper) { return !!mapper.signature; @@ -25937,14 +25959,10 @@ var ts; return type; } function combineTypeMappers(mapper1, mapper2) { - var mapper = function (t) { return instantiateType(mapper1(t), mapper2); }; - mapper.mappedTypes = ts.concatenate(mapper1.mappedTypes, mapper2.mappedTypes); - return mapper; + return function (t) { return instantiateType(mapper1(t), mapper2); }; } function createReplacementMapper(source, target, baseMapper) { - var mapper = function (t) { return t === source ? target : baseMapper(t); }; - mapper.mappedTypes = baseMapper.mappedTypes; - return mapper; + return function (t) { return t === source ? target : baseMapper(t); }; } function cloneTypeParameter(typeParameter) { var result = createType(16384); @@ -26004,13 +26022,45 @@ var ts; } return result; } - function instantiateAnonymousType(type, mapper) { - var result = createObjectType(16 | 64, type.symbol); - result.target = type.objectFlags & 64 ? type.target : type; - result.mapper = type.objectFlags & 64 ? combineTypeMappers(type.mapper, mapper) : mapper; - result.aliasSymbol = type.aliasSymbol; - result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper); - return result; + function getAnonymousTypeInstantiation(type, mapper) { + var target = type.objectFlags & 64 ? type.target : type; + var symbol = target.symbol; + var links = getSymbolLinks(symbol); + var typeParameters = links.typeParameters; + if (!typeParameters) { + var declaration_1 = symbol.declarations[0]; + var outerTypeParameters = getOuterTypeParameters(declaration_1, true) || ts.emptyArray; + typeParameters = symbol.flags & 2048 && !target.aliasTypeArguments ? + ts.filter(outerTypeParameters, function (tp) { return isTypeParameterReferencedWithin(tp, declaration_1); }) : + outerTypeParameters; + links.typeParameters = typeParameters; + if (typeParameters.length) { + links.instantiations = ts.createMap(); + links.instantiations.set(getTypeListId(typeParameters), target); + } + } + if (typeParameters.length) { + var combinedMapper = type.objectFlags & 64 ? combineTypeMappers(type.mapper, mapper) : mapper; + var typeArguments = ts.map(typeParameters, combinedMapper); + var id = getTypeListId(typeArguments); + var result = links.instantiations.get(id); + if (!result) { + var newMapper = createTypeMapper(typeParameters, typeArguments); + result = target.objectFlags & 32 ? instantiateMappedType(target, newMapper) : instantiateAnonymousType(target, newMapper); + links.instantiations.set(id, result); + } + return result; + } + return type; + } + function isTypeParameterReferencedWithin(tp, node) { + return tp.isThisType ? ts.forEachChild(node, checkThis) : ts.forEachChild(node, checkIdentifier); + function checkThis(node) { + return node.kind === 169 || ts.forEachChild(node, checkThis); + } + function checkIdentifier(node) { + return node.kind === 71 && ts.isPartOfTypeNode(node) && getTypeFromTypeNode(node) === tp || ts.forEachChild(node, checkIdentifier); + } } function instantiateMappedType(type, mapper) { var constraintType = getConstraintTypeFromMappedType(type); @@ -26021,134 +26071,58 @@ var ts; if (typeVariable_1 !== mappedTypeVariable) { return mapType(mappedTypeVariable, function (t) { if (isMappableType(t)) { - return instantiateMappedObjectType(type, createReplacementMapper(typeVariable_1, t, mapper)); + return instantiateAnonymousType(type, createReplacementMapper(typeVariable_1, t, mapper)); } return t; }); } } } - return instantiateMappedObjectType(type, mapper); + return instantiateAnonymousType(type, mapper); } function isMappableType(type) { return type.flags & (16384 | 32768 | 131072 | 524288); } - function instantiateMappedObjectType(type, mapper) { - var result = createObjectType(32 | 64, type.symbol); - result.declaration = type.declaration; - result.mapper = type.mapper ? combineTypeMappers(type.mapper, mapper) : mapper; + function instantiateAnonymousType(type, mapper) { + var result = createObjectType(type.objectFlags | 64, type.symbol); + if (type.objectFlags & 32) { + result.declaration = type.declaration; + } + result.target = type; + result.mapper = mapper; result.aliasSymbol = type.aliasSymbol; result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper); return result; } - function isSymbolInScopeOfMappedTypeParameter(symbol, mapper) { - if (!(symbol.declarations && symbol.declarations.length)) { - return false; - } - var mappedTypes = mapper.mappedTypes; - return !!ts.findAncestor(symbol.declarations[0], function (node) { - if (node.kind === 233 || node.kind === 265) { - return "quit"; - } - switch (node.kind) { - case 160: - case 161: - case 228: - case 151: - case 150: - case 152: - case 155: - case 156: - case 157: - case 153: - case 154: - case 186: - case 187: - case 229: - case 199: - case 230: - case 231: - var typeParameters = ts.getEffectiveTypeParameterDeclarations(node); - if (typeParameters) { - for (var _i = 0, typeParameters_1 = typeParameters; _i < typeParameters_1.length; _i++) { - var d = typeParameters_1[_i]; - if (ts.contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode(d)))) { - return true; - } - } - } - if (ts.isClassLike(node) || node.kind === 230) { - var thisType = getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node)).thisType; - if (thisType && ts.contains(mappedTypes, thisType)) { - return true; - } - } - break; - case 172: - if (ts.contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter)))) { - return true; - } - break; - case 273: - var func = node; - for (var _a = 0, _b = func.parameters; _a < _b.length; _a++) { - var p = _b[_a]; - if (ts.contains(mappedTypes, getTypeOfNode(p))) { - return true; - } - } - break; - } - }); - } - function isTopLevelTypeAlias(symbol) { - if (symbol.declarations && symbol.declarations.length) { - var parentKind = symbol.declarations[0].parent.kind; - return parentKind === 265 || parentKind === 234; - } - return false; - } function instantiateType(type, mapper) { if (type && mapper !== identityMapper) { - if (type.aliasSymbol && isTopLevelTypeAlias(type.aliasSymbol)) { - if (type.aliasTypeArguments) { - return getTypeAliasInstantiation(type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); + if (type.flags & 16384) { + return mapper(type); + } + if (type.flags & 32768) { + if (type.objectFlags & 16) { + return type.symbol && type.symbol.flags & (16 | 8192 | 32 | 2048 | 4096) && type.symbol.declarations ? + getAnonymousTypeInstantiation(type, mapper) : type; + } + if (type.objectFlags & 32) { + return getAnonymousTypeInstantiation(type, mapper); + } + if (type.objectFlags & 4) { + return createTypeReference(type.target, instantiateTypes(type.typeArguments, mapper)); } - return type; } - return instantiateTypeNoAlias(type, mapper); - } - return type; - } - function instantiateTypeNoAlias(type, mapper) { - if (type.flags & 16384) { - return mapper(type); - } - if (type.flags & 32768) { - if (type.objectFlags & 16) { - return type.symbol && - type.symbol.flags & (16 | 8192 | 32 | 2048 | 4096) && - (type.objectFlags & 64 || isSymbolInScopeOfMappedTypeParameter(type.symbol, mapper)) ? - instantiateCached(type, mapper, instantiateAnonymousType) : type; + if (type.flags & 65536 && !(type.flags & 8190)) { + return getUnionType(instantiateTypes(type.types, mapper), false, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); } - if (type.objectFlags & 32) { - return instantiateCached(type, mapper, instantiateMappedType); + if (type.flags & 131072) { + return getIntersectionType(instantiateTypes(type.types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); } - if (type.objectFlags & 4) { - return createTypeReference(type.target, instantiateTypes(type.typeArguments, mapper)); + if (type.flags & 262144) { + return getIndexType(instantiateType(type.type, mapper)); + } + if (type.flags & 524288) { + return getIndexedAccessType(instantiateType(type.objectType, mapper), instantiateType(type.indexType, mapper)); } - } - if (type.flags & 65536 && !(type.flags & 8190)) { - return getUnionType(instantiateTypes(type.types, mapper), false, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); - } - if (type.flags & 131072) { - return getIntersectionType(instantiateTypes(type.types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); - } - if (type.flags & 262144) { - return getIndexType(instantiateType(type.type, mapper)); - } - if (type.flags & 524288) { - return getIndexedAccessType(instantiateType(type.objectType, mapper), instantiateType(type.indexType, mapper)); } return type; } @@ -26262,7 +26236,8 @@ var ts; if (!target.hasRestParameter && source.minArgumentCount > target.parameters.length) { return 0; } - if (source.typeParameters) { + if (source.typeParameters && source.typeParameters !== target.typeParameters) { + target = getCanonicalSignature(target); source = instantiateSignatureInContextOf(source, target, undefined, compareTypes); } var result = -1; @@ -27750,7 +27725,6 @@ var ts; function createInferenceContext(signature, flags, compareTypes, baseInferences) { var inferences = baseInferences ? ts.map(baseInferences, cloneInferenceInfo) : ts.map(signature.typeParameters, createInferenceInfo); var context = mapper; - context.mappedTypes = signature.typeParameters; context.signature = signature; context.inferences = inferences; context.flags = flags; @@ -69222,7 +69196,7 @@ var ts; if (isTypeParameterList) { isVariadic = false; prefixDisplayParts.push(ts.punctuationPart(27)); - var typeParameters = candidateSignature.mapper ? candidateSignature.mapper.mappedTypes : candidateSignature.typeParameters; + var typeParameters = (candidateSignature.target || candidateSignature).typeParameters; signatureHelpParameters = typeParameters && typeParameters.length > 0 ? ts.map(typeParameters, createSignatureHelpParameterForTypeParameter) : ts.emptyArray; suffixDisplayParts.push(ts.punctuationPart(29)); var parameterParts = ts.mapToDisplayParts(function (writer) { @@ -74626,7 +74600,7 @@ var ts; Messages.CannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators = createMessage("Cannot extract range containing writes to references located outside of the target range in generators."); Messages.TypeWillNotBeVisibleInTheNewScope = createMessage("Type will not visible in the new scope."); Messages.FunctionWillNotBeVisibleInTheNewScope = createMessage("Function will not visible in the new scope."); - Messages.InsufficientSelection = createMessage("Select more than a single identifier."); + Messages.InsufficientSelection = createMessage("Select more than a single token."); Messages.CannotExtractExportedEntity = createMessage("Cannot extract exported declaration"); Messages.CannotCombineWritesAndReturns = createMessage("Cannot combine writes and returns"); Messages.CannotExtractReadonlyPropertyInitializerOutsideConstructor = createMessage("Cannot move initialization of read-only class property outside of the constructor"); @@ -74691,7 +74665,7 @@ var ts; return { errors: [ts.createFileDiagnostic(sourceFile, start, length, message)] }; } function checkRootNode(node) { - if (ts.isIdentifier(node)) { + if (ts.isToken(node)) { return [ts.createDiagnosticForNode(node, Messages.InsufficientSelection)]; } return undefined; @@ -83691,12 +83665,15 @@ var ts; var _this = this; this.telemetryEnabled = telemetryEnabled; this.logger = logger; + this.host = host; this.globalTypingsCacheLocation = globalTypingsCacheLocation; this.typingSafeListLocation = typingSafeListLocation; this.npmLocation = npmLocation; this.newLine = newLine; this.installerPidReported = false; - this.throttledOperations = new server.ThrottledOperations(host); + this.activeRequestCount = 0; + this.requestQueue = []; + this.requestMap = ts.createMap(); if (eventPort) { var s_1 = net.connect({ port: eventPort }, function () { _this.socket = s_1; @@ -83768,12 +83745,24 @@ var ts; this.logger.info("Scheduling throttled operation: " + JSON.stringify(request)); } } - this.throttledOperations.schedule(project.getProjectName(), 250, function () { + var operationId = project.getProjectName(); + var operation = function () { if (_this.logger.hasLevel(server.LogLevel.verbose)) { _this.logger.info("Sending request: " + JSON.stringify(request)); } _this.installer.send(request); - }); + }; + var queuedRequest = { operationId: operationId, operation: operation }; + if (this.activeRequestCount < NodeTypingsInstaller.maxActiveRequestCount) { + this.scheduleRequest(queuedRequest); + } + else { + if (this.logger.hasLevel(server.LogLevel.verbose)) { + this.logger.info("Deferring request for: " + operationId); + } + this.requestQueue.push(queuedRequest); + this.requestMap.set(operationId, queuedRequest); + } }; NodeTypingsInstaller.prototype.handleMessage = function (response) { if (this.logger.hasLevel(server.LogLevel.verbose)) { @@ -83827,11 +83816,37 @@ var ts; this.eventSender.event(body, eventName); return; } + if (this.activeRequestCount > 0) { + this.activeRequestCount--; + } + else { + ts.Debug.fail("Received too many responses"); + } + while (this.requestQueue.length > 0) { + var queuedRequest = this.requestQueue.shift(); + if (this.requestMap.get(queuedRequest.operationId) === queuedRequest) { + this.requestMap.delete(queuedRequest.operationId); + this.scheduleRequest(queuedRequest); + break; + } + if (this.logger.hasLevel(server.LogLevel.verbose)) { + this.logger.info("Skipping defunct request for: " + queuedRequest.operationId); + } + } this.projectService.updateTypingsForProject(response); if (response.kind === server.ActionSet && this.socket) { this.sendEvent(0, "setTypings", response); } }; + NodeTypingsInstaller.prototype.scheduleRequest = function (request) { + if (this.logger.hasLevel(server.LogLevel.verbose)) { + this.logger.info("Scheduling request for: " + request.operationId); + } + this.activeRequestCount++; + this.host.setTimeout(request.operation, NodeTypingsInstaller.requestDelayMillis); + }; + NodeTypingsInstaller.maxActiveRequestCount = 10; + NodeTypingsInstaller.requestDelayMillis = 100; return NodeTypingsInstaller; }()); var IOSession = (function (_super) { diff --git a/lib/tsserverlibrary.d.ts b/lib/tsserverlibrary.d.ts index 4779895cbab..d43491f9436 100644 --- a/lib/tsserverlibrary.d.ts +++ b/lib/tsserverlibrary.d.ts @@ -1429,7 +1429,6 @@ declare namespace ts { interface JSDocTypeLiteral extends JSDocType { kind: SyntaxKind.JSDocTypeLiteral; jsDocPropertyTags?: ReadonlyArray; - jsDocTypeTag?: JSDocTypeTag; isArrayType?: boolean; } enum FlowFlags { diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js index 93916b40bff..2d3d4cf3e54 100644 --- a/lib/tsserverlibrary.js +++ b/lib/tsserverlibrary.js @@ -10984,9 +10984,11 @@ var ts; visitNode(cbNode, node.typeExpression); } case 285: - for (var _i = 0, _a = node.jsDocPropertyTags; _i < _a.length; _i++) { - var tag = _a[_i]; - visitNode(cbNode, tag); + if (node.jsDocPropertyTags) { + for (var _i = 0, _a = node.jsDocPropertyTags; _i < _a.length; _i++) { + var tag = _a[_i]; + visitNode(cbNode, tag); + } } return; case 288: @@ -15401,19 +15403,18 @@ var ts; if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) { var child = void 0; var jsdocTypeLiteral = void 0; - var alreadyHasTypeTag = false; + var childTypeTag = void 0; var start_3 = scanner.getStartPos(); while (child = tryParse(function () { return parseChildParameterOrPropertyTag(0); })) { if (!jsdocTypeLiteral) { jsdocTypeLiteral = createNode(285, start_3); } if (child.kind === 281) { - if (alreadyHasTypeTag) { + if (childTypeTag) { break; } else { - jsdocTypeLiteral.jsDocTypeTag = child; - alreadyHasTypeTag = true; + childTypeTag = child; } } else { @@ -15427,7 +15428,9 @@ var ts; if (typeExpression && typeExpression.type.kind === 164) { jsdocTypeLiteral.isArrayType = true; } - typedefTag.typeExpression = finishNode(jsdocTypeLiteral); + typedefTag.typeExpression = childTypeTag && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ? + childTypeTag.typeExpression : + finishNode(jsdocTypeLiteral); } } return finishNode(typedefTag); @@ -24873,25 +24876,44 @@ var ts; } return typeParameters; } - function appendOuterTypeParameters(typeParameters, node) { + function getOuterTypeParameters(node, includeThisTypes) { while (true) { node = node.parent; if (!node) { - return typeParameters; + return undefined; } - if (node.kind === 229 || node.kind === 199 || - node.kind === 228 || node.kind === 186 || - node.kind === 151 || node.kind === 187) { - var declarations = node.typeParameters; - if (declarations) { - return appendTypeParameters(appendOuterTypeParameters(typeParameters, node), declarations); - } + switch (node.kind) { + case 229: + case 199: + case 230: + case 155: + case 156: + case 150: + case 160: + case 161: + case 273: + case 228: + case 151: + case 186: + case 187: + case 231: + case 282: + case 172: + var outerTypeParameters = getOuterTypeParameters(node, includeThisTypes); + if (node.kind === 172) { + return ts.append(outerTypeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter))); + } + var outerAndOwnTypeParameters = appendTypeParameters(outerTypeParameters, ts.getEffectiveTypeParameterDeclarations(node) || ts.emptyArray); + var thisType = includeThisTypes && + (node.kind === 229 || node.kind === 199 || node.kind === 230) && + getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node)).thisType; + return thisType ? ts.append(outerAndOwnTypeParameters, thisType) : outerAndOwnTypeParameters; } } } function getOuterTypeParametersOfClassOrInterface(symbol) { var declaration = symbol.flags & 32 ? symbol.valueDeclaration : ts.getDeclarationOfKind(symbol, 230); - return appendOuterTypeParameters(undefined, declaration); + return getOuterTypeParameters(declaration); } function getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol) { var result; @@ -26415,12 +26437,20 @@ var ts; return instantiateSignature(signature, createTypeMapper(signature.typeParameters, typeArguments), true); } function getErasedSignature(signature) { - if (!signature.typeParameters) - return signature; - if (!signature.erasedSignatureCache) { - signature.erasedSignatureCache = instantiateSignature(signature, createTypeEraser(signature.typeParameters), true); - } - return signature.erasedSignatureCache; + return signature.typeParameters ? + signature.erasedSignatureCache || (signature.erasedSignatureCache = createErasedSignature(signature)) : + signature; + } + function createErasedSignature(signature) { + return instantiateSignature(signature, createTypeEraser(signature.typeParameters), true); + } + function getCanonicalSignature(signature) { + return signature.typeParameters ? + signature.canonicalSignatureCache || (signature.canonicalSignatureCache = createCanonicalSignature(signature)) : + signature; + } + function createCanonicalSignature(signature) { + return getSignatureInstantiation(signature, ts.map(signature.typeParameters, function (tp) { return tp.target && !getConstraintOfTypeParameter(tp.target) ? tp.target : tp; })); } function getOrCreateTypeFromSignature(signature) { if (!signature.isolatedSignatureType) { @@ -26567,7 +26597,7 @@ var ts; var id = getTypeListId(typeArguments); var instantiation = links.instantiations.get(id); if (!instantiation) { - links.instantiations.set(id, instantiation = instantiateTypeNoAlias(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters))))); + links.instantiations.set(id, instantiation = instantiateType(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters))))); } return instantiation; } @@ -27595,10 +27625,6 @@ var ts; function instantiateSignatures(signatures, mapper) { return instantiateList(signatures, mapper, instantiateSignature); } - function instantiateCached(type, mapper, instantiator) { - var instantiations = mapper.instantiations || (mapper.instantiations = []); - return instantiations[type.id] || (instantiations[type.id] = instantiator(type, mapper)); - } function makeUnaryTypeMapper(source, target) { return function (t) { return t === source ? target : t; }; } @@ -27617,19 +27643,15 @@ var ts; } function createTypeMapper(sources, targets) { ts.Debug.assert(targets === undefined || sources.length === targets.length); - var mapper = sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) : + return sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) : sources.length === 2 ? makeBinaryTypeMapper(sources[0], targets ? targets[0] : anyType, sources[1], targets ? targets[1] : anyType) : makeArrayTypeMapper(sources, targets); - mapper.mappedTypes = sources; - return mapper; } function createTypeEraser(sources) { return createTypeMapper(sources, undefined); } function createBackreferenceMapper(typeParameters, index) { - var mapper = function (t) { return ts.indexOf(typeParameters, t) >= index ? emptyObjectType : t; }; - mapper.mappedTypes = typeParameters; - return mapper; + return function (t) { return ts.indexOf(typeParameters, t) >= index ? emptyObjectType : t; }; } function isInferenceContext(mapper) { return !!mapper.signature; @@ -27643,14 +27665,10 @@ var ts; return type; } function combineTypeMappers(mapper1, mapper2) { - var mapper = function (t) { return instantiateType(mapper1(t), mapper2); }; - mapper.mappedTypes = ts.concatenate(mapper1.mappedTypes, mapper2.mappedTypes); - return mapper; + return function (t) { return instantiateType(mapper1(t), mapper2); }; } function createReplacementMapper(source, target, baseMapper) { - var mapper = function (t) { return t === source ? target : baseMapper(t); }; - mapper.mappedTypes = baseMapper.mappedTypes; - return mapper; + return function (t) { return t === source ? target : baseMapper(t); }; } function cloneTypeParameter(typeParameter) { var result = createType(16384); @@ -27710,13 +27728,45 @@ var ts; } return result; } - function instantiateAnonymousType(type, mapper) { - var result = createObjectType(16 | 64, type.symbol); - result.target = type.objectFlags & 64 ? type.target : type; - result.mapper = type.objectFlags & 64 ? combineTypeMappers(type.mapper, mapper) : mapper; - result.aliasSymbol = type.aliasSymbol; - result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper); - return result; + function getAnonymousTypeInstantiation(type, mapper) { + var target = type.objectFlags & 64 ? type.target : type; + var symbol = target.symbol; + var links = getSymbolLinks(symbol); + var typeParameters = links.typeParameters; + if (!typeParameters) { + var declaration_1 = symbol.declarations[0]; + var outerTypeParameters = getOuterTypeParameters(declaration_1, true) || ts.emptyArray; + typeParameters = symbol.flags & 2048 && !target.aliasTypeArguments ? + ts.filter(outerTypeParameters, function (tp) { return isTypeParameterReferencedWithin(tp, declaration_1); }) : + outerTypeParameters; + links.typeParameters = typeParameters; + if (typeParameters.length) { + links.instantiations = ts.createMap(); + links.instantiations.set(getTypeListId(typeParameters), target); + } + } + if (typeParameters.length) { + var combinedMapper = type.objectFlags & 64 ? combineTypeMappers(type.mapper, mapper) : mapper; + var typeArguments = ts.map(typeParameters, combinedMapper); + var id = getTypeListId(typeArguments); + var result = links.instantiations.get(id); + if (!result) { + var newMapper = createTypeMapper(typeParameters, typeArguments); + result = target.objectFlags & 32 ? instantiateMappedType(target, newMapper) : instantiateAnonymousType(target, newMapper); + links.instantiations.set(id, result); + } + return result; + } + return type; + } + function isTypeParameterReferencedWithin(tp, node) { + return tp.isThisType ? ts.forEachChild(node, checkThis) : ts.forEachChild(node, checkIdentifier); + function checkThis(node) { + return node.kind === 169 || ts.forEachChild(node, checkThis); + } + function checkIdentifier(node) { + return node.kind === 71 && ts.isPartOfTypeNode(node) && getTypeFromTypeNode(node) === tp || ts.forEachChild(node, checkIdentifier); + } } function instantiateMappedType(type, mapper) { var constraintType = getConstraintTypeFromMappedType(type); @@ -27727,134 +27777,58 @@ var ts; if (typeVariable_1 !== mappedTypeVariable) { return mapType(mappedTypeVariable, function (t) { if (isMappableType(t)) { - return instantiateMappedObjectType(type, createReplacementMapper(typeVariable_1, t, mapper)); + return instantiateAnonymousType(type, createReplacementMapper(typeVariable_1, t, mapper)); } return t; }); } } } - return instantiateMappedObjectType(type, mapper); + return instantiateAnonymousType(type, mapper); } function isMappableType(type) { return type.flags & (16384 | 32768 | 131072 | 524288); } - function instantiateMappedObjectType(type, mapper) { - var result = createObjectType(32 | 64, type.symbol); - result.declaration = type.declaration; - result.mapper = type.mapper ? combineTypeMappers(type.mapper, mapper) : mapper; + function instantiateAnonymousType(type, mapper) { + var result = createObjectType(type.objectFlags | 64, type.symbol); + if (type.objectFlags & 32) { + result.declaration = type.declaration; + } + result.target = type; + result.mapper = mapper; result.aliasSymbol = type.aliasSymbol; result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper); return result; } - function isSymbolInScopeOfMappedTypeParameter(symbol, mapper) { - if (!(symbol.declarations && symbol.declarations.length)) { - return false; - } - var mappedTypes = mapper.mappedTypes; - return !!ts.findAncestor(symbol.declarations[0], function (node) { - if (node.kind === 233 || node.kind === 265) { - return "quit"; - } - switch (node.kind) { - case 160: - case 161: - case 228: - case 151: - case 150: - case 152: - case 155: - case 156: - case 157: - case 153: - case 154: - case 186: - case 187: - case 229: - case 199: - case 230: - case 231: - var typeParameters = ts.getEffectiveTypeParameterDeclarations(node); - if (typeParameters) { - for (var _i = 0, typeParameters_1 = typeParameters; _i < typeParameters_1.length; _i++) { - var d = typeParameters_1[_i]; - if (ts.contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode(d)))) { - return true; - } - } - } - if (ts.isClassLike(node) || node.kind === 230) { - var thisType = getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node)).thisType; - if (thisType && ts.contains(mappedTypes, thisType)) { - return true; - } - } - break; - case 172: - if (ts.contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter)))) { - return true; - } - break; - case 273: - var func = node; - for (var _a = 0, _b = func.parameters; _a < _b.length; _a++) { - var p = _b[_a]; - if (ts.contains(mappedTypes, getTypeOfNode(p))) { - return true; - } - } - break; - } - }); - } - function isTopLevelTypeAlias(symbol) { - if (symbol.declarations && symbol.declarations.length) { - var parentKind = symbol.declarations[0].parent.kind; - return parentKind === 265 || parentKind === 234; - } - return false; - } function instantiateType(type, mapper) { if (type && mapper !== identityMapper) { - if (type.aliasSymbol && isTopLevelTypeAlias(type.aliasSymbol)) { - if (type.aliasTypeArguments) { - return getTypeAliasInstantiation(type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); + if (type.flags & 16384) { + return mapper(type); + } + if (type.flags & 32768) { + if (type.objectFlags & 16) { + return type.symbol && type.symbol.flags & (16 | 8192 | 32 | 2048 | 4096) && type.symbol.declarations ? + getAnonymousTypeInstantiation(type, mapper) : type; + } + if (type.objectFlags & 32) { + return getAnonymousTypeInstantiation(type, mapper); + } + if (type.objectFlags & 4) { + return createTypeReference(type.target, instantiateTypes(type.typeArguments, mapper)); } - return type; } - return instantiateTypeNoAlias(type, mapper); - } - return type; - } - function instantiateTypeNoAlias(type, mapper) { - if (type.flags & 16384) { - return mapper(type); - } - if (type.flags & 32768) { - if (type.objectFlags & 16) { - return type.symbol && - type.symbol.flags & (16 | 8192 | 32 | 2048 | 4096) && - (type.objectFlags & 64 || isSymbolInScopeOfMappedTypeParameter(type.symbol, mapper)) ? - instantiateCached(type, mapper, instantiateAnonymousType) : type; + if (type.flags & 65536 && !(type.flags & 8190)) { + return getUnionType(instantiateTypes(type.types, mapper), false, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); } - if (type.objectFlags & 32) { - return instantiateCached(type, mapper, instantiateMappedType); + if (type.flags & 131072) { + return getIntersectionType(instantiateTypes(type.types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); } - if (type.objectFlags & 4) { - return createTypeReference(type.target, instantiateTypes(type.typeArguments, mapper)); + if (type.flags & 262144) { + return getIndexType(instantiateType(type.type, mapper)); + } + if (type.flags & 524288) { + return getIndexedAccessType(instantiateType(type.objectType, mapper), instantiateType(type.indexType, mapper)); } - } - if (type.flags & 65536 && !(type.flags & 8190)) { - return getUnionType(instantiateTypes(type.types, mapper), false, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); - } - if (type.flags & 131072) { - return getIntersectionType(instantiateTypes(type.types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); - } - if (type.flags & 262144) { - return getIndexType(instantiateType(type.type, mapper)); - } - if (type.flags & 524288) { - return getIndexedAccessType(instantiateType(type.objectType, mapper), instantiateType(type.indexType, mapper)); } return type; } @@ -27968,7 +27942,8 @@ var ts; if (!target.hasRestParameter && source.minArgumentCount > target.parameters.length) { return 0; } - if (source.typeParameters) { + if (source.typeParameters && source.typeParameters !== target.typeParameters) { + target = getCanonicalSignature(target); source = instantiateSignatureInContextOf(source, target, undefined, compareTypes); } var result = -1; @@ -29456,7 +29431,6 @@ var ts; function createInferenceContext(signature, flags, compareTypes, baseInferences) { var inferences = baseInferences ? ts.map(baseInferences, cloneInferenceInfo) : ts.map(signature.typeParameters, createInferenceInfo); var context = mapper; - context.mappedTypes = signature.typeParameters; context.signature = signature; context.inferences = inferences; context.flags = flags; @@ -69222,7 +69196,7 @@ var ts; if (isTypeParameterList) { isVariadic = false; prefixDisplayParts.push(ts.punctuationPart(27)); - var typeParameters = candidateSignature.mapper ? candidateSignature.mapper.mappedTypes : candidateSignature.typeParameters; + var typeParameters = (candidateSignature.target || candidateSignature).typeParameters; signatureHelpParameters = typeParameters && typeParameters.length > 0 ? ts.map(typeParameters, createSignatureHelpParameterForTypeParameter) : ts.emptyArray; suffixDisplayParts.push(ts.punctuationPart(29)); var parameterParts = ts.mapToDisplayParts(function (writer) { @@ -74626,7 +74600,7 @@ var ts; Messages.CannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators = createMessage("Cannot extract range containing writes to references located outside of the target range in generators."); Messages.TypeWillNotBeVisibleInTheNewScope = createMessage("Type will not visible in the new scope."); Messages.FunctionWillNotBeVisibleInTheNewScope = createMessage("Function will not visible in the new scope."); - Messages.InsufficientSelection = createMessage("Select more than a single identifier."); + Messages.InsufficientSelection = createMessage("Select more than a single token."); Messages.CannotExtractExportedEntity = createMessage("Cannot extract exported declaration"); Messages.CannotCombineWritesAndReturns = createMessage("Cannot combine writes and returns"); Messages.CannotExtractReadonlyPropertyInitializerOutsideConstructor = createMessage("Cannot move initialization of read-only class property outside of the constructor"); @@ -74691,7 +74665,7 @@ var ts; return { errors: [ts.createFileDiagnostic(sourceFile, start, length, message)] }; } function checkRootNode(node) { - if (ts.isIdentifier(node)) { + if (ts.isToken(node)) { return [ts.createDiagnosticForNode(node, Messages.InsufficientSelection)]; } return undefined; diff --git a/lib/typescript.d.ts b/lib/typescript.d.ts index 4b62e695c82..dd3414c68fd 100644 --- a/lib/typescript.d.ts +++ b/lib/typescript.d.ts @@ -1472,7 +1472,6 @@ declare namespace ts { interface JSDocTypeLiteral extends JSDocType { kind: SyntaxKind.JSDocTypeLiteral; jsDocPropertyTags?: ReadonlyArray; - jsDocTypeTag?: JSDocTypeTag; /** If true, then this type literal represents an *array* of its type. */ isArrayType?: boolean; } diff --git a/lib/typescript.js b/lib/typescript.js index 74272714529..ae40057ff89 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -12298,9 +12298,11 @@ var ts; visitNode(cbNode, node.typeExpression); } case 285 /* JSDocTypeLiteral */: - for (var _i = 0, _a = node.jsDocPropertyTags; _i < _a.length; _i++) { - var tag = _a[_i]; - visitNode(cbNode, tag); + if (node.jsDocPropertyTags) { + for (var _i = 0, _a = node.jsDocPropertyTags; _i < _a.length; _i++) { + var tag = _a[_i]; + visitNode(cbNode, tag); + } } return; case 288 /* PartiallyEmittedExpression */: @@ -17782,19 +17784,18 @@ var ts; if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) { var child = void 0; var jsdocTypeLiteral = void 0; - var alreadyHasTypeTag = false; + var childTypeTag = void 0; var start_3 = scanner.getStartPos(); while (child = tryParse(function () { return parseChildParameterOrPropertyTag(0 /* Property */); })) { if (!jsdocTypeLiteral) { jsdocTypeLiteral = createNode(285 /* JSDocTypeLiteral */, start_3); } if (child.kind === 281 /* JSDocTypeTag */) { - if (alreadyHasTypeTag) { + if (childTypeTag) { break; } else { - jsdocTypeLiteral.jsDocTypeTag = child; - alreadyHasTypeTag = true; + childTypeTag = child; } } else { @@ -17808,7 +17809,9 @@ var ts; if (typeExpression && typeExpression.type.kind === 164 /* ArrayType */) { jsdocTypeLiteral.isArrayType = true; } - typedefTag.typeExpression = finishNode(jsdocTypeLiteral); + typedefTag.typeExpression = childTypeTag && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ? + childTypeTag.typeExpression : + finishNode(jsdocTypeLiteral); } } return finishNode(typedefTag); @@ -26928,29 +26931,46 @@ var ts; } return typeParameters; } - // Appends the outer type parameters of a node to a set of type parameters and returns the resulting set. The function - // allocates a new array if the input type parameter set is undefined, but otherwise it modifies the set in-place and - // returns the same array. - function appendOuterTypeParameters(typeParameters, node) { + // Return the outer type parameters of a node or undefined if the node has no outer type parameters. + function getOuterTypeParameters(node, includeThisTypes) { while (true) { node = node.parent; if (!node) { - return typeParameters; + return undefined; } - if (node.kind === 229 /* ClassDeclaration */ || node.kind === 199 /* ClassExpression */ || - node.kind === 228 /* FunctionDeclaration */ || node.kind === 186 /* FunctionExpression */ || - node.kind === 151 /* MethodDeclaration */ || node.kind === 187 /* ArrowFunction */) { - var declarations = node.typeParameters; - if (declarations) { - return appendTypeParameters(appendOuterTypeParameters(typeParameters, node), declarations); - } + switch (node.kind) { + case 229 /* ClassDeclaration */: + case 199 /* ClassExpression */: + case 230 /* InterfaceDeclaration */: + case 155 /* CallSignature */: + case 156 /* ConstructSignature */: + case 150 /* MethodSignature */: + case 160 /* FunctionType */: + case 161 /* ConstructorType */: + case 273 /* JSDocFunctionType */: + case 228 /* FunctionDeclaration */: + case 151 /* MethodDeclaration */: + case 186 /* FunctionExpression */: + case 187 /* ArrowFunction */: + case 231 /* TypeAliasDeclaration */: + case 282 /* JSDocTemplateTag */: + case 172 /* MappedType */: + var outerTypeParameters = getOuterTypeParameters(node, includeThisTypes); + if (node.kind === 172 /* MappedType */) { + return ts.append(outerTypeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter))); + } + var outerAndOwnTypeParameters = appendTypeParameters(outerTypeParameters, ts.getEffectiveTypeParameterDeclarations(node) || ts.emptyArray); + var thisType = includeThisTypes && + (node.kind === 229 /* ClassDeclaration */ || node.kind === 199 /* ClassExpression */ || node.kind === 230 /* InterfaceDeclaration */) && + getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node)).thisType; + return thisType ? ts.append(outerAndOwnTypeParameters, thisType) : outerAndOwnTypeParameters; } } } // The outer type parameters are those defined by enclosing generic classes, methods, or functions. function getOuterTypeParametersOfClassOrInterface(symbol) { var declaration = symbol.flags & 32 /* Class */ ? symbol.valueDeclaration : ts.getDeclarationOfKind(symbol, 230 /* InterfaceDeclaration */); - return appendOuterTypeParameters(/*typeParameters*/ undefined, declaration); + return getOuterTypeParameters(declaration); } // The local type parameters are the combined set of type parameters from all declarations of the class, // interface, or type alias. @@ -28652,12 +28672,27 @@ var ts; return instantiateSignature(signature, createTypeMapper(signature.typeParameters, typeArguments), /*eraseTypeParameters*/ true); } function getErasedSignature(signature) { - if (!signature.typeParameters) - return signature; - if (!signature.erasedSignatureCache) { - signature.erasedSignatureCache = instantiateSignature(signature, createTypeEraser(signature.typeParameters), /*eraseTypeParameters*/ true); - } - return signature.erasedSignatureCache; + return signature.typeParameters ? + signature.erasedSignatureCache || (signature.erasedSignatureCache = createErasedSignature(signature)) : + signature; + } + function createErasedSignature(signature) { + // Create an instantiation of the signature where all type arguments are the any type. + return instantiateSignature(signature, createTypeEraser(signature.typeParameters), /*eraseTypeParameters*/ true); + } + function getCanonicalSignature(signature) { + return signature.typeParameters ? + signature.canonicalSignatureCache || (signature.canonicalSignatureCache = createCanonicalSignature(signature)) : + signature; + } + function createCanonicalSignature(signature) { + // Create an instantiation of the signature where each unconstrained type parameter is replaced with + // its original. When a generic class or interface is instantiated, each generic method in the class or + // interface is instantiated with a fresh set of cloned type parameters (which we need to handle scenarios + // where different generations of the same type parameter are in scope). This leads to a lot of new type + // identities, and potentially a lot of work comparing those identities, so here we create an instantiation + // that uses the original type identities for all unconstrained type parameters. + return getSignatureInstantiation(signature, ts.map(signature.typeParameters, function (tp) { return tp.target && !getConstraintOfTypeParameter(tp.target) ? tp.target : tp; })); } function getOrCreateTypeFromSignature(signature) { // There are two ways to declare a construct signature, one is by declaring a class constructor @@ -28818,7 +28853,7 @@ var ts; var id = getTypeListId(typeArguments); var instantiation = links.instantiations.get(id); if (!instantiation) { - links.instantiations.set(id, instantiation = instantiateTypeNoAlias(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters))))); + links.instantiations.set(id, instantiation = instantiateType(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters))))); } return instantiation; } @@ -29938,10 +29973,6 @@ var ts; function instantiateSignatures(signatures, mapper) { return instantiateList(signatures, mapper, instantiateSignature); } - function instantiateCached(type, mapper, instantiator) { - var instantiations = mapper.instantiations || (mapper.instantiations = []); - return instantiations[type.id] || (instantiations[type.id] = instantiator(type, mapper)); - } function makeUnaryTypeMapper(source, target) { return function (t) { return t === source ? target : t; }; } @@ -29960,11 +29991,9 @@ var ts; } function createTypeMapper(sources, targets) { ts.Debug.assert(targets === undefined || sources.length === targets.length); - var mapper = sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) : + return sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) : sources.length === 2 ? makeBinaryTypeMapper(sources[0], targets ? targets[0] : anyType, sources[1], targets ? targets[1] : anyType) : makeArrayTypeMapper(sources, targets); - mapper.mappedTypes = sources; - return mapper; } function createTypeEraser(sources) { return createTypeMapper(sources, /*targets*/ undefined); @@ -29974,9 +30003,7 @@ var ts; * This is used during inference when instantiating type parameter defaults. */ function createBackreferenceMapper(typeParameters, index) { - var mapper = function (t) { return ts.indexOf(typeParameters, t) >= index ? emptyObjectType : t; }; - mapper.mappedTypes = typeParameters; - return mapper; + return function (t) { return ts.indexOf(typeParameters, t) >= index ? emptyObjectType : t; }; } function isInferenceContext(mapper) { return !!mapper.signature; @@ -29990,14 +30017,10 @@ var ts; return type; } function combineTypeMappers(mapper1, mapper2) { - var mapper = function (t) { return instantiateType(mapper1(t), mapper2); }; - mapper.mappedTypes = ts.concatenate(mapper1.mappedTypes, mapper2.mappedTypes); - return mapper; + return function (t) { return instantiateType(mapper1(t), mapper2); }; } function createReplacementMapper(source, target, baseMapper) { - var mapper = function (t) { return t === source ? target : baseMapper(t); }; - mapper.mappedTypes = baseMapper.mappedTypes; - return mapper; + return function (t) { return t === source ? target : baseMapper(t); }; } function cloneTypeParameter(typeParameter) { var result = createType(16384 /* TypeParameter */); @@ -30066,13 +30089,52 @@ var ts; } return result; } - function instantiateAnonymousType(type, mapper) { - var result = createObjectType(16 /* Anonymous */ | 64 /* Instantiated */, type.symbol); - result.target = type.objectFlags & 64 /* Instantiated */ ? type.target : type; - result.mapper = type.objectFlags & 64 /* Instantiated */ ? combineTypeMappers(type.mapper, mapper) : mapper; - result.aliasSymbol = type.aliasSymbol; - result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper); - return result; + function getAnonymousTypeInstantiation(type, mapper) { + var target = type.objectFlags & 64 /* Instantiated */ ? type.target : type; + var symbol = target.symbol; + var links = getSymbolLinks(symbol); + var typeParameters = links.typeParameters; + if (!typeParameters) { + // The first time an anonymous type is instantiated we compute and store a list of the type + // parameters that are in scope (and therefore potentially referenced). For type literals that + // aren't the right hand side of a generic type alias declaration we optimize by reducing the + // set of type parameters to those that are actually referenced somewhere in the literal. + var declaration_1 = symbol.declarations[0]; + var outerTypeParameters = getOuterTypeParameters(declaration_1, /*includeThisTypes*/ true) || ts.emptyArray; + typeParameters = symbol.flags & 2048 /* TypeLiteral */ && !target.aliasTypeArguments ? + ts.filter(outerTypeParameters, function (tp) { return isTypeParameterReferencedWithin(tp, declaration_1); }) : + outerTypeParameters; + links.typeParameters = typeParameters; + if (typeParameters.length) { + links.instantiations = ts.createMap(); + links.instantiations.set(getTypeListId(typeParameters), target); + } + } + if (typeParameters.length) { + // We are instantiating an anonymous type that has one or more type parameters in scope. Apply the + // mapper to the type parameters to produce the effective list of type arguments, and compute the + // instantiation cache key from the type IDs of the type arguments. + var combinedMapper = type.objectFlags & 64 /* Instantiated */ ? combineTypeMappers(type.mapper, mapper) : mapper; + var typeArguments = ts.map(typeParameters, combinedMapper); + var id = getTypeListId(typeArguments); + var result = links.instantiations.get(id); + if (!result) { + var newMapper = createTypeMapper(typeParameters, typeArguments); + result = target.objectFlags & 32 /* Mapped */ ? instantiateMappedType(target, newMapper) : instantiateAnonymousType(target, newMapper); + links.instantiations.set(id, result); + } + return result; + } + return type; + } + function isTypeParameterReferencedWithin(tp, node) { + return tp.isThisType ? ts.forEachChild(node, checkThis) : ts.forEachChild(node, checkIdentifier); + function checkThis(node) { + return node.kind === 169 /* ThisType */ || ts.forEachChild(node, checkThis); + } + function checkIdentifier(node) { + return node.kind === 71 /* Identifier */ && ts.isPartOfTypeNode(node) && getTypeFromTypeNode(node) === tp || ts.forEachChild(node, checkIdentifier); + } } function instantiateMappedType(type, mapper) { // Check if we have a homomorphic mapped type, i.e. a type of the form { [P in keyof T]: X } for some @@ -30088,160 +30150,61 @@ var ts; if (typeVariable_1 !== mappedTypeVariable) { return mapType(mappedTypeVariable, function (t) { if (isMappableType(t)) { - return instantiateMappedObjectType(type, createReplacementMapper(typeVariable_1, t, mapper)); + return instantiateAnonymousType(type, createReplacementMapper(typeVariable_1, t, mapper)); } return t; }); } } } - return instantiateMappedObjectType(type, mapper); + return instantiateAnonymousType(type, mapper); } function isMappableType(type) { return type.flags & (16384 /* TypeParameter */ | 32768 /* Object */ | 131072 /* Intersection */ | 524288 /* IndexedAccess */); } - function instantiateMappedObjectType(type, mapper) { - var result = createObjectType(32 /* Mapped */ | 64 /* Instantiated */, type.symbol); - result.declaration = type.declaration; - result.mapper = type.mapper ? combineTypeMappers(type.mapper, mapper) : mapper; + function instantiateAnonymousType(type, mapper) { + var result = createObjectType(type.objectFlags | 64 /* Instantiated */, type.symbol); + if (type.objectFlags & 32 /* Mapped */) { + result.declaration = type.declaration; + } + result.target = type; + result.mapper = mapper; result.aliasSymbol = type.aliasSymbol; result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper); return result; } - function isSymbolInScopeOfMappedTypeParameter(symbol, mapper) { - if (!(symbol.declarations && symbol.declarations.length)) { - return false; - } - var mappedTypes = mapper.mappedTypes; - // Starting with the parent of the symbol's declaration, check if the mapper maps any of - // the type parameters introduced by enclosing declarations. We just pick the first - // declaration since multiple declarations will all have the same parent anyway. - return !!ts.findAncestor(symbol.declarations[0], function (node) { - if (node.kind === 233 /* ModuleDeclaration */ || node.kind === 265 /* SourceFile */) { - return "quit"; - } - switch (node.kind) { - case 160 /* FunctionType */: - case 161 /* ConstructorType */: - case 228 /* FunctionDeclaration */: - case 151 /* MethodDeclaration */: - case 150 /* MethodSignature */: - case 152 /* Constructor */: - case 155 /* CallSignature */: - case 156 /* ConstructSignature */: - case 157 /* IndexSignature */: - case 153 /* GetAccessor */: - case 154 /* SetAccessor */: - case 186 /* FunctionExpression */: - case 187 /* ArrowFunction */: - case 229 /* ClassDeclaration */: - case 199 /* ClassExpression */: - case 230 /* InterfaceDeclaration */: - case 231 /* TypeAliasDeclaration */: - var typeParameters = ts.getEffectiveTypeParameterDeclarations(node); - if (typeParameters) { - for (var _i = 0, typeParameters_1 = typeParameters; _i < typeParameters_1.length; _i++) { - var d = typeParameters_1[_i]; - if (ts.contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode(d)))) { - return true; - } - } - } - if (ts.isClassLike(node) || node.kind === 230 /* InterfaceDeclaration */) { - var thisType = getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node)).thisType; - if (thisType && ts.contains(mappedTypes, thisType)) { - return true; - } - } - break; - case 172 /* MappedType */: - if (ts.contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter)))) { - return true; - } - break; - case 273 /* JSDocFunctionType */: - var func = node; - for (var _a = 0, _b = func.parameters; _a < _b.length; _a++) { - var p = _b[_a]; - if (ts.contains(mappedTypes, getTypeOfNode(p))) { - return true; - } - } - break; - } - }); - } - function isTopLevelTypeAlias(symbol) { - if (symbol.declarations && symbol.declarations.length) { - var parentKind = symbol.declarations[0].parent.kind; - return parentKind === 265 /* SourceFile */ || parentKind === 234 /* ModuleBlock */; - } - return false; - } function instantiateType(type, mapper) { if (type && mapper !== identityMapper) { - // If we are instantiating a type that has a top-level type alias, obtain the instantiation through - // the type alias instead in order to share instantiations for the same type arguments. This can - // dramatically reduce the number of structurally identical types we generate. Note that we can only - // perform this optimization for top-level type aliases. Consider: - // - // function f1(x: T) { - // type Foo = { x: X, t: T }; - // let obj: Foo = { x: x }; - // return obj; - // } - // function f2(x: U) { return f1(x); } - // let z = f2(42); - // - // Above, the declaration of f2 has an inferred return type that is an instantiation of f1's Foo - // equivalent to { x: U, t: U }. When instantiating this return type, we can't go back to Foo's - // cache because all cached instantiations are of the form { x: ???, t: T }, i.e. they have not been - // instantiated for T. Instead, we need to further instantiate the { x: U, t: U } form. - if (type.aliasSymbol && isTopLevelTypeAlias(type.aliasSymbol)) { - if (type.aliasTypeArguments) { - return getTypeAliasInstantiation(type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); + if (type.flags & 16384 /* TypeParameter */) { + return mapper(type); + } + if (type.flags & 32768 /* Object */) { + if (type.objectFlags & 16 /* Anonymous */) { + // If the anonymous type originates in a declaration of a function, method, class, or + // interface, in an object type literal, or in an object literal expression, we may need + // to instantiate the type because it might reference a type parameter. + return type.symbol && type.symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */) && type.symbol.declarations ? + getAnonymousTypeInstantiation(type, mapper) : type; + } + if (type.objectFlags & 32 /* Mapped */) { + return getAnonymousTypeInstantiation(type, mapper); + } + if (type.objectFlags & 4 /* Reference */) { + return createTypeReference(type.target, instantiateTypes(type.typeArguments, mapper)); } - return type; } - return instantiateTypeNoAlias(type, mapper); - } - return type; - } - function instantiateTypeNoAlias(type, mapper) { - if (type.flags & 16384 /* TypeParameter */) { - return mapper(type); - } - if (type.flags & 32768 /* Object */) { - if (type.objectFlags & 16 /* Anonymous */) { - // If the anonymous type originates in a declaration of a function, method, class, or - // interface, in an object type literal, or in an object literal expression, we may need - // to instantiate the type because it might reference a type parameter. We skip instantiation - // if none of the type parameters that are in scope in the type's declaration are mapped by - // the given mapper, however we can only do that analysis if the type isn't itself an - // instantiation. - return type.symbol && - type.symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */) && - (type.objectFlags & 64 /* Instantiated */ || isSymbolInScopeOfMappedTypeParameter(type.symbol, mapper)) ? - instantiateCached(type, mapper, instantiateAnonymousType) : type; + if (type.flags & 65536 /* Union */ && !(type.flags & 8190 /* Primitive */)) { + return getUnionType(instantiateTypes(type.types, mapper), /*subtypeReduction*/ false, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); } - if (type.objectFlags & 32 /* Mapped */) { - return instantiateCached(type, mapper, instantiateMappedType); + if (type.flags & 131072 /* Intersection */) { + return getIntersectionType(instantiateTypes(type.types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); } - if (type.objectFlags & 4 /* Reference */) { - return createTypeReference(type.target, instantiateTypes(type.typeArguments, mapper)); + if (type.flags & 262144 /* Index */) { + return getIndexType(instantiateType(type.type, mapper)); + } + if (type.flags & 524288 /* IndexedAccess */) { + return getIndexedAccessType(instantiateType(type.objectType, mapper), instantiateType(type.indexType, mapper)); } - } - if (type.flags & 65536 /* Union */ && !(type.flags & 8190 /* Primitive */)) { - return getUnionType(instantiateTypes(type.types, mapper), /*subtypeReduction*/ false, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); - } - if (type.flags & 131072 /* Intersection */) { - return getIntersectionType(instantiateTypes(type.types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); - } - if (type.flags & 262144 /* Index */) { - return getIndexType(instantiateType(type.type, mapper)); - } - if (type.flags & 524288 /* IndexedAccess */) { - return getIndexedAccessType(instantiateType(type.objectType, mapper), instantiateType(type.indexType, mapper)); } return type; } @@ -30387,7 +30350,8 @@ var ts; if (!target.hasRestParameter && source.minArgumentCount > target.parameters.length) { return 0 /* False */; } - if (source.typeParameters) { + if (source.typeParameters && source.typeParameters !== target.typeParameters) { + target = getCanonicalSignature(target); source = instantiateSignatureInContextOf(source, target, /*contextualMapper*/ undefined, compareTypes); } var result = -1 /* True */; @@ -32094,7 +32058,6 @@ var ts; function createInferenceContext(signature, flags, compareTypes, baseInferences) { var inferences = baseInferences ? ts.map(baseInferences, cloneInferenceInfo) : ts.map(signature.typeParameters, createInferenceInfo); var context = mapper; - context.mappedTypes = signature.typeParameters; context.signature = signature; context.inferences = inferences; context.flags = flags; @@ -83412,8 +83375,7 @@ var ts; if (isTypeParameterList) { isVariadic = false; // type parameter lists are not variadic prefixDisplayParts.push(ts.punctuationPart(27 /* LessThanToken */)); - // Use `.mapper` to ensure we get the generic type arguments even if this is an instantiated version of the signature. - var typeParameters = candidateSignature.mapper ? candidateSignature.mapper.mappedTypes : candidateSignature.typeParameters; + var typeParameters = (candidateSignature.target || candidateSignature).typeParameters; signatureHelpParameters = typeParameters && typeParameters.length > 0 ? ts.map(typeParameters, createSignatureHelpParameterForTypeParameter) : ts.emptyArray; suffixDisplayParts.push(ts.punctuationPart(29 /* GreaterThanToken */)); var parameterParts = ts.mapToDisplayParts(function (writer) { @@ -89618,7 +89580,7 @@ var ts; Messages.CannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators = createMessage("Cannot extract range containing writes to references located outside of the target range in generators."); Messages.TypeWillNotBeVisibleInTheNewScope = createMessage("Type will not visible in the new scope."); Messages.FunctionWillNotBeVisibleInTheNewScope = createMessage("Function will not visible in the new scope."); - Messages.InsufficientSelection = createMessage("Select more than a single identifier."); + Messages.InsufficientSelection = createMessage("Select more than a single token."); Messages.CannotExtractExportedEntity = createMessage("Cannot extract exported declaration"); Messages.CannotCombineWritesAndReturns = createMessage("Cannot combine writes and returns"); Messages.CannotExtractReadonlyPropertyInitializerOutsideConstructor = createMessage("Cannot move initialization of read-only class property outside of the constructor"); @@ -89717,7 +89679,7 @@ var ts; return { errors: [ts.createFileDiagnostic(sourceFile, start, length, message)] }; } function checkRootNode(node) { - if (ts.isIdentifier(node)) { + if (ts.isToken(node)) { return [ts.createDiagnosticForNode(node, Messages.InsufficientSelection)]; } return undefined; diff --git a/lib/typescriptServices.d.ts b/lib/typescriptServices.d.ts index d5602ea0f78..cc7a778c17e 100644 --- a/lib/typescriptServices.d.ts +++ b/lib/typescriptServices.d.ts @@ -1472,7 +1472,6 @@ declare namespace ts { interface JSDocTypeLiteral extends JSDocType { kind: SyntaxKind.JSDocTypeLiteral; jsDocPropertyTags?: ReadonlyArray; - jsDocTypeTag?: JSDocTypeTag; /** If true, then this type literal represents an *array* of its type. */ isArrayType?: boolean; } diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index 74272714529..ae40057ff89 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -12298,9 +12298,11 @@ var ts; visitNode(cbNode, node.typeExpression); } case 285 /* JSDocTypeLiteral */: - for (var _i = 0, _a = node.jsDocPropertyTags; _i < _a.length; _i++) { - var tag = _a[_i]; - visitNode(cbNode, tag); + if (node.jsDocPropertyTags) { + for (var _i = 0, _a = node.jsDocPropertyTags; _i < _a.length; _i++) { + var tag = _a[_i]; + visitNode(cbNode, tag); + } } return; case 288 /* PartiallyEmittedExpression */: @@ -17782,19 +17784,18 @@ var ts; if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) { var child = void 0; var jsdocTypeLiteral = void 0; - var alreadyHasTypeTag = false; + var childTypeTag = void 0; var start_3 = scanner.getStartPos(); while (child = tryParse(function () { return parseChildParameterOrPropertyTag(0 /* Property */); })) { if (!jsdocTypeLiteral) { jsdocTypeLiteral = createNode(285 /* JSDocTypeLiteral */, start_3); } if (child.kind === 281 /* JSDocTypeTag */) { - if (alreadyHasTypeTag) { + if (childTypeTag) { break; } else { - jsdocTypeLiteral.jsDocTypeTag = child; - alreadyHasTypeTag = true; + childTypeTag = child; } } else { @@ -17808,7 +17809,9 @@ var ts; if (typeExpression && typeExpression.type.kind === 164 /* ArrayType */) { jsdocTypeLiteral.isArrayType = true; } - typedefTag.typeExpression = finishNode(jsdocTypeLiteral); + typedefTag.typeExpression = childTypeTag && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ? + childTypeTag.typeExpression : + finishNode(jsdocTypeLiteral); } } return finishNode(typedefTag); @@ -26928,29 +26931,46 @@ var ts; } return typeParameters; } - // Appends the outer type parameters of a node to a set of type parameters and returns the resulting set. The function - // allocates a new array if the input type parameter set is undefined, but otherwise it modifies the set in-place and - // returns the same array. - function appendOuterTypeParameters(typeParameters, node) { + // Return the outer type parameters of a node or undefined if the node has no outer type parameters. + function getOuterTypeParameters(node, includeThisTypes) { while (true) { node = node.parent; if (!node) { - return typeParameters; + return undefined; } - if (node.kind === 229 /* ClassDeclaration */ || node.kind === 199 /* ClassExpression */ || - node.kind === 228 /* FunctionDeclaration */ || node.kind === 186 /* FunctionExpression */ || - node.kind === 151 /* MethodDeclaration */ || node.kind === 187 /* ArrowFunction */) { - var declarations = node.typeParameters; - if (declarations) { - return appendTypeParameters(appendOuterTypeParameters(typeParameters, node), declarations); - } + switch (node.kind) { + case 229 /* ClassDeclaration */: + case 199 /* ClassExpression */: + case 230 /* InterfaceDeclaration */: + case 155 /* CallSignature */: + case 156 /* ConstructSignature */: + case 150 /* MethodSignature */: + case 160 /* FunctionType */: + case 161 /* ConstructorType */: + case 273 /* JSDocFunctionType */: + case 228 /* FunctionDeclaration */: + case 151 /* MethodDeclaration */: + case 186 /* FunctionExpression */: + case 187 /* ArrowFunction */: + case 231 /* TypeAliasDeclaration */: + case 282 /* JSDocTemplateTag */: + case 172 /* MappedType */: + var outerTypeParameters = getOuterTypeParameters(node, includeThisTypes); + if (node.kind === 172 /* MappedType */) { + return ts.append(outerTypeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter))); + } + var outerAndOwnTypeParameters = appendTypeParameters(outerTypeParameters, ts.getEffectiveTypeParameterDeclarations(node) || ts.emptyArray); + var thisType = includeThisTypes && + (node.kind === 229 /* ClassDeclaration */ || node.kind === 199 /* ClassExpression */ || node.kind === 230 /* InterfaceDeclaration */) && + getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node)).thisType; + return thisType ? ts.append(outerAndOwnTypeParameters, thisType) : outerAndOwnTypeParameters; } } } // The outer type parameters are those defined by enclosing generic classes, methods, or functions. function getOuterTypeParametersOfClassOrInterface(symbol) { var declaration = symbol.flags & 32 /* Class */ ? symbol.valueDeclaration : ts.getDeclarationOfKind(symbol, 230 /* InterfaceDeclaration */); - return appendOuterTypeParameters(/*typeParameters*/ undefined, declaration); + return getOuterTypeParameters(declaration); } // The local type parameters are the combined set of type parameters from all declarations of the class, // interface, or type alias. @@ -28652,12 +28672,27 @@ var ts; return instantiateSignature(signature, createTypeMapper(signature.typeParameters, typeArguments), /*eraseTypeParameters*/ true); } function getErasedSignature(signature) { - if (!signature.typeParameters) - return signature; - if (!signature.erasedSignatureCache) { - signature.erasedSignatureCache = instantiateSignature(signature, createTypeEraser(signature.typeParameters), /*eraseTypeParameters*/ true); - } - return signature.erasedSignatureCache; + return signature.typeParameters ? + signature.erasedSignatureCache || (signature.erasedSignatureCache = createErasedSignature(signature)) : + signature; + } + function createErasedSignature(signature) { + // Create an instantiation of the signature where all type arguments are the any type. + return instantiateSignature(signature, createTypeEraser(signature.typeParameters), /*eraseTypeParameters*/ true); + } + function getCanonicalSignature(signature) { + return signature.typeParameters ? + signature.canonicalSignatureCache || (signature.canonicalSignatureCache = createCanonicalSignature(signature)) : + signature; + } + function createCanonicalSignature(signature) { + // Create an instantiation of the signature where each unconstrained type parameter is replaced with + // its original. When a generic class or interface is instantiated, each generic method in the class or + // interface is instantiated with a fresh set of cloned type parameters (which we need to handle scenarios + // where different generations of the same type parameter are in scope). This leads to a lot of new type + // identities, and potentially a lot of work comparing those identities, so here we create an instantiation + // that uses the original type identities for all unconstrained type parameters. + return getSignatureInstantiation(signature, ts.map(signature.typeParameters, function (tp) { return tp.target && !getConstraintOfTypeParameter(tp.target) ? tp.target : tp; })); } function getOrCreateTypeFromSignature(signature) { // There are two ways to declare a construct signature, one is by declaring a class constructor @@ -28818,7 +28853,7 @@ var ts; var id = getTypeListId(typeArguments); var instantiation = links.instantiations.get(id); if (!instantiation) { - links.instantiations.set(id, instantiation = instantiateTypeNoAlias(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters))))); + links.instantiations.set(id, instantiation = instantiateType(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters))))); } return instantiation; } @@ -29938,10 +29973,6 @@ var ts; function instantiateSignatures(signatures, mapper) { return instantiateList(signatures, mapper, instantiateSignature); } - function instantiateCached(type, mapper, instantiator) { - var instantiations = mapper.instantiations || (mapper.instantiations = []); - return instantiations[type.id] || (instantiations[type.id] = instantiator(type, mapper)); - } function makeUnaryTypeMapper(source, target) { return function (t) { return t === source ? target : t; }; } @@ -29960,11 +29991,9 @@ var ts; } function createTypeMapper(sources, targets) { ts.Debug.assert(targets === undefined || sources.length === targets.length); - var mapper = sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) : + return sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) : sources.length === 2 ? makeBinaryTypeMapper(sources[0], targets ? targets[0] : anyType, sources[1], targets ? targets[1] : anyType) : makeArrayTypeMapper(sources, targets); - mapper.mappedTypes = sources; - return mapper; } function createTypeEraser(sources) { return createTypeMapper(sources, /*targets*/ undefined); @@ -29974,9 +30003,7 @@ var ts; * This is used during inference when instantiating type parameter defaults. */ function createBackreferenceMapper(typeParameters, index) { - var mapper = function (t) { return ts.indexOf(typeParameters, t) >= index ? emptyObjectType : t; }; - mapper.mappedTypes = typeParameters; - return mapper; + return function (t) { return ts.indexOf(typeParameters, t) >= index ? emptyObjectType : t; }; } function isInferenceContext(mapper) { return !!mapper.signature; @@ -29990,14 +30017,10 @@ var ts; return type; } function combineTypeMappers(mapper1, mapper2) { - var mapper = function (t) { return instantiateType(mapper1(t), mapper2); }; - mapper.mappedTypes = ts.concatenate(mapper1.mappedTypes, mapper2.mappedTypes); - return mapper; + return function (t) { return instantiateType(mapper1(t), mapper2); }; } function createReplacementMapper(source, target, baseMapper) { - var mapper = function (t) { return t === source ? target : baseMapper(t); }; - mapper.mappedTypes = baseMapper.mappedTypes; - return mapper; + return function (t) { return t === source ? target : baseMapper(t); }; } function cloneTypeParameter(typeParameter) { var result = createType(16384 /* TypeParameter */); @@ -30066,13 +30089,52 @@ var ts; } return result; } - function instantiateAnonymousType(type, mapper) { - var result = createObjectType(16 /* Anonymous */ | 64 /* Instantiated */, type.symbol); - result.target = type.objectFlags & 64 /* Instantiated */ ? type.target : type; - result.mapper = type.objectFlags & 64 /* Instantiated */ ? combineTypeMappers(type.mapper, mapper) : mapper; - result.aliasSymbol = type.aliasSymbol; - result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper); - return result; + function getAnonymousTypeInstantiation(type, mapper) { + var target = type.objectFlags & 64 /* Instantiated */ ? type.target : type; + var symbol = target.symbol; + var links = getSymbolLinks(symbol); + var typeParameters = links.typeParameters; + if (!typeParameters) { + // The first time an anonymous type is instantiated we compute and store a list of the type + // parameters that are in scope (and therefore potentially referenced). For type literals that + // aren't the right hand side of a generic type alias declaration we optimize by reducing the + // set of type parameters to those that are actually referenced somewhere in the literal. + var declaration_1 = symbol.declarations[0]; + var outerTypeParameters = getOuterTypeParameters(declaration_1, /*includeThisTypes*/ true) || ts.emptyArray; + typeParameters = symbol.flags & 2048 /* TypeLiteral */ && !target.aliasTypeArguments ? + ts.filter(outerTypeParameters, function (tp) { return isTypeParameterReferencedWithin(tp, declaration_1); }) : + outerTypeParameters; + links.typeParameters = typeParameters; + if (typeParameters.length) { + links.instantiations = ts.createMap(); + links.instantiations.set(getTypeListId(typeParameters), target); + } + } + if (typeParameters.length) { + // We are instantiating an anonymous type that has one or more type parameters in scope. Apply the + // mapper to the type parameters to produce the effective list of type arguments, and compute the + // instantiation cache key from the type IDs of the type arguments. + var combinedMapper = type.objectFlags & 64 /* Instantiated */ ? combineTypeMappers(type.mapper, mapper) : mapper; + var typeArguments = ts.map(typeParameters, combinedMapper); + var id = getTypeListId(typeArguments); + var result = links.instantiations.get(id); + if (!result) { + var newMapper = createTypeMapper(typeParameters, typeArguments); + result = target.objectFlags & 32 /* Mapped */ ? instantiateMappedType(target, newMapper) : instantiateAnonymousType(target, newMapper); + links.instantiations.set(id, result); + } + return result; + } + return type; + } + function isTypeParameterReferencedWithin(tp, node) { + return tp.isThisType ? ts.forEachChild(node, checkThis) : ts.forEachChild(node, checkIdentifier); + function checkThis(node) { + return node.kind === 169 /* ThisType */ || ts.forEachChild(node, checkThis); + } + function checkIdentifier(node) { + return node.kind === 71 /* Identifier */ && ts.isPartOfTypeNode(node) && getTypeFromTypeNode(node) === tp || ts.forEachChild(node, checkIdentifier); + } } function instantiateMappedType(type, mapper) { // Check if we have a homomorphic mapped type, i.e. a type of the form { [P in keyof T]: X } for some @@ -30088,160 +30150,61 @@ var ts; if (typeVariable_1 !== mappedTypeVariable) { return mapType(mappedTypeVariable, function (t) { if (isMappableType(t)) { - return instantiateMappedObjectType(type, createReplacementMapper(typeVariable_1, t, mapper)); + return instantiateAnonymousType(type, createReplacementMapper(typeVariable_1, t, mapper)); } return t; }); } } } - return instantiateMappedObjectType(type, mapper); + return instantiateAnonymousType(type, mapper); } function isMappableType(type) { return type.flags & (16384 /* TypeParameter */ | 32768 /* Object */ | 131072 /* Intersection */ | 524288 /* IndexedAccess */); } - function instantiateMappedObjectType(type, mapper) { - var result = createObjectType(32 /* Mapped */ | 64 /* Instantiated */, type.symbol); - result.declaration = type.declaration; - result.mapper = type.mapper ? combineTypeMappers(type.mapper, mapper) : mapper; + function instantiateAnonymousType(type, mapper) { + var result = createObjectType(type.objectFlags | 64 /* Instantiated */, type.symbol); + if (type.objectFlags & 32 /* Mapped */) { + result.declaration = type.declaration; + } + result.target = type; + result.mapper = mapper; result.aliasSymbol = type.aliasSymbol; result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper); return result; } - function isSymbolInScopeOfMappedTypeParameter(symbol, mapper) { - if (!(symbol.declarations && symbol.declarations.length)) { - return false; - } - var mappedTypes = mapper.mappedTypes; - // Starting with the parent of the symbol's declaration, check if the mapper maps any of - // the type parameters introduced by enclosing declarations. We just pick the first - // declaration since multiple declarations will all have the same parent anyway. - return !!ts.findAncestor(symbol.declarations[0], function (node) { - if (node.kind === 233 /* ModuleDeclaration */ || node.kind === 265 /* SourceFile */) { - return "quit"; - } - switch (node.kind) { - case 160 /* FunctionType */: - case 161 /* ConstructorType */: - case 228 /* FunctionDeclaration */: - case 151 /* MethodDeclaration */: - case 150 /* MethodSignature */: - case 152 /* Constructor */: - case 155 /* CallSignature */: - case 156 /* ConstructSignature */: - case 157 /* IndexSignature */: - case 153 /* GetAccessor */: - case 154 /* SetAccessor */: - case 186 /* FunctionExpression */: - case 187 /* ArrowFunction */: - case 229 /* ClassDeclaration */: - case 199 /* ClassExpression */: - case 230 /* InterfaceDeclaration */: - case 231 /* TypeAliasDeclaration */: - var typeParameters = ts.getEffectiveTypeParameterDeclarations(node); - if (typeParameters) { - for (var _i = 0, typeParameters_1 = typeParameters; _i < typeParameters_1.length; _i++) { - var d = typeParameters_1[_i]; - if (ts.contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode(d)))) { - return true; - } - } - } - if (ts.isClassLike(node) || node.kind === 230 /* InterfaceDeclaration */) { - var thisType = getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node)).thisType; - if (thisType && ts.contains(mappedTypes, thisType)) { - return true; - } - } - break; - case 172 /* MappedType */: - if (ts.contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter)))) { - return true; - } - break; - case 273 /* JSDocFunctionType */: - var func = node; - for (var _a = 0, _b = func.parameters; _a < _b.length; _a++) { - var p = _b[_a]; - if (ts.contains(mappedTypes, getTypeOfNode(p))) { - return true; - } - } - break; - } - }); - } - function isTopLevelTypeAlias(symbol) { - if (symbol.declarations && symbol.declarations.length) { - var parentKind = symbol.declarations[0].parent.kind; - return parentKind === 265 /* SourceFile */ || parentKind === 234 /* ModuleBlock */; - } - return false; - } function instantiateType(type, mapper) { if (type && mapper !== identityMapper) { - // If we are instantiating a type that has a top-level type alias, obtain the instantiation through - // the type alias instead in order to share instantiations for the same type arguments. This can - // dramatically reduce the number of structurally identical types we generate. Note that we can only - // perform this optimization for top-level type aliases. Consider: - // - // function f1(x: T) { - // type Foo = { x: X, t: T }; - // let obj: Foo = { x: x }; - // return obj; - // } - // function f2(x: U) { return f1(x); } - // let z = f2(42); - // - // Above, the declaration of f2 has an inferred return type that is an instantiation of f1's Foo - // equivalent to { x: U, t: U }. When instantiating this return type, we can't go back to Foo's - // cache because all cached instantiations are of the form { x: ???, t: T }, i.e. they have not been - // instantiated for T. Instead, we need to further instantiate the { x: U, t: U } form. - if (type.aliasSymbol && isTopLevelTypeAlias(type.aliasSymbol)) { - if (type.aliasTypeArguments) { - return getTypeAliasInstantiation(type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); + if (type.flags & 16384 /* TypeParameter */) { + return mapper(type); + } + if (type.flags & 32768 /* Object */) { + if (type.objectFlags & 16 /* Anonymous */) { + // If the anonymous type originates in a declaration of a function, method, class, or + // interface, in an object type literal, or in an object literal expression, we may need + // to instantiate the type because it might reference a type parameter. + return type.symbol && type.symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */) && type.symbol.declarations ? + getAnonymousTypeInstantiation(type, mapper) : type; + } + if (type.objectFlags & 32 /* Mapped */) { + return getAnonymousTypeInstantiation(type, mapper); + } + if (type.objectFlags & 4 /* Reference */) { + return createTypeReference(type.target, instantiateTypes(type.typeArguments, mapper)); } - return type; } - return instantiateTypeNoAlias(type, mapper); - } - return type; - } - function instantiateTypeNoAlias(type, mapper) { - if (type.flags & 16384 /* TypeParameter */) { - return mapper(type); - } - if (type.flags & 32768 /* Object */) { - if (type.objectFlags & 16 /* Anonymous */) { - // If the anonymous type originates in a declaration of a function, method, class, or - // interface, in an object type literal, or in an object literal expression, we may need - // to instantiate the type because it might reference a type parameter. We skip instantiation - // if none of the type parameters that are in scope in the type's declaration are mapped by - // the given mapper, however we can only do that analysis if the type isn't itself an - // instantiation. - return type.symbol && - type.symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */) && - (type.objectFlags & 64 /* Instantiated */ || isSymbolInScopeOfMappedTypeParameter(type.symbol, mapper)) ? - instantiateCached(type, mapper, instantiateAnonymousType) : type; + if (type.flags & 65536 /* Union */ && !(type.flags & 8190 /* Primitive */)) { + return getUnionType(instantiateTypes(type.types, mapper), /*subtypeReduction*/ false, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); } - if (type.objectFlags & 32 /* Mapped */) { - return instantiateCached(type, mapper, instantiateMappedType); + if (type.flags & 131072 /* Intersection */) { + return getIntersectionType(instantiateTypes(type.types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); } - if (type.objectFlags & 4 /* Reference */) { - return createTypeReference(type.target, instantiateTypes(type.typeArguments, mapper)); + if (type.flags & 262144 /* Index */) { + return getIndexType(instantiateType(type.type, mapper)); + } + if (type.flags & 524288 /* IndexedAccess */) { + return getIndexedAccessType(instantiateType(type.objectType, mapper), instantiateType(type.indexType, mapper)); } - } - if (type.flags & 65536 /* Union */ && !(type.flags & 8190 /* Primitive */)) { - return getUnionType(instantiateTypes(type.types, mapper), /*subtypeReduction*/ false, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); - } - if (type.flags & 131072 /* Intersection */) { - return getIntersectionType(instantiateTypes(type.types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); - } - if (type.flags & 262144 /* Index */) { - return getIndexType(instantiateType(type.type, mapper)); - } - if (type.flags & 524288 /* IndexedAccess */) { - return getIndexedAccessType(instantiateType(type.objectType, mapper), instantiateType(type.indexType, mapper)); } return type; } @@ -30387,7 +30350,8 @@ var ts; if (!target.hasRestParameter && source.minArgumentCount > target.parameters.length) { return 0 /* False */; } - if (source.typeParameters) { + if (source.typeParameters && source.typeParameters !== target.typeParameters) { + target = getCanonicalSignature(target); source = instantiateSignatureInContextOf(source, target, /*contextualMapper*/ undefined, compareTypes); } var result = -1 /* True */; @@ -32094,7 +32058,6 @@ var ts; function createInferenceContext(signature, flags, compareTypes, baseInferences) { var inferences = baseInferences ? ts.map(baseInferences, cloneInferenceInfo) : ts.map(signature.typeParameters, createInferenceInfo); var context = mapper; - context.mappedTypes = signature.typeParameters; context.signature = signature; context.inferences = inferences; context.flags = flags; @@ -83412,8 +83375,7 @@ var ts; if (isTypeParameterList) { isVariadic = false; // type parameter lists are not variadic prefixDisplayParts.push(ts.punctuationPart(27 /* LessThanToken */)); - // Use `.mapper` to ensure we get the generic type arguments even if this is an instantiated version of the signature. - var typeParameters = candidateSignature.mapper ? candidateSignature.mapper.mappedTypes : candidateSignature.typeParameters; + var typeParameters = (candidateSignature.target || candidateSignature).typeParameters; signatureHelpParameters = typeParameters && typeParameters.length > 0 ? ts.map(typeParameters, createSignatureHelpParameterForTypeParameter) : ts.emptyArray; suffixDisplayParts.push(ts.punctuationPart(29 /* GreaterThanToken */)); var parameterParts = ts.mapToDisplayParts(function (writer) { @@ -89618,7 +89580,7 @@ var ts; Messages.CannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators = createMessage("Cannot extract range containing writes to references located outside of the target range in generators."); Messages.TypeWillNotBeVisibleInTheNewScope = createMessage("Type will not visible in the new scope."); Messages.FunctionWillNotBeVisibleInTheNewScope = createMessage("Function will not visible in the new scope."); - Messages.InsufficientSelection = createMessage("Select more than a single identifier."); + Messages.InsufficientSelection = createMessage("Select more than a single token."); Messages.CannotExtractExportedEntity = createMessage("Cannot extract exported declaration"); Messages.CannotCombineWritesAndReturns = createMessage("Cannot combine writes and returns"); Messages.CannotExtractReadonlyPropertyInitializerOutsideConstructor = createMessage("Cannot move initialization of read-only class property outside of the constructor"); @@ -89717,7 +89679,7 @@ var ts; return { errors: [ts.createFileDiagnostic(sourceFile, start, length, message)] }; } function checkRootNode(node) { - if (ts.isIdentifier(node)) { + if (ts.isToken(node)) { return [ts.createDiagnosticForNode(node, Messages.InsufficientSelection)]; } return undefined; diff --git a/lib/typingsInstaller.js b/lib/typingsInstaller.js index 2c2ccfdcf1f..9aa63731908 100644 --- a/lib/typingsInstaller.js +++ b/lib/typingsInstaller.js @@ -9927,9 +9927,11 @@ var ts; visitNode(cbNode, node.typeExpression); } case 285: - for (var _i = 0, _a = node.jsDocPropertyTags; _i < _a.length; _i++) { - var tag = _a[_i]; - visitNode(cbNode, tag); + if (node.jsDocPropertyTags) { + for (var _i = 0, _a = node.jsDocPropertyTags; _i < _a.length; _i++) { + var tag = _a[_i]; + visitNode(cbNode, tag); + } } return; case 288: @@ -14300,19 +14302,18 @@ var ts; if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) { var child = void 0; var jsdocTypeLiteral = void 0; - var alreadyHasTypeTag = false; + var childTypeTag = void 0; var start_3 = scanner.getStartPos(); while (child = tryParse(function () { return parseChildParameterOrPropertyTag(0); })) { if (!jsdocTypeLiteral) { jsdocTypeLiteral = createNode(285, start_3); } if (child.kind === 281) { - if (alreadyHasTypeTag) { + if (childTypeTag) { break; } else { - jsdocTypeLiteral.jsDocTypeTag = child; - alreadyHasTypeTag = true; + childTypeTag = child; } } else { @@ -14326,7 +14327,9 @@ var ts; if (typeExpression && typeExpression.type.kind === 164) { jsdocTypeLiteral.isArrayType = true; } - typedefTag.typeExpression = finishNode(jsdocTypeLiteral); + typedefTag.typeExpression = childTypeTag && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ? + childTypeTag.typeExpression : + finishNode(jsdocTypeLiteral); } } return finishNode(typedefTag);