Skip to content
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

Improve error handling for custom/duplicate decorators #54139

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

pmvald
Copy link
Member

@pmvald pmvald commented Jan 29, 2024

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • angular.io application / infrastructure changes
  • Other... Please describe:

What is the current behavior?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@pmvald pmvald added action: review The PR is still awaiting reviews from at least one requested reviewer area: compiler Issues related to `ngc`, Angular's template compiler target: minor This PR is targeted for the next minor release PullApprove: disable labels Jan 29, 2024
@ngbot ngbot bot modified the milestone: Backlog Jan 29, 2024
@pmvald pmvald force-pushed the orphan-comps branch 3 times, most recently from 90cb601 to 1f3280a Compare January 29, 2024 05:06
@pmvald pmvald changed the title fix(compiler-cli): forbid custom decorator when option `forbidOrphanC… Improve error handling for custom/duplicate decorators Jan 29, 2024
@pmvald
Copy link
Member Author

pmvald commented Jan 29, 2024

TGP link

Comment on lines +754 to +747
if (isCore) {
return decorator.name === 'Injectable';
} else if (decorator.import !== null && decorator.import.from === '@angular/core') {
return decorator.import.name === 'Injectable';
}
Copy link

Choose a reason for hiding this comment

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

I think this is unclear usage. So, it makes harder to find changes for next versions

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure I follow. Can you elaborate please?

Comment on lines +1170 to 1185
semanticDepGraphUpdater, this.adapter, isCore, !!this.options.forbidOrphanComponents);

Copy link

Choose a reason for hiding this comment

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

why we did use magic operator in here?

// reason for both cases is that the `DepsTracker` is not able to understand components mutated
// by decorators. Once the `DepsTracker` is fixed then these issues will be resolved. This issue
// is to be fixed soon (b/320536434).
const unmatchedDecoratorsInLocalMode =
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
const unmatchedDecoratorsInLocalMode =
const unmatchedDecorators =

Regarding "fixing deps tracker". There is no fix we are landing right? except hoping for ES decorators at some point. The comment sound like deps tracker needs a fix.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done!

It is possible to fix this issue. It requires some emit shenanigans to somehow connect a decorated class to its pre-decorated version. I have a solution in mind. We can do this if the number of use cases increases. Right now I'm aware of one app using custom decorators for components (and even that one marked the decorator as deprecated as plan to remove).

Copy link
Member

Choose a reason for hiding this comment

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

I was just curious because of the comment sounding like we intend to allow this in the future again. Maybe remove?

Comment on lines +754 to +747
if (isCore) {
return decorator.name === 'Injectable';
} else if (decorator.import !== null && decorator.import.from === '@angular/core') {
return decorator.import.name === 'Injectable';
}
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure I follow. Can you elaborate please?

…in local compilation diagnostics

For cases like this:

```
@component({...})
@component({...})
export class SomeComp {
}
```

The `DecoratorHandler.detect` apparantly matches only one of the `@Component` decorator, leaving the other undetected which will be transformed by TS decorator helper and that breaks local compilation runtimes. But the error message only mentioned "custom" decorator, while in this case it is a "duplicate Angular" decorator. The respective error message is updated thus.
Copy link
Member

@devversion devversion left a comment

Choose a reason for hiding this comment

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

LGTM, please add merge ready once you think it's ready

…classes in local compilation mode

Custom/duplicate decorators break the deps tracker in local mode. But deps tracker only deals with non-injectable classes. So applying custom/duplicate decorators to `@Injectable` only classes does not disturb deps tracker and local compilation in general. There are also ~ 100 such cases in g3 which cannot be cleaned up.
…bidOrphanComponents` is set

The deps tracker which is responsible to track orphan components does not work for classes mutated by custom decorator. Some work needed to make this happen (tracked in b/320536434). As a result, with option `forbidOrphanComponents` being true the deps tracker will falsely report any component as orphan if it or its NgModule have custom/duplicate decorators. So it is unsafe to use this option in the presence of custom/duplicate decorator and we disable it until it is made compatible. Note that applying custom/duplicate decorators to `@Injectable` classes is ok since these classes never make it into the deps tracker. So we excempt them.
@pmvald pmvald 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 Feb 5, 2024
jessicajaniuk pushed a commit that referenced this pull request Feb 5, 2024
…classes in local compilation mode (#54139)

Custom/duplicate decorators break the deps tracker in local mode. But deps tracker only deals with non-injectable classes. So applying custom/duplicate decorators to `@Injectable` only classes does not disturb deps tracker and local compilation in general. There are also ~ 100 such cases in g3 which cannot be cleaned up.

PR Close #54139
jessicajaniuk pushed a commit that referenced this pull request Feb 5, 2024
…bidOrphanComponents` is set (#54139)

The deps tracker which is responsible to track orphan components does not work for classes mutated by custom decorator. Some work needed to make this happen (tracked in b/320536434). As a result, with option `forbidOrphanComponents` being true the deps tracker will falsely report any component as orphan if it or its NgModule have custom/duplicate decorators. So it is unsafe to use this option in the presence of custom/duplicate decorator and we disable it until it is made compatible. Note that applying custom/duplicate decorators to `@Injectable` classes is ok since these classes never make it into the deps tracker. So we excempt them.

PR Close #54139
@jessicajaniuk
Copy link
Contributor

This PR was merged into the repository by commit 96bcf4f.

jessicajaniuk pushed a commit to jessicajaniuk/angular that referenced this pull request Feb 5, 2024
…ion `forbidOrphanComponents` is set (angular#54139)"

This reverts commit 96bcf4f.
jessicajaniuk pushed a commit to jessicajaniuk/angular that referenced this pull request Feb 5, 2024
jessicajaniuk pushed a commit to jessicajaniuk/angular that referenced this pull request Feb 5, 2024
…orators in local compilation diagnostics (angular#54139)"

This reverts commit 4b1d948.
jessicajaniuk pushed a commit that referenced this pull request Feb 5, 2024
…ion `forbidOrphanComponents` is set (#54139)" (#54264)

This reverts commit 96bcf4f.

PR Close #54264
jessicajaniuk pushed a commit that referenced this pull request Feb 5, 2024
…ectable classes in local compilation mode (#54139)" (#54264)

This reverts commit a592904.

PR Close #54264
jessicajaniuk pushed a commit that referenced this pull request Feb 5, 2024
…orators in local compilation diagnostics (#54139)" (#54264)

This reverts commit 4b1d948.

PR Close #54264
@jessicajaniuk jessicajaniuk reopened this Feb 5, 2024
@jessicajaniuk
Copy link
Contributor

@pmvald This caused a breakage in G3 and has been reverted.

@jessicajaniuk jessicajaniuk added state: blocked action: global presubmit The PR is in need of a google3 global presubmit and removed action: merge The PR is ready for merge by the caretaker PullApprove: disable labels Feb 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
action: global presubmit The PR is in need of a google3 global presubmit area: compiler Issues related to `ngc`, Angular's template compiler state: blocked target: minor This PR is targeted for the next minor release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants