ExpressionWithTypeArguments parent may be a JSDocAugmentsTag (#27229)

This commit is contained in:
Andy 2018-09-27 18:26:57 -07:00 committed by GitHub
parent 26eb6ab6f4
commit 19af881f94
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 23 additions and 31 deletions

View file

@ -27940,24 +27940,20 @@ namespace ts {
return errorType;
}
const classDecl = tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node);
const classType = classDecl && getDeclaredTypeOfClassOrInterface(getSymbolOfNode(classDecl.class));
if (isPartOfTypeNode(node)) {
const typeFromTypeNode = getTypeFromTypeNode(<TypeNode>node);
if (isExpressionWithTypeArgumentsInClassImplementsClause(node)) {
return getTypeWithThisArgument(typeFromTypeNode, getTypeOfClassContainingHeritageClause(node).thisType);
}
return typeFromTypeNode;
return classType ? getTypeWithThisArgument(typeFromTypeNode, classType.thisType) : typeFromTypeNode;
}
if (isExpressionNode(node)) {
return getRegularTypeOfExpression(<Expression>node);
}
if (isExpressionWithTypeArgumentsInClassExtendsClause(node)) {
if (classType && !classDecl!.isImplements) {
// A SyntaxKind.ExpressionWithTypeArguments is considered a type node, except when it occurs in the
// extends clause of a class. We handle that case here.
const classType = getTypeOfClassContainingHeritageClause(node);
const baseType = firstOrUndefined(getBaseTypes(classType));
return baseType ? getTypeWithThisArgument(baseType, classType.thisType) : errorType;
}
@ -27999,10 +27995,6 @@ namespace ts {
return errorType;
}
function getTypeOfClassContainingHeritageClause(node: ExpressionWithTypeArguments): InterfaceType {
return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node.parent.parent));
}
// Gets the type of object literal or array literal of destructuring assignment.
// { a } from
// for ( { a } of elems) {

View file

@ -434,7 +434,7 @@ namespace ts {
// Heritage clause is written by user so it can always be named
if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) {
// Class or Interface implemented/extended is inaccessible
diagnosticMessage = (node as ExpressionWithTypeArguments).parent.token === SyntaxKind.ImplementsKeyword ?
diagnosticMessage = isHeritageClause(node.parent) && node.parent.token === SyntaxKind.ImplementsKeyword ?
Diagnostics.Implements_clause_of_exported_class_0_has_or_is_using_private_name_1 :
Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1;
}
@ -446,7 +446,7 @@ namespace ts {
return {
diagnosticMessage,
errorNode: node,
typeName: getNameOfDeclaration((node as ExpressionWithTypeArguments).parent.parent)
typeName: getNameOfDeclaration(node.parent.parent as Declaration)
};
}

View file

@ -1708,7 +1708,7 @@ namespace ts {
export interface ExpressionWithTypeArguments extends NodeWithTypeArguments {
kind: SyntaxKind.ExpressionWithTypeArguments;
parent: HeritageClause;
parent: HeritageClause | JSDocAugmentsTag;
expression: LeftHandSideExpression;
}

View file

@ -3734,11 +3734,20 @@ namespace ts {
/** Get `C` given `N` if `N` is in the position `class C extends N` where `N` is an ExpressionWithTypeArguments. */
export function tryGetClassExtendingExpressionWithTypeArguments(node: Node): ClassLikeDeclaration | undefined {
if (isExpressionWithTypeArguments(node) &&
node.parent.token === SyntaxKind.ExtendsKeyword &&
isClassLike(node.parent.parent)) {
return node.parent.parent;
}
const cls = tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node);
return cls && !cls.isImplements ? cls.class : undefined;
}
export interface ClassImplementingOrExtendingExpressionWithTypeArguments {
readonly class: ClassLikeDeclaration;
readonly isImplements: boolean;
}
export function tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node: Node): ClassImplementingOrExtendingExpressionWithTypeArguments | undefined {
return isExpressionWithTypeArguments(node)
&& isHeritageClause(node.parent)
&& isClassLike(node.parent.parent)
? { class: node.parent.parent, isImplements: node.parent.token === SyntaxKind.ImplementsKeyword }
: undefined;
}
export function isAssignmentExpression(node: Node, excludeCompoundAssignment: true): node is AssignmentExpression<EqualsToken>;
@ -3765,15 +3774,6 @@ namespace ts {
return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined;
}
export function isExpressionWithTypeArgumentsInClassImplementsClause(node: Node): node is ExpressionWithTypeArguments {
return node.kind === SyntaxKind.ExpressionWithTypeArguments
&& isEntityNameExpression((node as ExpressionWithTypeArguments).expression)
&& node.parent
&& (<HeritageClause>node.parent).token === SyntaxKind.ImplementsKeyword
&& node.parent.parent
&& isClassLike(node.parent.parent);
}
export function isEntityNameExpression(node: Node): node is EntityNameExpression {
return node.kind === SyntaxKind.Identifier || isPropertyAccessEntityNameExpression(node);
}

View file

@ -1082,7 +1082,7 @@ declare namespace ts {
}
interface ExpressionWithTypeArguments extends NodeWithTypeArguments {
kind: SyntaxKind.ExpressionWithTypeArguments;
parent: HeritageClause;
parent: HeritageClause | JSDocAugmentsTag;
expression: LeftHandSideExpression;
}
interface NewExpression extends PrimaryExpression, Declaration {

View file

@ -1082,7 +1082,7 @@ declare namespace ts {
}
interface ExpressionWithTypeArguments extends NodeWithTypeArguments {
kind: SyntaxKind.ExpressionWithTypeArguments;
parent: HeritageClause;
parent: HeritageClause | JSDocAugmentsTag;
expression: LeftHandSideExpression;
}
interface NewExpression extends PrimaryExpression, Declaration {