Skip to content

fix(compiler-cli): report when NgModule imports or exports itself #58231

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

Closed
wants to merge 2 commits into from

Conversation

crisbeto
Copy link
Member

Reports a diagnostic if an NgModule refers to itself in its imports or exports. Previously the compiler would go into an infinite loop.

Fixes #58224.

@crisbeto crisbeto added action: review The PR is still awaiting reviews from at least one requested reviewer target: patch This PR is targeted for the next patch release area: compiler Issues related to `ngc`, Angular's template compiler labels Oct 16, 2024
@crisbeto crisbeto requested a review from JoostK October 16, 2024 19:11
@ngbot ngbot bot modified the milestone: Backlog Oct 16, 2024
@angular-robot angular-robot bot removed the area: compiler Issues related to `ngc`, Angular's template compiler label Oct 16, 2024
@ngbot ngbot bot removed this from the Backlog milestone Oct 16, 2024
if (decl.node === ref.node) {
diagnostics.push(
makeDiagnostic(
ErrorCode.NGMODULE_INVALID_IMPORT,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was on the fence whether to introduce a new error code or reuse the existing one.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think having just one code is fine.

@crisbeto crisbeto force-pushed the 58224/ng-module-self-import branch from f8c7388 to 9608a03 Compare October 16, 2024 19:42
Copy link
Member

@JoostK JoostK left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was contemplating whether situations like the following would work correctly:

A > B > C
    ^---/

as then the cycle would still infinitely recurse when lookupRoot is A, but a quick test didn't show this failure mode.

We could avoid that potential problem by inserting a sentinel value into the cache prior to recursing, such that any cycle can be detected by asserting that the cache entry is not set to the cycle sentinel.

if (decl.node === ref.node) {
diagnostics.push(
makeDiagnostic(
ErrorCode.NGMODULE_INVALID_IMPORT,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think having just one code is fine.

@crisbeto
Copy link
Member Author

I don't quite follow the A > B > C example. In this case does C depend back on A?

@JoostK
Copy link
Member

JoostK commented Oct 17, 2024

I don't quite follow the A > B > C example. In this case does C depend back on A?

No, just C depending on B.

@NgModule({ imports: [forwardRef(() => ModB)] })
class ModC {}

@NgModule({ imports: [ModC] })
class ModB {}

@NgModule({ imports: [ModB] })
class ModA {}

(I haven't attempted with the exact code as above, only with NgModules across different modules).

The problem won't be observed if the scope of either ModB or ModC is requested before that of ModA, but if ModA is the first to kick of all others then ModB and ModC won't consider themselves to be part of a cycle, as lookupRoot would be ModA.

So perhaps a repro might be (haven't tested):

@NgModule({ imports: [forwardRef(() => ModB)] })
class ModA {}

@NgModule({ imports: [forwardRef(() => ModC)] })
class ModB {}

@NgModule({ imports: [ModB] })
class ModC {}

Reports a diagnostic if an NgModule refers to itself in its `imports` or `exports`. Previously the compiler would go into an infinite loop.

Fixes angular#58224.
@crisbeto crisbeto force-pushed the 58224/ng-module-self-import branch from 9608a03 to 071df45 Compare October 17, 2024 19:15
@crisbeto
Copy link
Member Author

Ah, well spotted 👍 I've pushed a fixup commit.

@crisbeto crisbeto added action: merge The PR is ready for merge by the caretaker and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Oct 17, 2024
@devversion
Copy link
Member

This PR was merged into the repository by commit d0c74f3.

The changes were merged into the following branches: main, 18.2.x

devversion pushed a commit that referenced this pull request Oct 18, 2024
…8231)

Reports a diagnostic if an NgModule refers to itself in its `imports` or `exports`. Previously the compiler would go into an infinite loop.

Fixes #58224.

PR Close #58231
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Nov 18, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker target: patch This PR is targeted for the next patch release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Stack overflow in Angular Compiler if an NgModule imports itself
3 participants