-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Skip past module.exports = { Foo }
in go-to-defintion on 'Foo'
#40835
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
698965f
5b986f8
2e25d90
687a662
f07771c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -92,9 +92,16 @@ namespace ts.GoToDefinition { | |
getDefinitionFromSymbol(typeChecker, propertySymbol, node)); | ||
} | ||
} | ||
|
||
return getDefinitionFromSymbol(typeChecker, symbol, node); | ||
} | ||
|
||
function isShorthandPropertyAssignmentOfModuleExports(symbol: Symbol): boolean { | ||
const shorthandProperty = tryCast(symbol.valueDeclaration, isShorthandPropertyAssignment); | ||
const binaryExpression = tryCast(shorthandProperty?.parent.parent, isAssignmentExpression); | ||
return !!binaryExpression && getAssignmentDeclarationKind(binaryExpression) === AssignmentDeclarationKind.ModuleExports; | ||
} | ||
|
||
/** | ||
* True if we should not add definitions for both the signature symbol and the definition symbol. | ||
* True for `const |f = |() => 0`, false for `function |f() {} const |g = f;`. | ||
|
@@ -197,15 +204,29 @@ namespace ts.GoToDefinition { | |
} | ||
|
||
function getSymbol(node: Node, checker: TypeChecker): Symbol | undefined { | ||
const symbol = checker.getSymbolAtLocation(node); | ||
let symbol = checker.getSymbolAtLocation(node); | ||
// If this is an alias, and the request came at the declaration location | ||
// get the aliased symbol instead. This allows for goto def on an import e.g. | ||
// import {A, B} from "mod"; | ||
// to jump to the implementation directly. | ||
if (symbol && symbol.flags & SymbolFlags.Alias && shouldSkipAlias(node, symbol.declarations[0])) { | ||
const aliased = checker.getAliasedSymbol(symbol); | ||
if (aliased.declarations) { | ||
return aliased; | ||
while (symbol) { | ||
if (symbol.flags & SymbolFlags.Alias && shouldSkipAlias(node, symbol.declarations[0])) { | ||
const aliased = checker.getAliasedSymbol(symbol); | ||
if (!aliased.declarations) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. when does this happen? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is just the converse of the previous code, but I think it could happen in certain error cases where the checker falls back to |
||
break; | ||
} | ||
symbol = aliased; | ||
} | ||
else if (isShorthandPropertyAssignmentOfModuleExports(symbol)) { | ||
// Skip past `module.exports = { Foo }` even though 'Foo' is not a real alias | ||
const shorthandTarget = checker.resolveName(symbol.name, symbol.valueDeclaration, SymbolFlags.Value, /*excludeGlobals*/ false); | ||
if (!some(shorthandTarget?.declarations)) { | ||
break; | ||
} | ||
symbol = shorthandTarget; | ||
} | ||
else { | ||
break; | ||
} | ||
} | ||
return symbol; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/// <reference path="fourslash.ts" /> | ||
|
||
// @allowJs: true | ||
|
||
// @Filename: util.js | ||
//// class /*2*/Util {} | ||
//// module.exports = { Util }; | ||
|
||
// @Filename: index.js | ||
//// const { Util } = require('./util'); | ||
//// new [|Util/*1*/|]() | ||
|
||
verify.goToDefinition("1", "2"); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/// <reference path="fourslash.ts" /> | ||
|
||
// @allowJs: true | ||
|
||
// @Filename: util.js | ||
//// class /*2*/Util {} | ||
//// module.exports = { Util }; | ||
|
||
// @Filename: reexport.js | ||
//// const { Util } = require('./util'); | ||
//// module.exports = { Util }; | ||
|
||
// @Filename: index.js | ||
//// const { Util } = require('./reexport'); | ||
//// new [|Util/*1*/|]() | ||
|
||
verify.goToDefinition("1", "2"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
look to see colour markup in error messages