-
Notifications
You must be signed in to change notification settings - Fork 27k
fix(language-service): Support to resolve the re-export component. #62585
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
Conversation
5ba6e32 to
68a6b85
Compare
|
@atscott Take a look when you have time. |
68a6b85 to
e771902
Compare
|
/gemini review |
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.
Code Review
This pull request updates the language service to correctly handle re-exported components by resolving the most recent re-export. The changes involve modifying how module specifiers are resolved to include the export name, and using the TypeScript type checker to identify aliased symbols. The implementation looks solid and includes a good test case. I've found a few areas for improvement, mainly around documentation clarity and code duplication, including one high-severity issue with an incorrect example in a comment.
| const sf = program.getSourceFile(tsEntry.tsCompletionEntrySymbolFileName); | ||
| if (sf === undefined) { | ||
| return false; | ||
| } | ||
| const sfSymbol = typeChecker.getSymbolAtLocation(sf); | ||
| if (sfSymbol === undefined) { | ||
| return false; | ||
| } | ||
| const tsEntrySymbol = typeChecker.tryGetMemberInModuleExports( | ||
| tsEntry.tsCompletionEntrySymbolName, | ||
| sfSymbol, | ||
| ); | ||
| if (tsEntrySymbol === undefined) { | ||
| return false; | ||
| } | ||
| const tsEntryType = typeChecker.getTypeOfSymbol(tsEntrySymbol); | ||
| return tsEntryType.symbol?.declarations?.[0] === toImport.node; | ||
| }); | ||
| } |
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.
This block of code for resolving a symbol from TsCompletionEntryInfo is very similar to the new getSymbolFromTsEntryInfo function in packages/compiler-cli/src/ngtsc/typecheck/src/checker.ts. To improve maintainability and avoid code duplication, consider refactoring this logic into a shared utility function that can be used in both places. If getSymbolFromTsEntryInfo can be exported from checker.ts (or a shared file) and used here, that would be ideal.
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.
Exporting the getSymbolFromTsEntryInfo function from checker.ts is not the correct approach. Allowing code duplication is acceptable.
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.
I'll refactor this if there is a better approach.
e771902 to
2fc2f52
Compare
atscott
left a comment
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.
Generally LGTM. Unless I'm misunderstanding, I think there might be some risk of always preferring the alias. When working within a package directory, the original definition might be preferable to the alias? That said, if we're only ever allowing one completion item, then we have to make a choice and likely the alias is the one we want most of the time?
2fc2f52 to
38e106b
Compare
38e106b to
a82d174
Compare
| * Make sure these are the same node. | ||
| */ | ||
| if (toImportSymbolFromModule?.declarations?.[0] === toImport) { | ||
| if (symbolType.getSymbol()?.declarations?.[0] === toImport) { |
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.
Use type declaration to check with toImport, the symbol may be an alias of toImport.
| }) | ||
| class BazComponent {} | ||
| export {BarComponent, BazComponent}; |
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.
Add a test case for the new change.
|
Just in case you forget about this PR. |
In the context of TypeScript (TS), a re-exported symbol is considered a distinct symbol. This means that a developer can choose to import either the re-exported symbol or the original symbol. However, in the context of Angular, the re-exported symbol is treated as the same component because it uses the same selector. This pull request will utilize the most recent re-export component file to resolve the module specifier.
a82d174 to
1c863d7
Compare
…62585) In the context of TypeScript (TS), a re-exported symbol is considered a distinct symbol. This means that a developer can choose to import either the re-exported symbol or the original symbol. However, in the context of Angular, the re-exported symbol is treated as the same component because it uses the same selector. This pull request will utilize the most recent re-export component file to resolve the module specifier. PR Close #62585
|
This PR was merged into the repository by commit eeeaadc. The changes were merged into the following branches: main, 20.2.x |
|
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |


In the context of TypeScript (TS), a re-exported symbol is considered a distinct symbol.
This means that a developer can choose to import either the re-exported symbol or
the original symbol. However, in the context of Angular, the re-exported symbol
is treated as the same component because it uses the same selector.
This pull request will utilize the most recent re-export component file to
resolve the module specifier.
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
Issue Number: N/A
What is the new behavior?
Does this PR introduce a breaking change?
Other information