Skip to content

Commit 29776f4

Browse files
committed
Merge pull request #1782 from Microsoft/findAllRefs
use nameTable - services layer storage of identifiers in the file
2 parents 25324fa + da6070b commit 29776f4

File tree

3 files changed

+92
-12
lines changed

3 files changed

+92
-12
lines changed

src/services/services.ts

+52-12
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ module ts {
5959
isOpen: boolean;
6060
version: string;
6161
scriptSnapshot: IScriptSnapshot;
62-
62+
nameTable: Map<string>;
6363
getNamedDeclarations(): Declaration[];
6464
}
6565

@@ -750,6 +750,7 @@ module ts {
750750
public isOpen: boolean;
751751
public languageVersion: ScriptTarget;
752752
public identifiers: Map<string>;
753+
public nameTable: Map<string>;
753754

754755
private namedDeclarations: Declaration[];
755756

@@ -1546,6 +1547,8 @@ module ts {
15461547
export function createLanguageServiceSourceFile(filename: string, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: string, isOpen: boolean, setNodeParents: boolean): SourceFile {
15471548
var sourceFile = createSourceFile(filename, scriptSnapshot.getText(0, scriptSnapshot.getLength()), scriptTarget, setNodeParents);
15481549
setSourceFileFields(sourceFile, scriptSnapshot, version, isOpen);
1550+
// after full parsing we can use table with interned strings as name table
1551+
sourceFile.nameTable = sourceFile.identifiers;
15491552
return sourceFile;
15501553
}
15511554

@@ -1577,6 +1580,9 @@ module ts {
15771580
if (!disableIncrementalParsing) {
15781581
var newSourceFile = sourceFile.update(scriptSnapshot.getText(0, scriptSnapshot.getLength()), textChangeRange);
15791582
setSourceFileFields(newSourceFile, scriptSnapshot, version, isOpen);
1583+
// after incremental parsing nameTable might not be up-to-date
1584+
// drop it so it can be lazily recreated later
1585+
newSourceFile.nameTable = undefined;
15801586
return newSourceFile;
15811587
}
15821588
}
@@ -3235,7 +3241,7 @@ module ts {
32353241

32363242
if (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.ThisKeyword || node.kind === SyntaxKind.SuperKeyword ||
32373243
isLiteralNameOfPropertyDeclarationOrIndexAccess(node) || isNameOfExternalModuleImportOrDeclaration(node)) {
3238-
return getReferencesForNode(node, [sourceFile], /*findInStrings:*/ false, /*findInComments:*/ false);
3244+
return getReferencesForNode(node, [sourceFile], /*searchOnlyInCurrentFile*/ true, /*findInStrings:*/ false, /*findInComments:*/ false);
32393245
}
32403246

32413247
switch (node.kind) {
@@ -3788,10 +3794,31 @@ module ts {
37883794
}
37893795

37903796
Debug.assert(node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.NumericLiteral || node.kind === SyntaxKind.StringLiteral);
3791-
return getReferencesForNode(node, program.getSourceFiles(), findInStrings, findInComments);
3797+
return getReferencesForNode(node, program.getSourceFiles(), /*searchOnlyInCurrentFile*/ false, findInStrings, findInComments);
3798+
}
3799+
3800+
function initializeNameTable(sourceFile: SourceFile): void {
3801+
var nameTable: Map<string> = {};
3802+
3803+
walk(sourceFile);
3804+
sourceFile.nameTable = nameTable;
3805+
3806+
function walk(node: Node) {
3807+
switch (node.kind) {
3808+
case SyntaxKind.Identifier:
3809+
nameTable[(<Identifier>node).text] = (<Identifier>node).text;
3810+
break;
3811+
case SyntaxKind.StringLiteral:
3812+
case SyntaxKind.NumericLiteral:
3813+
nameTable[(<LiteralExpression>node).text] = (<LiteralExpression>node).text;
3814+
break;
3815+
default:
3816+
forEachChild(node, walk);
3817+
}
3818+
}
37923819
}
37933820

3794-
function getReferencesForNode(node: Node, sourceFiles: SourceFile[], findInStrings: boolean, findInComments: boolean): ReferenceEntry[] {
3821+
function getReferencesForNode(node: Node, sourceFiles: SourceFile[], searchOnlyInCurrentFile: boolean, findInStrings: boolean, findInComments: boolean): ReferenceEntry[] {
37953822
// Labels
37963823
if (isLabelName(node)) {
37973824
if (isJumpStatementTarget(node)) {
@@ -3847,15 +3874,28 @@ module ts {
38473874
getReferencesInNode(scope, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result);
38483875
}
38493876
else {
3850-
var internedName = getInternedName(symbol, declarations)
3851-
forEach(sourceFiles, sourceFile => {
3852-
cancellationToken.throwIfCancellationRequested();
3877+
if (searchOnlyInCurrentFile) {
3878+
Debug.assert(sourceFiles.length === 1);
3879+
result = [];
3880+
getReferencesInNode(sourceFiles[0], symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result);
3881+
}
3882+
else {
3883+
var internedName = getInternedName(symbol, declarations)
3884+
forEach(sourceFiles, sourceFile => {
3885+
cancellationToken.throwIfCancellationRequested();
38533886

3854-
if (lookUp(sourceFile.identifiers, internedName)) {
3855-
result = result || [];
3856-
getReferencesInNode(sourceFile, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result);
3857-
}
3858-
});
3887+
if (!sourceFile.nameTable) {
3888+
initializeNameTable(sourceFile)
3889+
}
3890+
3891+
Debug.assert(sourceFile.nameTable !== undefined);
3892+
3893+
if (lookUp(sourceFile.nameTable, internedName)) {
3894+
result = result || [];
3895+
getReferencesInNode(sourceFile, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result);
3896+
}
3897+
});
3898+
}
38593899
}
38603900

38613901
return result;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/// <reference path='fourslash.ts'/>
2+
3+
// @Filename: a.ts
4+
////interface A {
5+
//// foo: string;
6+
////}
7+
8+
// @Filename: b.ts
9+
///////<reference path='a.ts'/>
10+
/////*0*/
11+
////function foo(x: A) {
12+
//// x.f/*1*/oo
13+
////}
14+
15+
goTo.marker("1");
16+
verify.referencesCountIs(2);
17+
18+
goTo.marker("0");
19+
edit.insert("\r\n");
20+
21+
goTo.marker("1");
22+
verify.referencesCountIs(2);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/// <reference path='fourslash.ts'/>
2+
3+
/////*0*/
4+
////interface A {
5+
//// foo: string;
6+
////}
7+
////function foo(x: A) {
8+
//// x.f/*1*/oo
9+
////}
10+
11+
goTo.marker("1");
12+
verify.occurrencesAtPositionCount(2);
13+
14+
goTo.marker("0");
15+
edit.insert("\r\n");
16+
17+
goTo.marker("1");
18+
verify.occurrencesAtPositionCount(2);

0 commit comments

Comments
 (0)