-
Notifications
You must be signed in to change notification settings - Fork 13k
Find references in importing modules for members of export =
ed symbols
#62428
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
base: main
Are you sure you want to change the base?
Changes from all commits
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 |
---|---|---|
|
@@ -21,6 +21,7 @@ import { | |
getNameOfAccessExpression, | ||
getSourceFileOfNode, | ||
getSymbolId, | ||
getSymbolTarget, | ||
hasSyntacticModifier, | ||
Identifier, | ||
ImportCall, | ||
|
@@ -635,6 +636,16 @@ export function getImportOrExportSymbol(node: Node, symbol: Symbol, checker: Typ | |
else if (isJSDocTypedefTag(parent) || isJSDocCallbackTag(parent)) { | ||
return exportInfo(symbol, ExportKind.Named); | ||
} | ||
else { | ||
const sourceFile = getSourceFileOfNode(node); | ||
if (sourceFile.symbol?.exports?.has(InternalSymbolName.ExportEquals)) { | ||
const moduleSymbol = checker.resolveExternalModuleSymbol(sourceFile.symbol); | ||
if (moduleSymbol && (moduleSymbol === symbol.parent || some(checker.getPropertiesOfType(checker.getTypeOfSymbol(moduleSymbol)), s => getSymbolTarget(s, checker) === symbol))) { | ||
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. I'm open to suggestions how to improve
This comment was marked as spam.
Sorry, something went wrong. |
||
const exportInfo = { exportingModuleSymbol: sourceFile.symbol, exportKind: ExportKind.Named }; | ||
return { kind: ImportExport.Export, symbol, exportInfo }; | ||
} | ||
} | ||
} | ||
} | ||
|
||
function getExportAssignmentExport(ex: ExportAssignment): ExportedSymbol | undefined { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
// === findAllReferences === | ||
// === /mod.ts === | ||
// class Cls { | ||
// /*FIND ALL REFS*/<|[|{| isWriteAccess: true, isDefinition: true |}foo|]() {}|> | ||
// }; | ||
// | ||
// export default new Cls(); | ||
|
||
// === /index.ts === | ||
// import def from "./mod" | ||
// def.[|foo|](); | ||
|
||
// === Definitions === | ||
// === /mod.ts === | ||
// class Cls { | ||
// /*FIND ALL REFS*/<|[|foo|]() {}|> | ||
// }; | ||
// | ||
// export default new Cls(); | ||
|
||
// === Details === | ||
[ | ||
{ | ||
"containerKind": "", | ||
"containerName": "", | ||
"kind": "method", | ||
"name": "(method) Cls.foo(): void", | ||
"displayParts": [ | ||
{ | ||
"text": "(", | ||
"kind": "punctuation" | ||
}, | ||
{ | ||
"text": "method", | ||
"kind": "text" | ||
}, | ||
{ | ||
"text": ")", | ||
"kind": "punctuation" | ||
}, | ||
{ | ||
"text": " ", | ||
"kind": "space" | ||
}, | ||
{ | ||
"text": "Cls", | ||
"kind": "className" | ||
}, | ||
{ | ||
"text": ".", | ||
"kind": "punctuation" | ||
}, | ||
{ | ||
"text": "foo", | ||
"kind": "methodName" | ||
}, | ||
{ | ||
"text": "(", | ||
"kind": "punctuation" | ||
}, | ||
{ | ||
"text": ")", | ||
"kind": "punctuation" | ||
}, | ||
{ | ||
"text": ":", | ||
"kind": "punctuation" | ||
}, | ||
{ | ||
"text": " ", | ||
"kind": "space" | ||
}, | ||
{ | ||
"text": "void", | ||
"kind": "keyword" | ||
} | ||
] | ||
} | ||
] | ||
|
||
|
||
|
||
// === findAllReferences === | ||
// === /mod.ts === | ||
// class Cls { | ||
// <|[|{| isWriteAccess: true |}foo|]() {}|> | ||
// }; | ||
// | ||
// export default new Cls(); | ||
|
||
// === /index.ts === | ||
// import def from "./mod" | ||
// def.[|foo|]/*FIND ALL REFS*/(); | ||
|
||
// === Definitions === | ||
// === /mod.ts === | ||
// class Cls { | ||
// <|[|foo|]() {}|> | ||
// }; | ||
// | ||
// export default new Cls(); | ||
|
||
// === Details === | ||
[ | ||
{ | ||
"containerKind": "", | ||
"containerName": "", | ||
"kind": "method", | ||
"name": "(method) Cls.foo(): void", | ||
"displayParts": [ | ||
{ | ||
"text": "(", | ||
"kind": "punctuation" | ||
}, | ||
{ | ||
"text": "method", | ||
"kind": "text" | ||
}, | ||
{ | ||
"text": ")", | ||
"kind": "punctuation" | ||
}, | ||
{ | ||
"text": " ", | ||
"kind": "space" | ||
}, | ||
{ | ||
"text": "Cls", | ||
"kind": "className" | ||
}, | ||
{ | ||
"text": ".", | ||
"kind": "punctuation" | ||
}, | ||
{ | ||
"text": "foo", | ||
"kind": "methodName" | ||
}, | ||
{ | ||
"text": "(", | ||
"kind": "punctuation" | ||
}, | ||
{ | ||
"text": ")", | ||
"kind": "punctuation" | ||
}, | ||
{ | ||
"text": ":", | ||
"kind": "punctuation" | ||
}, | ||
{ | ||
"text": " ", | ||
"kind": "space" | ||
}, | ||
{ | ||
"text": "void", | ||
"kind": "keyword" | ||
} | ||
] | ||
} | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
// === findAllReferences === | ||
// === /mod.d.ts === | ||
// export default React; | ||
// | ||
// declare namespace React { | ||
// <|function /*FIND ALL REFS*/[|{| isWriteAccess: true, isDefinition: true |}lazy|](): void;|> | ||
// } | ||
|
||
// === /index.ts === | ||
// import def from "./mod" | ||
// def.[|lazy|](); | ||
|
||
// === Definitions === | ||
// === /mod.d.ts === | ||
// export default React; | ||
// | ||
// declare namespace React { | ||
// <|function /*FIND ALL REFS*/[|lazy|](): void;|> | ||
// } | ||
|
||
// === Details === | ||
[ | ||
{ | ||
"containerKind": "", | ||
"containerName": "", | ||
"kind": "function", | ||
"name": "function React.lazy(): void", | ||
"displayParts": [ | ||
{ | ||
"text": "function", | ||
"kind": "keyword" | ||
}, | ||
{ | ||
"text": " ", | ||
"kind": "space" | ||
}, | ||
{ | ||
"text": "React", | ||
"kind": "moduleName" | ||
}, | ||
{ | ||
"text": ".", | ||
"kind": "punctuation" | ||
}, | ||
{ | ||
"text": "lazy", | ||
"kind": "functionName" | ||
}, | ||
{ | ||
"text": "(", | ||
"kind": "punctuation" | ||
}, | ||
{ | ||
"text": ")", | ||
"kind": "punctuation" | ||
}, | ||
{ | ||
"text": ":", | ||
"kind": "punctuation" | ||
}, | ||
{ | ||
"text": " ", | ||
"kind": "space" | ||
}, | ||
{ | ||
"text": "void", | ||
"kind": "keyword" | ||
} | ||
] | ||
} | ||
] | ||
|
||
|
||
|
||
// === findAllReferences === | ||
// === /mod.d.ts === | ||
// export default React; | ||
// | ||
// declare namespace React { | ||
// <|function [|{| isWriteAccess: true |}lazy|](): void;|> | ||
// } | ||
|
||
// === /index.ts === | ||
// import def from "./mod" | ||
// def.[|lazy|]/*FIND ALL REFS*/(); | ||
|
||
// === Definitions === | ||
// === /mod.d.ts === | ||
// export default React; | ||
// | ||
// declare namespace React { | ||
// <|function [|lazy|](): void;|> | ||
// } | ||
|
||
// === Details === | ||
[ | ||
{ | ||
"containerKind": "", | ||
"containerName": "", | ||
"kind": "function", | ||
"name": "function React.lazy(): void", | ||
"displayParts": [ | ||
{ | ||
"text": "function", | ||
"kind": "keyword" | ||
}, | ||
{ | ||
"text": " ", | ||
"kind": "space" | ||
}, | ||
{ | ||
"text": "React", | ||
"kind": "moduleName" | ||
}, | ||
{ | ||
"text": ".", | ||
"kind": "punctuation" | ||
}, | ||
{ | ||
"text": "lazy", | ||
"kind": "functionName" | ||
}, | ||
{ | ||
"text": "(", | ||
"kind": "punctuation" | ||
}, | ||
{ | ||
"text": ")", | ||
"kind": "punctuation" | ||
}, | ||
{ | ||
"text": ":", | ||
"kind": "punctuation" | ||
}, | ||
{ | ||
"text": " ", | ||
"kind": "space" | ||
}, | ||
{ | ||
"text": "void", | ||
"kind": "keyword" | ||
} | ||
] | ||
} | ||
] |
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.
It turns out that the added
checker.resolveExternalModuleSymbol
call triggered a symbol merge. And that broke this test case (tests/cases/fourslash/renameExportCrash.ts
):allSearchSymbols
(the state was created first)resolveExternalModuleSymbol -> getCommonJsExportEquals -> cloneSymbol -> recordMergedSymbol
)state.checker.getSymbolAtLocation(referenceLocation)
called bygetReferencesAtLocation
found the merged symbol throughresolveEntityName -> resolveNameHelper -> result = lookup(location.locals, name, meaning) -> getSymbol -> getMergedSymbol
includes
was called with that merged symbolSo it seems this was always prone to issues with lazily-merged symbols and comparing merged symbols of both looks like a reasonable solution to me.