Skip to content

Commit 1121e11

Browse files
Basic implementation without tests for findAllRefs/getOccs for 'super' keywords.
1 parent 024ca6d commit 1121e11

File tree

2 files changed

+85
-48
lines changed

2 files changed

+85
-48
lines changed

src/compiler/parser.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,23 @@ module ts {
434434
}
435435
}
436436

437+
export function getSuperContainer(node: Node): Node {
438+
while (true) {
439+
node = node.parent;
440+
if (!node) {
441+
return node;
442+
}
443+
switch (node.kind) {
444+
case SyntaxKind.Property:
445+
case SyntaxKind.Method:
446+
case SyntaxKind.Constructor:
447+
case SyntaxKind.GetAccessor:
448+
case SyntaxKind.SetAccessor:
449+
return node;
450+
}
451+
}
452+
}
453+
437454
export function hasRestParameters(s: SignatureDeclaration): boolean {
438455
return s.parameters.length > 0 && (s.parameters[s.parameters.length - 1].flags & NodeFlags.Rest) !== 0;
439456
}

src/services/services.ts

Lines changed: 68 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,7 +2146,7 @@ module ts {
21462146
return undefined;
21472147
}
21482148

2149-
if (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.ThisKeyword ||
2149+
if (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.ThisKeyword || node.kind === SyntaxKind.SuperKeyword ||
21502150
isLiteralNameOfPropertyDeclarationOrIndexAccess(node) || isNameOfExternalModuleImportOrDeclaration(node)) {
21512151
return getReferencesForNode(node, [sourceFile]);
21522152
}
@@ -2379,6 +2379,7 @@ module ts {
23792379

23802380
if (node.kind !== SyntaxKind.Identifier &&
23812381
node.kind !== SyntaxKind.ThisKeyword &&
2382+
node.kind !== SyntaxKind.SuperKeyword &&
23822383
!isLiteralNameOfPropertyDeclarationOrIndexAccess(node) &&
23832384
!isNameOfExternalModuleImportOrDeclaration(node)) {
23842385
return undefined;
@@ -2402,8 +2403,8 @@ module ts {
24022403
}
24032404
}
24042405

2405-
if (node.kind === SyntaxKind.ThisKeyword) {
2406-
return getReferencesForThisKeyword(node, sourceFiles);
2406+
if (node.kind === SyntaxKind.ThisKeyword || node.kind === SyntaxKind.SuperKeyword) {
2407+
return getReferencesForThisOrSuperKeyword(node, sourceFiles);
24072408
}
24082409

24092410
var symbol = typeInfoResolver.getSymbolInfo(node);
@@ -2627,32 +2628,46 @@ module ts {
26272628
}
26282629
}
26292630

2630-
function getReferencesForThisKeyword(thisKeyword: Node, sourceFiles: SourceFile[]) {
2631-
// Get the owner" of the 'this' keyword.
2632-
var thisContainer = getThisContainer(thisKeyword, /* includeArrowFunctions */ false);
2633-
2631+
function getReferencesForThisOrSuperKeyword(thisOrSuperKeyword: Node, sourceFiles: SourceFile[]): ReferenceEntry[] {
2632+
var keywordName: string;
26342633
var searchSpaceNode: Node;
26352634

2636-
// Whether 'this' occurs in a static context within a class;
2635+
if (thisOrSuperKeyword.kind === SyntaxKind.ThisKeyword) {
2636+
keywordName = "this"
2637+
searchSpaceNode = getThisContainer(thisOrSuperKeyword, /* includeArrowFunctions */ false);
2638+
}
2639+
else {
2640+
keywordName = "super";
2641+
searchSpaceNode = getSuperContainer(thisOrSuperKeyword);
2642+
2643+
if (!searchSpaceNode) {
2644+
return undefined;
2645+
}
2646+
}
2647+
2648+
// Whether 'this'/'super' occurs in a static context within a class.
26372649
var staticFlag = NodeFlags.Static;
26382650

2639-
switch (thisContainer.kind) {
2651+
switch (searchSpaceNode.kind) {
26402652
case SyntaxKind.Property:
26412653
case SyntaxKind.Method:
26422654
case SyntaxKind.Constructor:
26432655
case SyntaxKind.GetAccessor:
26442656
case SyntaxKind.SetAccessor:
2645-
searchSpaceNode = thisContainer.parent; // should be the owning class
2646-
staticFlag &= thisContainer.flags
2657+
staticFlag &= searchSpaceNode.flags
2658+
searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class
26472659
break;
26482660
case SyntaxKind.SourceFile:
2649-
if (isExternalModule(<SourceFile>thisContainer)) {
2661+
if (isExternalModule(<SourceFile>searchSpaceNode)) {
26502662
return undefined;
26512663
}
2652-
// Fall through
2664+
break;
26532665
case SyntaxKind.FunctionDeclaration:
26542666
case SyntaxKind.FunctionExpression:
2655-
searchSpaceNode = thisContainer;
2667+
// 'super' can only occur within a class.
2668+
if (thisOrSuperKeyword.kind === SyntaxKind.SuperKeyword) {
2669+
return undefined;
2670+
}
26562671
break;
26572672
default:
26582673
return undefined;
@@ -2662,55 +2677,60 @@ module ts {
26622677

26632678
if (searchSpaceNode.kind === SyntaxKind.SourceFile) {
26642679
forEach(sourceFiles, sourceFile => {
2665-
var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", sourceFile.getStart(), sourceFile.getEnd());
2666-
getThisReferencesInFile(sourceFile, sourceFile, possiblePositions, result);
2680+
var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, keywordName, sourceFile.getStart(), sourceFile.getEnd());
2681+
getThisOrSuperReferencesInFile(sourceFile, sourceFile, possiblePositions, result);
26672682
});
26682683
}
26692684
else {
26702685
var sourceFile = searchSpaceNode.getSourceFile();
2671-
var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", searchSpaceNode.getStart(), searchSpaceNode.getEnd());
2672-
getThisReferencesInFile(sourceFile, searchSpaceNode, possiblePositions, result);
2686+
var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, keywordName, searchSpaceNode.getStart(), searchSpaceNode.getEnd());
2687+
getThisOrSuperReferencesInFile(sourceFile, searchSpaceNode, possiblePositions, result);
26732688
}
26742689

26752690
return result;
26762691

2677-
function getThisReferencesInFile(sourceFile: SourceFile, searchSpaceNode: Node, possiblePositions: number[], result: ReferenceEntry[]): void {
2692+
function getThisOrSuperReferencesInFile(sourceFile: SourceFile, searchSpaceNode: Node, possiblePositions: number[], result: ReferenceEntry[]): void {
26782693
forEach(possiblePositions, position => {
26792694
cancellationToken.throwIfCancellationRequested();
26802695

26812696
var node = getNodeAtPosition(sourceFile, position);
2682-
if (!node || node.kind !== SyntaxKind.ThisKeyword) {
2697+
if (!node) {
26832698
return;
26842699
}
26852700

2686-
// Get the owner of the 'this' keyword.
2687-
// This *should* be a node that occurs somewhere within searchSpaceNode.
2688-
var container = getThisContainer(node, /* includeArrowFunctions */ false);
2689-
2690-
switch (container.kind) {
2691-
case SyntaxKind.Property:
2692-
case SyntaxKind.Method:
2693-
case SyntaxKind.Constructor:
2694-
case SyntaxKind.GetAccessor:
2695-
case SyntaxKind.SetAccessor:
2696-
// Make sure the container belongs to the same class
2697-
// and has the appropriate static modifier from the original container.
2698-
if (searchSpaceNode.symbol === container.parent.symbol && (container.flags & NodeFlags.Static) === staticFlag) {
2699-
result.push(getReferenceEntryFromNode(node));
2700-
}
2701-
break;
2702-
case SyntaxKind.FunctionDeclaration:
2703-
case SyntaxKind.FunctionExpression:
2704-
if (searchSpaceNode.symbol === container.symbol) {
2705-
result.push(getReferenceEntryFromNode(node));
2706-
}
2707-
break;
2708-
case SyntaxKind.SourceFile:
2709-
// Add all 'this' keywords that belong to the top-level scope.
2710-
if (searchSpaceNode.kind === SyntaxKind.SourceFile && !isExternalModule(<SourceFile>searchSpaceNode)) {
2711-
result.push(getReferenceEntryFromNode(node));
2712-
}
2713-
break;
2701+
var container = getNodeAtPosition(sourceFile, position);
2702+
if (!container) {
2703+
return;
2704+
}
2705+
2706+
if (node.kind === SyntaxKind.SuperKeyword) {
2707+
container = getSuperContainer(node);
2708+
}
2709+
else if (node.kind === SyntaxKind.ThisKeyword) {
2710+
container = getThisContainer(node, /* includeArrowFunctions */ false);
2711+
}
2712+
2713+
if (container) {
2714+
switch (searchSpaceNode.kind) {
2715+
case SyntaxKind.FunctionExpression:
2716+
case SyntaxKind.FunctionDeclaration:
2717+
if (searchSpaceNode.symbol === container.symbol) {
2718+
result.push(getReferenceEntryFromNode(node));
2719+
}
2720+
break;
2721+
case SyntaxKind.ClassDeclaration:
2722+
// Make sure the container belongs to the same class
2723+
// and has the appropriate static modifier from the original container.
2724+
if (container.parent && searchSpaceNode.symbol === container.parent.symbol && (container.flags & NodeFlags.Static) === staticFlag) {
2725+
result.push(getReferenceEntryFromNode(node));
2726+
}
2727+
break;
2728+
case SyntaxKind.SourceFile:
2729+
if (container.kind === SyntaxKind.SourceFile && !isExternalModule(<SourceFile>container)) {
2730+
result.push(getReferenceEntryFromNode(node));
2731+
}
2732+
break;
2733+
}
27142734
}
27152735
});
27162736
}

0 commit comments

Comments
 (0)