From 7474bdcaa2a5b3ace25d4c10d3f23fb085f0a70e Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 27 Aug 2019 15:44:56 -0700 Subject: [PATCH 1/3] goto-def:special handling for constructor functions --- src/services/goToDefinition.ts | 7 +++++++ .../gotoDefinitionConstructorFunction.ts | 15 +++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 tests/cases/fourslash/gotoDefinitionConstructorFunction.ts diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index e514ca01e7947..a1477afd7678f 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -242,6 +242,13 @@ namespace ts.GoToDefinition { // Applicable only if we are in a new expression, or we are on a constructor declaration // and in either case the symbol has a construct signature definition, i.e. class if (symbol.flags & SymbolFlags.Class && (isNewExpressionTarget(node) || node.kind === SyntaxKind.ConstructorKeyword)) { + if (symbol.flags & SymbolFlags.Function) { + // constructor functions + const func = find(filteredDeclarations, decl => isFunctionDeclaration(decl) || isFunctionExpression(decl)); + if (func) { + return getSignatureDefinition([func], /*selectConstructors*/ false); + } + } const cls = find(filteredDeclarations, isClassLike) || Debug.fail("Expected declaration to have at least one class-like declaration"); return getSignatureDefinition(cls.members, /*selectConstructors*/ true); } diff --git a/tests/cases/fourslash/gotoDefinitionConstructorFunction.ts b/tests/cases/fourslash/gotoDefinitionConstructorFunction.ts new file mode 100644 index 0000000000000..aa149e70d7dc4 --- /dev/null +++ b/tests/cases/fourslash/gotoDefinitionConstructorFunction.ts @@ -0,0 +1,15 @@ +/// +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @filename: gotoDefinitionConstructorFunction.js +//// function /*end*/StringStreamm() { +//// } +//// StringStreamm.prototype = { +//// }; +//// +//// function runMode () { +//// new [|/*start*/StringStreamm|]() +//// }; + +verify.goToDefinition('start', 'end') From 49938f5f2f6524f5d57632734fc7db54065b17ca Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 27 Aug 2019 16:02:52 -0700 Subject: [PATCH 2/3] Just treat constructor functions like functions --- src/services/goToDefinition.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index a1477afd7678f..388cfe494ed5f 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -243,11 +243,8 @@ namespace ts.GoToDefinition { // and in either case the symbol has a construct signature definition, i.e. class if (symbol.flags & SymbolFlags.Class && (isNewExpressionTarget(node) || node.kind === SyntaxKind.ConstructorKeyword)) { if (symbol.flags & SymbolFlags.Function) { - // constructor functions - const func = find(filteredDeclarations, decl => isFunctionDeclaration(decl) || isFunctionExpression(decl)); - if (func) { - return getSignatureDefinition([func], /*selectConstructors*/ false); - } + // constructor functions are just call signatures + return undefined; } const cls = find(filteredDeclarations, isClassLike) || Debug.fail("Expected declaration to have at least one class-like declaration"); return getSignatureDefinition(cls.members, /*selectConstructors*/ true); From cba2ba29db2de72e3da60071796f9c59cce52138 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 27 Aug 2019 16:04:57 -0700 Subject: [PATCH 3/3] Even simpler fallback --- src/services/goToDefinition.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 388cfe494ed5f..22d28efd2f4e0 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -241,11 +241,7 @@ namespace ts.GoToDefinition { function getConstructSignatureDefinition(): DefinitionInfo[] | undefined { // Applicable only if we are in a new expression, or we are on a constructor declaration // and in either case the symbol has a construct signature definition, i.e. class - if (symbol.flags & SymbolFlags.Class && (isNewExpressionTarget(node) || node.kind === SyntaxKind.ConstructorKeyword)) { - if (symbol.flags & SymbolFlags.Function) { - // constructor functions are just call signatures - return undefined; - } + if (symbol.flags & SymbolFlags.Class && !(symbol.flags & SymbolFlags.Function) && (isNewExpressionTarget(node) || node.kind === SyntaxKind.ConstructorKeyword)) { const cls = find(filteredDeclarations, isClassLike) || Debug.fail("Expected declaration to have at least one class-like declaration"); return getSignatureDefinition(cls.members, /*selectConstructors*/ true); }