Merge pull request #16463 from Microsoft/jsdoc-@template-in-scope-as-type-parameter

Jsdoc @template in scope as type parameter
This commit is contained in:
Nathan Shively-Sanders
2017-06-12 16:07:49 -07:00
committed by GitHub
5 changed files with 126 additions and 21 deletions

View File

@@ -6170,24 +6170,16 @@ namespace ts {
return undefined;
}
function getTypeParametersFromJSDocTemplate(declaration: SignatureDeclaration): TypeParameter[] {
if (declaration.flags & NodeFlags.JavaScriptFile) {
const templateTag = getJSDocTemplateTag(declaration);
if (templateTag) {
return getTypeParametersFromDeclaration(templateTag.typeParameters);
}
}
return undefined;
}
// Return list of type parameters with duplicates removed (duplicate identifier errors are generated in the actual
// type checking functions).
function getTypeParametersFromDeclaration(typeParameterDeclarations: TypeParameterDeclaration[]): TypeParameter[] {
const result: TypeParameter[] = [];
forEach(typeParameterDeclarations, node => {
function getTypeParametersFromDeclaration(declaration: DeclarationWithTypeParameters): TypeParameter[] {
let result: TypeParameter[];
forEach(getEffectiveTypeParameterDeclarations(declaration), node => {
const tp = getDeclaredTypeOfTypeParameter(node.symbol);
if (!contains(result, tp)) {
if (!result) {
result = [];
}
result.push(tp);
}
});
@@ -6383,9 +6375,7 @@ namespace ts {
const classType = declaration.kind === SyntaxKind.Constructor ?
getDeclaredTypeOfClassOrInterface(getMergedSymbol((<ClassDeclaration>declaration.parent).symbol))
: undefined;
const typeParameters = classType ? classType.localTypeParameters :
declaration.typeParameters ? getTypeParametersFromDeclaration(declaration.typeParameters) :
getTypeParametersFromJSDocTemplate(declaration);
const typeParameters = classType ? classType.localTypeParameters : getTypeParametersFromDeclaration(declaration);
const returnType = getSignatureReturnTypeFromDeclaration(declaration, isJSConstructSignature, classType);
const typePredicate = declaration.type && declaration.type.kind === SyntaxKind.TypePredicate ?
createTypePredicateFromTypePredicateNode(declaration.type as TypePredicateNode) :
@@ -8166,9 +8156,9 @@ namespace ts {
case SyntaxKind.ClassExpression:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.TypeAliasDeclaration:
const declaration = node as DeclarationWithTypeParameters;
if (declaration.typeParameters) {
for (const d of declaration.typeParameters) {
const typeParameters = getEffectiveTypeParameterDeclarations(node as DeclarationWithTypeParameters);
if (typeParameters) {
for (const d of typeParameters) {
if (contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode(d)))) {
return true;
}

View File

@@ -1448,7 +1448,7 @@ namespace ts {
return node && firstOrUndefined(getJSDocTags(node, kind));
}
export function getJSDocs(node: Node): (JSDoc | JSDocTag)[] {
export function getJSDocs(node: Node): (JSDoc | JSDocTag)[] {
if (isJSDocTypedefTag(node)) {
return [node.parent];
}
@@ -2743,6 +2743,20 @@ namespace ts {
}
}
/**
* Gets the effective type parameters. If the node was parsed in a
* JavaScript file, gets the type parameters from the `@template` tag from JSDoc.
*/
export function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters): TypeParameterDeclaration[] {
if (node.typeParameters) {
return node.typeParameters;
}
if (node.flags & NodeFlags.JavaScriptFile) {
const templateTag = getJSDocTemplateTag(node);
return templateTag && templateTag.typeParameters;
}
}
/**
* Gets the effective type annotation of the value parameter of a set accessor. If the node
* was parsed in a JavaScript file, gets the type annotation from JSDoc.