From 782275924fbb6ae3cee4fdea1c445a3b2372d7fb Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 1 Oct 2014 18:51:58 -0700 Subject: [PATCH] Only show first overload in a series of consecutive overload signatures for navigateTo --- src/services/services.ts | 32 +++++++++++++++---- .../fourslash/navigationItemsOverloads1.ts | 30 +++++++++++++++++ .../fourslash/navigationItemsOverloads2.ts | 12 +++++++ .../navigationItemsOverloadsBroken.ts | 29 +++++++++++++++++ 4 files changed, 96 insertions(+), 7 deletions(-) create mode 100644 tests/cases/fourslash/navigationItemsOverloads1.ts create mode 100644 tests/cases/fourslash/navigationItemsOverloads2.ts create mode 100644 tests/cases/fourslash/navigationItemsOverloadsBroken.ts diff --git a/src/services/services.ts b/src/services/services.ts index a35c1213956..a7a3b43afd1 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -504,17 +504,36 @@ module ts { if (!this.namedDeclarations) { var sourceFile = this; var namedDeclarations: Declaration[] = []; - var isExternalModule = ts.isExternalModule(sourceFile); + + // This keeps track of the last encountered function/method/method signature + // so that we may ignore all but the first overload. + var overloadDeclaration: FunctionDeclaration; forEachChild(sourceFile, function visit(node: Node): boolean { switch (node.kind) { + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.Method: + var functionDeclaration = node; + + // We can assume that overloadDeclaration will never be "trampled" + // between consecutive overloads because we never dive into parameter initializers. + if (functionDeclaration.name) { + if (overloadDeclaration && + functionDeclaration.name.text === overloadDeclaration.name.text && + node.parent === overloadDeclaration.parent) { + break; + } + + namedDeclarations.push(functionDeclaration); + overloadDeclaration = functionDeclaration; + } + break; + case SyntaxKind.ClassDeclaration: case SyntaxKind.InterfaceDeclaration: case SyntaxKind.EnumDeclaration: case SyntaxKind.ModuleDeclaration: case SyntaxKind.ImportDeclaration: - case SyntaxKind.Method: - case SyntaxKind.FunctionDeclaration: case SyntaxKind.Constructor: case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: @@ -522,9 +541,7 @@ module ts { if ((node).name) { namedDeclarations.push(node); } - forEachChild(node, visit); - break; - + // fall through case SyntaxKind.VariableStatement: case SyntaxKind.ModuleBlock: case SyntaxKind.FunctionBlock: @@ -532,10 +549,11 @@ module ts { break; case SyntaxKind.Parameter: + // Only consider properties defined as constructor parameters if (!(node.flags & NodeFlags.AccessibilityModifier)) { - // Only consider properties defined as constructor parameters break; } + // fall through case SyntaxKind.VariableDeclaration: case SyntaxKind.EnumMember: case SyntaxKind.Property: diff --git a/tests/cases/fourslash/navigationItemsOverloads1.ts b/tests/cases/fourslash/navigationItemsOverloads1.ts new file mode 100644 index 00000000000..5f1981fe917 --- /dev/null +++ b/tests/cases/fourslash/navigationItemsOverloads1.ts @@ -0,0 +1,30 @@ +/// + +////function overload(a: string): boolean; +////function overload(b: boolean): boolean; +////function overload(b: number): boolean; +////function overload(f: typeof overload): boolean; +////function overload(x: any, b = (function overload() { return false })): boolean { +//// throw overload; +////} +//// +////interface I { +//// interfaceMethodSignature(a: string): boolean; +//// interfaceMethodSignature(b: boolean): boolean; +//// interfaceMethodSignature(b: number): boolean; +//// interfaceMethodSignature(f: I): boolean; +////} +//// +////class C { +//// methodOverload(a: string): boolean; +//// methodOverload(b: boolean): boolean; +//// methodOverload(b: number): boolean; +//// methodOverload(f: I): boolean; +//// methodOverload(x: any, b = (function overload() { return false })): boolean { +//// throw C; +//// } +////} + +verify.navigationItemsListCount(1, "overload", "exact"); +verify.navigationItemsListCount(1, "interfaceMethodSignature", "exact"); +verify.navigationItemsListCount(1, "methodOverload", "exact"); diff --git a/tests/cases/fourslash/navigationItemsOverloads2.ts b/tests/cases/fourslash/navigationItemsOverloads2.ts new file mode 100644 index 00000000000..c5824b639bc --- /dev/null +++ b/tests/cases/fourslash/navigationItemsOverloads2.ts @@ -0,0 +1,12 @@ +/// + +////interface I { +//// interfaceMethodSignature(a: string): boolean; +//// interfaceMethodSignature(b: number): boolean; +//// interfaceMethodSignature(f: I): boolean; +////} +////interface I { +//// interfaceMethodSignature(b: boolean): boolean; +////} + +verify.navigationItemsListCount(2, "interfaceMethodSignature", "exact"); diff --git a/tests/cases/fourslash/navigationItemsOverloadsBroken.ts b/tests/cases/fourslash/navigationItemsOverloadsBroken.ts new file mode 100644 index 00000000000..f9501948272 --- /dev/null +++ b/tests/cases/fourslash/navigationItemsOverloadsBroken.ts @@ -0,0 +1,29 @@ +/// + +////function overload1(a: string): boolean; +////function overload1(b: boolean): boolean; +////function overload1(b: number): boolean; +//// +////var heyImNotInterruptingAnythingAmI = '?'; +//// +////function overload1(f: typeof overload): boolean; +////function overload1(x: any, b = (function overload() { return false })): boolean { +//// throw overload; +////} + +////function overload2(a: string): boolean; +////function overload2(b: boolean): boolean; +////function overload2(b: number): boolean; +//// +////function iJustRuinEverything(x: any, b = (function overload() { return false })): boolean { +//// throw overload; +////} +//// +////function overload2(f: typeof overload): boolean; +////function overload2(x: any, b = (function overload() { return false })): boolean { +//// throw overload; +////} + +verify.navigationItemsListCount(1, "overload1", "exact"); +verify.navigationItemsListCount(2, "overload2", "exact"); +verify.navigationItemsListCount(3, "overload", "prefix"); \ No newline at end of file