diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index 54f87d8e50b..cc81031fc04 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -9,11 +9,10 @@ module ts.NavigateTo { forEach(program.getSourceFiles(), sourceFile => { cancellationToken.throwIfCancellationRequested(); - let declarations = sourceFile.getNamedDeclarations(); - for (let declaration of declarations) { - var name = getDeclarationName(declaration); - if (name !== undefined) { - + let nameToDeclarations = sourceFile.getNamedDeclarations(); + for (let name in nameToDeclarations) { + let declarations = getProperty(nameToDeclarations, name); + if (declarations) { // First do a quick check to see if the name of the declaration matches the // last portion of the (possibly) dotted name they're searching for. let matches = patternMatcher.getMatchesForLastSegmentOfPattern(name); @@ -22,24 +21,26 @@ module ts.NavigateTo { continue; } - // It was a match! If the pattern has dots in it, then also see if the - // declaration container matches as well. - if (patternMatcher.patternContainsDots) { - let containers = getContainers(declaration); - if (!containers) { - return undefined; + for (let declaration of declarations) { + // It was a match! If the pattern has dots in it, then also see if the + // declaration container matches as well. + if (patternMatcher.patternContainsDots) { + let containers = getContainers(declaration); + if (!containers) { + return undefined; + } + + matches = patternMatcher.getMatches(containers, name); + + if (!matches) { + continue; + } } - matches = patternMatcher.getMatches(containers, name); - - if (!matches) { - continue; - } + let fileName = sourceFile.fileName; + let matchKind = bestMatchKind(matches); + rawItems.push({ name, fileName, matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration }); } - - let fileName = sourceFile.fileName; - let matchKind = bestMatchKind(matches); - rawItems.push({ name, fileName, matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration }); } } }); @@ -66,30 +67,14 @@ module ts.NavigateTo { return true; } - function getDeclarationName(declaration: Declaration): string { - let result = getTextOfIdentifierOrLiteral(declaration.name); - if (result !== undefined) { - return result; - } - - if (declaration.name.kind === SyntaxKind.ComputedPropertyName) { - let expr = (declaration.name).expression; - if (expr.kind === SyntaxKind.PropertyAccessExpression) { - return (expr).name.text; - } - - return getTextOfIdentifierOrLiteral(expr); - } - - return undefined; - } - function getTextOfIdentifierOrLiteral(node: Node) { - if (node.kind === SyntaxKind.Identifier || - node.kind === SyntaxKind.StringLiteral || - node.kind === SyntaxKind.NumericLiteral) { + if (node) { + if (node.kind === SyntaxKind.Identifier || + node.kind === SyntaxKind.StringLiteral || + node.kind === SyntaxKind.NumericLiteral) { - return (node).text; + return (node).text; + } } return undefined; diff --git a/src/services/services.ts b/src/services/services.ts index 12ea84eafc1..67d799f62f0 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -63,7 +63,8 @@ module ts { /* @internal */ scriptSnapshot: IScriptSnapshot; /* @internal */ nameTable: Map; - getNamedDeclarations(): Declaration[]; + /* @internal */ getNamedDeclarations(): Map; + getLineAndCharacterOfPosition(pos: number): LineAndCharacter; getLineStarts(): number[]; getPositionOfLineAndCharacter(line: number, character: number): number; @@ -749,7 +750,7 @@ module ts { public identifiers: Map; public nameTable: Map; - private namedDeclarations: Declaration[]; + private namedDeclarations: Map; public update(newText: string, textChangeRange: TextChangeRange): SourceFile { return updateSourceFile(this, newText, textChangeRange); @@ -767,7 +768,7 @@ module ts { return ts.getPositionOfLineAndCharacter(this, line, character); } - public getNamedDeclarations() { + public getNamedDeclarations(): Map { if (!this.namedDeclarations) { this.namedDeclarations = this.computeNamedDeclarations(); } @@ -775,12 +776,57 @@ module ts { return this.namedDeclarations; } - private computeNamedDeclarations() { - let namedDeclarations: Declaration[] = []; + private computeNamedDeclarations(): Map { + let result: Map = {}; forEachChild(this, visit); - return namedDeclarations; + return result; + + function addDeclaration(declaration: Declaration) { + let name = getDeclarationName(declaration); + if (name) { + let declarations = getDeclarations(name); + declarations.push(declaration); + } + } + + function getDeclarations(name: string) { + return getProperty(result, name) || (result[name] = []); + } + + function getDeclarationName(declaration: Declaration) { + if (declaration.name) { + let result = getTextOfIdentifierOrLiteral(declaration.name); + if (result !== undefined) { + return result; + } + + if (declaration.name.kind === SyntaxKind.ComputedPropertyName) { + let expr = (declaration.name).expression; + if (expr.kind === SyntaxKind.PropertyAccessExpression) { + return (expr).name.text; + } + + return getTextOfIdentifierOrLiteral(expr); + } + } + + return undefined; + } + + function getTextOfIdentifierOrLiteral(node: Node) { + if (node) { + if (node.kind === SyntaxKind.Identifier || + node.kind === SyntaxKind.StringLiteral || + node.kind === SyntaxKind.NumericLiteral) { + + return (node).text; + } + } + + return undefined; + } function visit(node: Node): void { switch (node.kind) { @@ -788,22 +834,22 @@ module ts { case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: let functionDeclaration = node; + let declarationName = getDeclarationName(functionDeclaration); - if (functionDeclaration.name && functionDeclaration.name.getFullWidth() > 0) { - let lastDeclaration = namedDeclarations.length > 0 ? - namedDeclarations[namedDeclarations.length - 1] : - undefined; + if (declarationName) { + let declarations = getDeclarations(declarationName); + let lastDeclaration = lastOrUndefined(declarations); // Check whether this declaration belongs to an "overload group". - if (lastDeclaration && functionDeclaration.symbol === lastDeclaration.symbol) { + if (lastDeclaration && functionDeclaration.parent === lastDeclaration.parent && functionDeclaration.symbol === lastDeclaration.symbol) { // Overwrite the last declaration if it was an overload // and this one is an implementation. if (functionDeclaration.body && !(lastDeclaration).body) { - namedDeclarations[namedDeclarations.length - 1] = functionDeclaration; + declarations[declarations.length - 1] = functionDeclaration; } } else { - namedDeclarations.push(functionDeclaration); + declarations.push(functionDeclaration); } forEachChild(node, visit); @@ -824,10 +870,8 @@ module ts { case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: case SyntaxKind.TypeLiteral: - if ((node).name) { - namedDeclarations.push(node); - } - // fall through + addDeclaration(node); + // fall through case SyntaxKind.Constructor: case SyntaxKind.VariableStatement: case SyntaxKind.VariableDeclarationList: @@ -858,7 +902,7 @@ module ts { case SyntaxKind.EnumMember: case SyntaxKind.PropertyDeclaration: case SyntaxKind.PropertySignature: - namedDeclarations.push(node); + addDeclaration(node); break; case SyntaxKind.ExportDeclaration: @@ -875,7 +919,7 @@ module ts { // Handle default import case e.g.: // import d from "mod"; if (importClause.name) { - namedDeclarations.push(importClause); + addDeclaration(importClause); } // Handle named bindings in imports e.g.: @@ -883,7 +927,7 @@ module ts { // import {a, b as B} from "mod"; if (importClause.namedBindings) { if (importClause.namedBindings.kind === SyntaxKind.NamespaceImport) { - namedDeclarations.push(importClause.namedBindings); + addDeclaration(importClause.namedBindings); } else { forEach((importClause.namedBindings).elements, visit); diff --git a/tests/baselines/reference/APISample_compile.js b/tests/baselines/reference/APISample_compile.js index 6c28c96a6d8..b604b5f950b 100644 --- a/tests/baselines/reference/APISample_compile.js +++ b/tests/baselines/reference/APISample_compile.js @@ -1562,7 +1562,6 @@ declare module "typescript" { getDocumentationComment(): SymbolDisplayPart[]; } interface SourceFile { - getNamedDeclarations(): Declaration[]; getLineAndCharacterOfPosition(pos: number): LineAndCharacter; getLineStarts(): number[]; getPositionOfLineAndCharacter(line: number, character: number): number; diff --git a/tests/baselines/reference/APISample_compile.types b/tests/baselines/reference/APISample_compile.types index 635aff75628..3b66a5bfe29 100644 --- a/tests/baselines/reference/APISample_compile.types +++ b/tests/baselines/reference/APISample_compile.types @@ -5018,10 +5018,6 @@ declare module "typescript" { interface SourceFile { >SourceFile : SourceFile - getNamedDeclarations(): Declaration[]; ->getNamedDeclarations : () => Declaration[] ->Declaration : Declaration - getLineAndCharacterOfPosition(pos: number): LineAndCharacter; >getLineAndCharacterOfPosition : (pos: number) => LineAndCharacter >pos : number diff --git a/tests/baselines/reference/APISample_linter.js b/tests/baselines/reference/APISample_linter.js index f59fa91da14..5c2627041f0 100644 --- a/tests/baselines/reference/APISample_linter.js +++ b/tests/baselines/reference/APISample_linter.js @@ -1593,7 +1593,6 @@ declare module "typescript" { getDocumentationComment(): SymbolDisplayPart[]; } interface SourceFile { - getNamedDeclarations(): Declaration[]; getLineAndCharacterOfPosition(pos: number): LineAndCharacter; getLineStarts(): number[]; getPositionOfLineAndCharacter(line: number, character: number): number; diff --git a/tests/baselines/reference/APISample_linter.types b/tests/baselines/reference/APISample_linter.types index 12f4ac12fdc..048eb9b5604 100644 --- a/tests/baselines/reference/APISample_linter.types +++ b/tests/baselines/reference/APISample_linter.types @@ -5164,10 +5164,6 @@ declare module "typescript" { interface SourceFile { >SourceFile : SourceFile - getNamedDeclarations(): Declaration[]; ->getNamedDeclarations : () => Declaration[] ->Declaration : Declaration - getLineAndCharacterOfPosition(pos: number): LineAndCharacter; >getLineAndCharacterOfPosition : (pos: number) => LineAndCharacter >pos : number diff --git a/tests/baselines/reference/APISample_linter.types.pull b/tests/baselines/reference/APISample_linter.types.pull index 0a2a7ea948a..e262cf3954b 100644 --- a/tests/baselines/reference/APISample_linter.types.pull +++ b/tests/baselines/reference/APISample_linter.types.pull @@ -5164,10 +5164,6 @@ declare module "typescript" { interface SourceFile { >SourceFile : SourceFile - getNamedDeclarations(): Declaration[]; ->getNamedDeclarations : () => Declaration[] ->Declaration : Declaration - getLineAndCharacterOfPosition(pos: number): LineAndCharacter; >getLineAndCharacterOfPosition : (pos: number) => LineAndCharacter >pos : number diff --git a/tests/baselines/reference/APISample_transform.js b/tests/baselines/reference/APISample_transform.js index 6bdf755ae12..b160719f947 100644 --- a/tests/baselines/reference/APISample_transform.js +++ b/tests/baselines/reference/APISample_transform.js @@ -1594,7 +1594,6 @@ declare module "typescript" { getDocumentationComment(): SymbolDisplayPart[]; } interface SourceFile { - getNamedDeclarations(): Declaration[]; getLineAndCharacterOfPosition(pos: number): LineAndCharacter; getLineStarts(): number[]; getPositionOfLineAndCharacter(line: number, character: number): number; diff --git a/tests/baselines/reference/APISample_transform.types b/tests/baselines/reference/APISample_transform.types index 4bd248d70c7..4ac4e6da456 100644 --- a/tests/baselines/reference/APISample_transform.types +++ b/tests/baselines/reference/APISample_transform.types @@ -5114,10 +5114,6 @@ declare module "typescript" { interface SourceFile { >SourceFile : SourceFile - getNamedDeclarations(): Declaration[]; ->getNamedDeclarations : () => Declaration[] ->Declaration : Declaration - getLineAndCharacterOfPosition(pos: number): LineAndCharacter; >getLineAndCharacterOfPosition : (pos: number) => LineAndCharacter >pos : number diff --git a/tests/baselines/reference/APISample_watcher.js b/tests/baselines/reference/APISample_watcher.js index 3c11e27f0e1..a5ec8a9a8ab 100644 --- a/tests/baselines/reference/APISample_watcher.js +++ b/tests/baselines/reference/APISample_watcher.js @@ -1631,7 +1631,6 @@ declare module "typescript" { getDocumentationComment(): SymbolDisplayPart[]; } interface SourceFile { - getNamedDeclarations(): Declaration[]; getLineAndCharacterOfPosition(pos: number): LineAndCharacter; getLineStarts(): number[]; getPositionOfLineAndCharacter(line: number, character: number): number; diff --git a/tests/baselines/reference/APISample_watcher.types b/tests/baselines/reference/APISample_watcher.types index f38cdc9b1af..8166244a838 100644 --- a/tests/baselines/reference/APISample_watcher.types +++ b/tests/baselines/reference/APISample_watcher.types @@ -5287,10 +5287,6 @@ declare module "typescript" { interface SourceFile { >SourceFile : SourceFile - getNamedDeclarations(): Declaration[]; ->getNamedDeclarations : () => Declaration[] ->Declaration : Declaration - getLineAndCharacterOfPosition(pos: number): LineAndCharacter; >getLineAndCharacterOfPosition : (pos: number) => LineAndCharacter >pos : number diff --git a/tests/cases/fourslash/navigationItemsOverloads2.ts b/tests/cases/fourslash/navigationItemsOverloads2.ts index 2c33ef65f0d..98908c84e98 100644 --- a/tests/cases/fourslash/navigationItemsOverloads2.ts +++ b/tests/cases/fourslash/navigationItemsOverloads2.ts @@ -8,5 +8,5 @@ ////interface I { //// interfaceMethodSignature(b: boolean): boolean; ////} - +debugger; verify.navigationItemsListCount(2, "interfaceMethodSignature", "exact"); diff --git a/tests/cases/fourslash/navigationItemsOverloadsBroken1.ts b/tests/cases/fourslash/navigationItemsOverloadsBroken1.ts index d2a9ec8e25f..21b7d33dd41 100644 --- a/tests/cases/fourslash/navigationItemsOverloadsBroken1.ts +++ b/tests/cases/fourslash/navigationItemsOverloadsBroken1.ts @@ -4,7 +4,7 @@ ////function overload1(b: boolean): boolean; ////function overload1(b: number): boolean; //// -////var heyImNotInterruptingAnythingAmI = '?'; +////var x= '?'; //// ////function overload1(f: typeof overload): boolean; ////function overload1(x: any, b = (function overload() { return false })): boolean { @@ -15,7 +15,7 @@ ////function overload2(b: boolean): boolean; ////function overload2(b: number): boolean; //// -////function iJustRuinEverything(x: any, b = (function overload() { return false })): boolean { +////function y(x: any, b = (function overload() { return false })): boolean { //// throw overload; ////} //// @@ -24,6 +24,6 @@ //// throw overload; ////} -verify.navigationItemsListCount(2, "overload1", "exact"); -verify.navigationItemsListCount(2, "overload2", "exact"); -verify.navigationItemsListCount(4, "overload", "prefix"); \ No newline at end of file +verify.navigationItemsListCount(1, "overload1", "exact"); +verify.navigationItemsListCount(1, "overload2", "exact"); +verify.navigationItemsListCount(2, "overload", "prefix"); \ No newline at end of file