Skip to content

Commit 999ac0a

Browse files
author
Andy
authored
Merge pull request microsoft#9270 from Microsoft/this_references
Allow to find all references of the 'this 'keyword
2 parents 515ed3d + 89c992a commit 999ac0a

16 files changed

Lines changed: 248 additions & 127 deletions

src/compiler/checker.ts

Lines changed: 88 additions & 57 deletions
Large diffs are not rendered by default.

src/compiler/types.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1874,7 +1874,7 @@ namespace ts {
18741874
buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
18751875
buildTypePredicateDisplay(predicate: TypePredicate, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
18761876
buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
1877-
buildDisplayForParametersAndDelimiters(thisType: Type, parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
1877+
buildDisplayForParametersAndDelimiters(thisParameter: Symbol, parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
18781878
buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
18791879
buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
18801880
}
@@ -2394,7 +2394,8 @@ namespace ts {
23942394
declaration: SignatureDeclaration; // Originating declaration
23952395
typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic)
23962396
parameters: Symbol[]; // Parameters
2397-
thisType?: Type; // type of this-type
2397+
/* @internal */
2398+
thisParameter?: Symbol; // symbol of this-type parameter
23982399
/* @internal */
23992400
resolvedReturnType: Type; // Resolved return type
24002401
/* @internal */

src/harness/fourslash.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,7 @@ namespace FourSlash {
760760
// Find the unaccounted-for reference.
761761
for (const actual of actualReferences) {
762762
if (!ts.forEach(expectedReferences, r => r.start === actual.textSpan.start)) {
763-
this.raiseError(`A reference ${actual} is unaccounted for.`);
763+
this.raiseError(`A reference ${stringify(actual)} is unaccounted for.`);
764764
}
765765
}
766766
// Probably will never reach here.
@@ -907,13 +907,13 @@ namespace FourSlash {
907907
assert.equal(getDisplayPartsJson(actualQuickInfo.documentation), getDisplayPartsJson(documentation), this.messageAtLastKnownMarker("QuickInfo documentation"));
908908
}
909909

910-
public verifyRenameLocations(findInStrings: boolean, findInComments: boolean) {
910+
public verifyRenameLocations(findInStrings: boolean, findInComments: boolean, ranges?: Range[]) {
911911
const renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition);
912912
if (renameInfo.canRename) {
913913
let references = this.languageService.findRenameLocations(
914914
this.activeFile.fileName, this.currentCaretPosition, findInStrings, findInComments);
915915

916-
let ranges = this.getRanges();
916+
ranges = ranges || this.getRanges();
917917

918918
if (!references) {
919919
if (ranges.length !== 0) {
@@ -3128,8 +3128,8 @@ namespace FourSlashInterface {
31283128
this.state.verifyRenameInfoFailed(message);
31293129
}
31303130

3131-
public renameLocations(findInStrings: boolean, findInComments: boolean) {
3132-
this.state.verifyRenameLocations(findInStrings, findInComments);
3131+
public renameLocations(findInStrings: boolean, findInComments: boolean, ranges?: FourSlash.Range[]) {
3132+
this.state.verifyRenameLocations(findInStrings, findInComments, ranges);
31333133
}
31343134

31353135
public verifyQuickInfoDisplayParts(kind: string, kindModifiers: string, textSpan: { start: number; length: number; },

src/services/services.ts

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,7 @@ namespace ts {
779779
declaration: SignatureDeclaration;
780780
typeParameters: TypeParameter[];
781781
parameters: Symbol[];
782-
thisType: Type;
782+
thisParameter: Symbol;
783783
resolvedReturnType: Type;
784784
minArgumentCount: number;
785785
hasRestParameter: boolean;
@@ -5819,17 +5819,32 @@ namespace ts {
58195819
return undefined;
58205820
}
58215821

5822-
if (node.kind !== SyntaxKind.Identifier &&
5823-
// TODO (drosen): This should be enabled in a later release - currently breaks rename.
5824-
// node.kind !== SyntaxKind.ThisKeyword &&
5825-
// node.kind !== SyntaxKind.SuperKeyword &&
5826-
node.kind !== SyntaxKind.StringLiteral &&
5827-
!isLiteralNameOfPropertyDeclarationOrIndexAccess(node)) {
5828-
return undefined;
5822+
switch (node.kind) {
5823+
case SyntaxKind.NumericLiteral:
5824+
if (!isLiteralNameOfPropertyDeclarationOrIndexAccess(node)) {
5825+
break;
5826+
}
5827+
// Fallthrough
5828+
case SyntaxKind.Identifier:
5829+
case SyntaxKind.ThisKeyword:
5830+
// case SyntaxKind.SuperKeyword: TODO:GH#9268
5831+
case SyntaxKind.StringLiteral:
5832+
return getReferencedSymbolsForNode(node, program.getSourceFiles(), findInStrings, findInComments);
58295833
}
5834+
return undefined;
5835+
}
58305836

5831-
Debug.assert(node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.NumericLiteral || node.kind === SyntaxKind.StringLiteral);
5832-
return getReferencedSymbolsForNode(node, program.getSourceFiles(), findInStrings, findInComments);
5837+
function isThis(node: Node): boolean {
5838+
switch (node.kind) {
5839+
case SyntaxKind.ThisKeyword:
5840+
// case SyntaxKind.ThisType: TODO: GH#9267
5841+
return true;
5842+
case SyntaxKind.Identifier:
5843+
// 'this' as a parameter
5844+
return (node as Identifier).originalKeywordKind === SyntaxKind.ThisKeyword && node.parent.kind === SyntaxKind.Parameter;
5845+
default:
5846+
return false;
5847+
}
58335848
}
58345849

58355850
function getReferencedSymbolsForNode(node: Node, sourceFiles: SourceFile[], findInStrings: boolean, findInComments: boolean): ReferencedSymbol[] {
@@ -5849,7 +5864,7 @@ namespace ts {
58495864
}
58505865
}
58515866

5852-
if (node.kind === SyntaxKind.ThisKeyword || node.kind === SyntaxKind.ThisType) {
5867+
if (isThis(node)) {
58535868
return getReferencesForThisKeyword(node, sourceFiles);
58545869
}
58555870

@@ -6384,7 +6399,7 @@ namespace ts {
63846399
cancellationToken.throwIfCancellationRequested();
63856400

63866401
const node = getTouchingWord(sourceFile, position);
6387-
if (!node || (node.kind !== SyntaxKind.ThisKeyword && node.kind !== SyntaxKind.ThisType)) {
6402+
if (!node || !isThis(node)) {
63886403
return;
63896404
}
63906405

@@ -8012,11 +8027,11 @@ namespace ts {
80128027

80138028
const node = getTouchingWord(sourceFile, position, /*includeJsDocComment*/ true);
80148029

8015-
// Can only rename an identifier.
80168030
if (node) {
80178031
if (node.kind === SyntaxKind.Identifier ||
80188032
node.kind === SyntaxKind.StringLiteral ||
8019-
isLiteralNameOfPropertyDeclarationOrIndexAccess(node)) {
8033+
isLiteralNameOfPropertyDeclarationOrIndexAccess(node) ||
8034+
isThis(node)) {
80208035
const symbol = typeChecker.getSymbolAtLocation(node);
80218036

80228037
// Only allow a symbol to be renamed if it actually has at least one declaration.

src/services/signatureHelp.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -357,8 +357,8 @@ namespace ts.SignatureHelp {
357357
}
358358

359359
function getArgumentIndex(argumentsList: Node, node: Node) {
360-
// The list we got back can include commas. In the presence of errors it may
361-
// also just have nodes without commas. For example "Foo(a b c)" will have 3
360+
// The list we got back can include commas. In the presence of errors it may
361+
// also just have nodes without commas. For example "Foo(a b c)" will have 3
362362
// args without commas. We want to find what index we're at. So we count
363363
// forward until we hit ourselves, only incrementing the index if it isn't a
364364
// comma.
@@ -390,8 +390,8 @@ namespace ts.SignatureHelp {
390390
// 'a' '<comma>'. So, in the case where the last child is a comma, we increase the
391391
// arg count by one to compensate.
392392
//
393-
// Note: this subtlety only applies to the last comma. If you had "Foo(a,," then
394-
// we'll have: 'a' '<comma>' '<missing>'
393+
// Note: this subtlety only applies to the last comma. If you had "Foo(a,," then
394+
// we'll have: 'a' '<comma>' '<missing>'
395395
// That will give us 2 non-commas. We then add one for the last comma, givin us an
396396
// arg count of 3.
397397
const listChildren = argumentsList.getChildren();
@@ -563,7 +563,7 @@ namespace ts.SignatureHelp {
563563
signatureHelpParameters = typeParameters && typeParameters.length > 0 ? map(typeParameters, createSignatureHelpParameterForTypeParameter) : emptyArray;
564564
suffixDisplayParts.push(punctuationPart(SyntaxKind.GreaterThanToken));
565565
const parameterParts = mapToDisplayParts(writer =>
566-
typeChecker.getSymbolDisplayBuilder().buildDisplayForParametersAndDelimiters(candidateSignature.thisType, candidateSignature.parameters, writer, invocation));
566+
typeChecker.getSymbolDisplayBuilder().buildDisplayForParametersAndDelimiters(candidateSignature.thisParameter, candidateSignature.parameters, writer, invocation));
567567
addRange(suffixDisplayParts, parameterParts);
568568
}
569569
else {

tests/baselines/reference/inferParameterWithMethodCallInitializer.symbols

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ function weird(this: Example, a = this.getNumber()) {
3030
>Example : Symbol(Example, Decl(inferParameterWithMethodCallInitializer.ts, 2, 1))
3131
>a : Symbol(a, Decl(inferParameterWithMethodCallInitializer.ts, 11, 29))
3232
>this.getNumber : Symbol(Example.getNumber, Decl(inferParameterWithMethodCallInitializer.ts, 3, 15))
33-
>this : Symbol(Example, Decl(inferParameterWithMethodCallInitializer.ts, 2, 1))
33+
>this : Symbol(this, Decl(inferParameterWithMethodCallInitializer.ts, 11, 15))
3434
>getNumber : Symbol(Example.getNumber, Decl(inferParameterWithMethodCallInitializer.ts, 3, 15))
3535

3636
return a;
@@ -45,7 +45,7 @@ class Weird {
4545
>Example : Symbol(Example, Decl(inferParameterWithMethodCallInitializer.ts, 2, 1))
4646
>a : Symbol(a, Decl(inferParameterWithMethodCallInitializer.ts, 15, 30))
4747
>this.getNumber : Symbol(Example.getNumber, Decl(inferParameterWithMethodCallInitializer.ts, 3, 15))
48-
>this : Symbol(Example, Decl(inferParameterWithMethodCallInitializer.ts, 2, 1))
48+
>this : Symbol(this, Decl(inferParameterWithMethodCallInitializer.ts, 15, 16))
4949
>getNumber : Symbol(Example.getNumber, Decl(inferParameterWithMethodCallInitializer.ts, 3, 15))
5050

5151
return a;

tests/baselines/reference/thisTypeInAccessors.symbols

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const explicit = {
2020
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 7, 10))
2121
>Foo : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
2222
>this.n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
23-
>this : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
23+
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 7, 10))
2424
>n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
2525

2626
set x(this: Foo, n: number) { this.n = n; }
@@ -29,7 +29,7 @@ const explicit = {
2929
>Foo : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
3030
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 8, 20))
3131
>this.n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
32-
>this : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
32+
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 8, 10))
3333
>n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
3434
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 8, 20))
3535
}
@@ -44,14 +44,14 @@ const copiedFromGetter = {
4444
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 12, 10))
4545
>Foo : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
4646
>this.n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
47-
>this : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
47+
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 12, 10))
4848
>n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
4949

5050
set x(n) { this.n = n; }
5151
>x : Symbol(x, Decl(thisTypeInAccessors.ts, 11, 10), Decl(thisTypeInAccessors.ts, 12, 48))
5252
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 13, 10))
5353
>this.n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
54-
>this : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
54+
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 12, 10))
5555
>n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
5656
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 13, 10))
5757
}
@@ -64,7 +64,7 @@ const copiedFromSetter = {
6464
get x() { return this.n },
6565
>x : Symbol(x, Decl(thisTypeInAccessors.ts, 16, 10), Decl(thisTypeInAccessors.ts, 17, 30))
6666
>this.n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
67-
>this : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
67+
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 18, 10))
6868
>n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
6969

7070
set x(this: Foo, n: number) { this.n = n; }
@@ -73,7 +73,7 @@ const copiedFromSetter = {
7373
>Foo : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
7474
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 18, 20))
7575
>this.n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
76-
>this : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
76+
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 18, 10))
7777
>n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
7878
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 18, 20))
7979
}
@@ -88,15 +88,15 @@ const copiedFromGetterUnannotated = {
8888
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 22, 10))
8989
>Foo : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
9090
>this.n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
91-
>this : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
91+
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 22, 10))
9292
>n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
9393

9494
set x(this, n) { this.n = n; }
9595
>x : Symbol(x, Decl(thisTypeInAccessors.ts, 21, 10), Decl(thisTypeInAccessors.ts, 22, 39))
9696
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 23, 10))
9797
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 23, 15))
9898
>this.n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
99-
>this : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
99+
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 23, 10))
100100
>n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
101101
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 23, 15))
102102
}
@@ -112,7 +112,7 @@ class Explicit {
112112
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 28, 10))
113113
>Foo : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
114114
>this.n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
115-
>this : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
115+
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 28, 10))
116116
>n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
117117

118118
set x(this: Foo, n: number) { this.n = n; }
@@ -121,7 +121,7 @@ class Explicit {
121121
>Foo : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
122122
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 29, 20))
123123
>this.n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
124-
>this : Symbol(Foo, Decl(thisTypeInAccessors.ts, 0, 0))
124+
>this : Symbol(this, Decl(thisTypeInAccessors.ts, 29, 10))
125125
>n : Symbol(Foo.n, Decl(thisTypeInAccessors.ts, 0, 15))
126126
>n : Symbol(n, Decl(thisTypeInAccessors.ts, 29, 20))
127127
}

0 commit comments

Comments
 (0)