@@ -1102,57 +1102,37 @@ namespace ts.FindAllReferences.Core {
11021102 }
11031103
11041104 // If we got a type reference, try and see if the reference applies to any expressions that can implement an interface
1105- const containingTypeReference = getContainingTypeReference ( refNode ) ;
1106- if ( containingTypeReference && state . markSeenContainingTypeReference ( containingTypeReference ) ) {
1107- const parent = containingTypeReference . parent ;
1108- if ( hasType ( parent ) && parent . type === containingTypeReference && hasInitializer ( parent ) && isImplementationExpression ( parent . initializer ) ) {
1109- addReference ( parent . initializer ) ;
1105+ // Find the first node whose parent isn't a type node -- i.e., the highest type node.
1106+ const typeNode = findAncestor ( refNode , a => ! isQualifiedName ( a . parent ) && ! isTypeNode ( a . parent ) && ! isTypeElement ( a . parent ) ) ;
1107+ const typeHavingNode = typeNode . parent ;
1108+ if ( hasType ( typeHavingNode ) && typeHavingNode . type === typeNode && state . markSeenContainingTypeReference ( typeHavingNode ) ) {
1109+ if ( hasInitializer ( typeHavingNode ) ) {
1110+ addIfImplementation ( typeHavingNode . initializer ) ;
11101111 }
1111- else if ( isFunctionLike ( parent ) && parent . type === containingTypeReference && ( parent as FunctionLikeDeclaration ) . body ) {
1112- const body = ( parent as FunctionLikeDeclaration ) . body ;
1112+ else if ( isFunctionLike ( typeHavingNode ) && ( typeHavingNode as FunctionLikeDeclaration ) . body ) {
1113+ const body = ( typeHavingNode as FunctionLikeDeclaration ) . body ;
11131114 if ( body . kind === SyntaxKind . Block ) {
11141115 forEachReturnStatement ( < Block > body , returnStatement => {
1115- if ( returnStatement . expression && isImplementationExpression ( returnStatement . expression ) ) {
1116- addReference ( returnStatement . expression ) ;
1117- }
1116+ if ( returnStatement . expression ) addIfImplementation ( returnStatement . expression ) ;
11181117 } ) ;
11191118 }
1120- else if ( isImplementationExpression ( body ) ) {
1121- addReference ( body ) ;
1119+ else {
1120+ addIfImplementation ( body ) ;
11221121 }
11231122 }
1124- else if ( isAssertionExpression ( parent ) && isImplementationExpression ( parent . expression ) ) {
1125- addReference ( parent . expression ) ;
1123+ else if ( isAssertionExpression ( typeHavingNode ) ) {
1124+ addIfImplementation ( typeHavingNode . expression ) ;
11261125 }
11271126 }
1128- }
1129-
1130- function getContainingTypeReference ( node : Node ) : Node {
1131- let topLevelTypeReference : Node ;
11321127
1133- while ( node ) {
1134- if ( isTypeNode ( node ) ) {
1135- topLevelTypeReference = node ;
1136- }
1137- node = node . parent ;
1128+ function addIfImplementation ( e : Expression ) : void {
1129+ if ( isImplementationExpression ( e ) ) addReference ( e ) ;
11381130 }
1139-
1140- return topLevelTypeReference ;
11411131 }
11421132
1143- function getContainingClassIfInHeritageClause ( node : Node ) : ClassLikeDeclaration {
1144- if ( node && node . parent ) {
1145- if ( node . kind === SyntaxKind . ExpressionWithTypeArguments
1146- && node . parent . kind === SyntaxKind . HeritageClause
1147- && isClassLike ( node . parent . parent ) ) {
1148- return node . parent . parent ;
1149- }
1150-
1151- else if ( node . kind === SyntaxKind . Identifier || node . kind === SyntaxKind . PropertyAccessExpression ) {
1152- return getContainingClassIfInHeritageClause ( node . parent ) ;
1153- }
1154- }
1155- return undefined ;
1133+ function getContainingClassIfInHeritageClause ( node : Node ) : ClassLikeDeclaration | InterfaceDeclaration {
1134+ return isIdentifier ( node ) || isPropertyAccessExpression ( node ) ? getContainingClassIfInHeritageClause ( node . parent )
1135+ : isExpressionWithTypeArguments ( node ) ? tryCast ( node . parent . parent , isClassLike ) : undefined ;
11561136 }
11571137
11581138 /**
0 commit comments