Skip to content

Commit 19af881

Browse files
author
Andy
authored
ExpressionWithTypeArguments parent may be a JSDocAugmentsTag (microsoft#27229)
1 parent 26eb6ab commit 19af881

File tree

6 files changed

+23
-31
lines changed

6 files changed

+23
-31
lines changed

src/compiler/checker.ts

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27940,24 +27940,20 @@ namespace ts {
2794027940
return errorType;
2794127941
}
2794227942

27943+
const classDecl = tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node);
27944+
const classType = classDecl && getDeclaredTypeOfClassOrInterface(getSymbolOfNode(classDecl.class));
2794327945
if (isPartOfTypeNode(node)) {
2794427946
const typeFromTypeNode = getTypeFromTypeNode(<TypeNode>node);
27945-
27946-
if (isExpressionWithTypeArgumentsInClassImplementsClause(node)) {
27947-
return getTypeWithThisArgument(typeFromTypeNode, getTypeOfClassContainingHeritageClause(node).thisType);
27948-
}
27949-
27950-
return typeFromTypeNode;
27947+
return classType ? getTypeWithThisArgument(typeFromTypeNode, classType.thisType) : typeFromTypeNode;
2795127948
}
2795227949

2795327950
if (isExpressionNode(node)) {
2795427951
return getRegularTypeOfExpression(<Expression>node);
2795527952
}
2795627953

27957-
if (isExpressionWithTypeArgumentsInClassExtendsClause(node)) {
27954+
if (classType && !classDecl!.isImplements) {
2795827955
// A SyntaxKind.ExpressionWithTypeArguments is considered a type node, except when it occurs in the
2795927956
// extends clause of a class. We handle that case here.
27960-
const classType = getTypeOfClassContainingHeritageClause(node);
2796127957
const baseType = firstOrUndefined(getBaseTypes(classType));
2796227958
return baseType ? getTypeWithThisArgument(baseType, classType.thisType) : errorType;
2796327959
}
@@ -27999,10 +27995,6 @@ namespace ts {
2799927995
return errorType;
2800027996
}
2800127997

28002-
function getTypeOfClassContainingHeritageClause(node: ExpressionWithTypeArguments): InterfaceType {
28003-
return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node.parent.parent));
28004-
}
28005-
2800627998
// Gets the type of object literal or array literal of destructuring assignment.
2800727999
// { a } from
2800828000
// for ( { a } of elems) {

src/compiler/transformers/declarations/diagnostics.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ namespace ts {
434434
// Heritage clause is written by user so it can always be named
435435
if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) {
436436
// Class or Interface implemented/extended is inaccessible
437-
diagnosticMessage = (node as ExpressionWithTypeArguments).parent.token === SyntaxKind.ImplementsKeyword ?
437+
diagnosticMessage = isHeritageClause(node.parent) && node.parent.token === SyntaxKind.ImplementsKeyword ?
438438
Diagnostics.Implements_clause_of_exported_class_0_has_or_is_using_private_name_1 :
439439
Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1;
440440
}
@@ -446,7 +446,7 @@ namespace ts {
446446
return {
447447
diagnosticMessage,
448448
errorNode: node,
449-
typeName: getNameOfDeclaration((node as ExpressionWithTypeArguments).parent.parent)
449+
typeName: getNameOfDeclaration(node.parent.parent as Declaration)
450450
};
451451
}
452452

src/compiler/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1708,7 +1708,7 @@ namespace ts {
17081708

17091709
export interface ExpressionWithTypeArguments extends NodeWithTypeArguments {
17101710
kind: SyntaxKind.ExpressionWithTypeArguments;
1711-
parent: HeritageClause;
1711+
parent: HeritageClause | JSDocAugmentsTag;
17121712
expression: LeftHandSideExpression;
17131713
}
17141714

src/compiler/utilities.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3734,11 +3734,20 @@ namespace ts {
37343734

37353735
/** Get `C` given `N` if `N` is in the position `class C extends N` where `N` is an ExpressionWithTypeArguments. */
37363736
export function tryGetClassExtendingExpressionWithTypeArguments(node: Node): ClassLikeDeclaration | undefined {
3737-
if (isExpressionWithTypeArguments(node) &&
3738-
node.parent.token === SyntaxKind.ExtendsKeyword &&
3739-
isClassLike(node.parent.parent)) {
3740-
return node.parent.parent;
3741-
}
3737+
const cls = tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node);
3738+
return cls && !cls.isImplements ? cls.class : undefined;
3739+
}
3740+
3741+
export interface ClassImplementingOrExtendingExpressionWithTypeArguments {
3742+
readonly class: ClassLikeDeclaration;
3743+
readonly isImplements: boolean;
3744+
}
3745+
export function tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node: Node): ClassImplementingOrExtendingExpressionWithTypeArguments | undefined {
3746+
return isExpressionWithTypeArguments(node)
3747+
&& isHeritageClause(node.parent)
3748+
&& isClassLike(node.parent.parent)
3749+
? { class: node.parent.parent, isImplements: node.parent.token === SyntaxKind.ImplementsKeyword }
3750+
: undefined;
37423751
}
37433752

37443753
export function isAssignmentExpression(node: Node, excludeCompoundAssignment: true): node is AssignmentExpression<EqualsToken>;
@@ -3765,15 +3774,6 @@ namespace ts {
37653774
return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined;
37663775
}
37673776

3768-
export function isExpressionWithTypeArgumentsInClassImplementsClause(node: Node): node is ExpressionWithTypeArguments {
3769-
return node.kind === SyntaxKind.ExpressionWithTypeArguments
3770-
&& isEntityNameExpression((node as ExpressionWithTypeArguments).expression)
3771-
&& node.parent
3772-
&& (<HeritageClause>node.parent).token === SyntaxKind.ImplementsKeyword
3773-
&& node.parent.parent
3774-
&& isClassLike(node.parent.parent);
3775-
}
3776-
37773777
export function isEntityNameExpression(node: Node): node is EntityNameExpression {
37783778
return node.kind === SyntaxKind.Identifier || isPropertyAccessEntityNameExpression(node);
37793779
}

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,7 @@ declare namespace ts {
10821082
}
10831083
interface ExpressionWithTypeArguments extends NodeWithTypeArguments {
10841084
kind: SyntaxKind.ExpressionWithTypeArguments;
1085-
parent: HeritageClause;
1085+
parent: HeritageClause | JSDocAugmentsTag;
10861086
expression: LeftHandSideExpression;
10871087
}
10881088
interface NewExpression extends PrimaryExpression, Declaration {

tests/baselines/reference/api/typescript.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,7 @@ declare namespace ts {
10821082
}
10831083
interface ExpressionWithTypeArguments extends NodeWithTypeArguments {
10841084
kind: SyntaxKind.ExpressionWithTypeArguments;
1085-
parent: HeritageClause;
1085+
parent: HeritageClause | JSDocAugmentsTag;
10861086
expression: LeftHandSideExpression;
10871087
}
10881088
interface NewExpression extends PrimaryExpression, Declaration {

0 commit comments

Comments
 (0)