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

feat(compiler-cli): detect missing structural directive imports #59443

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

Conversation

manbearwiz
Copy link
Contributor

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Feature

What is the current behavior?

Issue Number: #37322

Currently, the compiler will warn about missing directive imports if they are one of the "known" structural directives from the CommonModule or use regular binding syntax. This extends that to include custom, user-defined, structural directives. Currently, missing an import for these custom structural directives just fails silently which is a pain point when doing standalone migrations.

What is the new behavior?

The compiler will now warn on missing custom structural directives.

Does this PR introduce a breaking change?

  • Yes
  • No

I made minimal changes and left existing logic in order to ensure the changes are not breaking. I am definitely open to taking another approach, adding more test cases, etc.

@pullapprove pullapprove bot requested a review from devversion January 9, 2025 07:02
@angular-robot angular-robot bot added the detected: feature PR contains a feature commit label Jan 9, 2025
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, thanks for the PR.

The diagnostic is named control flow, but might be fine. Also adding @thePunderWoman as the original author IIRC

@devversion devversion added the action: review The PR is still awaiting reviews from at least one requested reviewer label Jan 9, 2025
@manbearwiz
Copy link
Contributor Author

The diagnostic is named control flow, but might be fine.

Yeah that was one of the things I was unsure about. Would it be better as a separate diagnostic? Would renaming this diagnostic be considered a breaking change?

@thePunderWoman
Copy link
Contributor

@manbearwiz Since this extended diagnostic is specifically about control flow, this seems out of scope to me. I think it would be better to have a separate optional template diagnostic for this since it doesn't apply to everyone. What do you think?

@kirjs kirjs added the area: compiler Issues related to `ngc`, Angular's template compiler label Jan 9, 2025
@ngbot ngbot bot added this to the Backlog milestone Jan 9, 2025
@manbearwiz
Copy link
Contributor Author

manbearwiz commented Jan 9, 2025

That works for me. I'll update it to be a separate diagnostic. Any other suggestions while I'm in there? This will definitely touch a lot more files

@angular-robot angular-robot bot removed the area: compiler Issues related to `ngc`, Angular's template compiler label Jan 9, 2025
@ngbot ngbot bot removed this from the Backlog milestone Jan 9, 2025
@manbearwiz manbearwiz force-pushed the check-missing-structural-directives branch 2 times, most recently from f0b2991 to 9cdc812 Compare January 9, 2025 20:25
@kirjs kirjs added the area: compiler Issues related to `ngc`, Angular's template compiler label Jan 9, 2025
@ngbot ngbot bot added this to the Backlog milestone Jan 9, 2025
@manbearwiz manbearwiz changed the title feat(compiler-cli): detect missing structural directive imports in standalone components feat(compiler-cli): detect missing structural directive imports Jan 9, 2025
@thePunderWoman thePunderWoman added area: compiler-cli area: compiler Issues related to `ngc`, Angular's template compiler target: rc This PR is targeted for the next release-candidate and removed area: compiler Issues related to `ngc`, Angular's template compiler area: compiler-cli labels Jan 10, 2025
Copy link
Contributor

@thePunderWoman thePunderWoman left a comment

Choose a reason for hiding this comment

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

LGTM! Thanks!

@thePunderWoman thePunderWoman added action: presubmit The PR is in need of a google3 presubmit and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Jan 10, 2025
@thePunderWoman
Copy link
Contributor

@manbearwiz It looks like you have legitimate test failures. Can you take a look?

@thePunderWoman thePunderWoman added action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews and removed action: presubmit The PR is in need of a google3 presubmit labels Jan 10, 2025
AndrewKushnir added a commit that referenced this pull request Jan 15, 2025
@AndrewKushnir
Copy link
Contributor

AndrewKushnir commented Jan 15, 2025

@manbearwiz we've reverted this change via #59544, since it broke some targets in Google's codebase. We'll be running some additional tests and let you know what the next steps for this PR are.

@AndrewKushnir AndrewKushnir reopened this Jan 15, 2025
@AndrewKushnir AndrewKushnir added requires: TGP This PR requires a passing TGP before merging is allowed 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 labels Jan 15, 2025
@pullapprove pullapprove bot removed action: global presubmit The PR is in need of a google3 global presubmit requires: TGP This PR requires a passing TGP before merging is allowed labels Jan 15, 2025
@AndrewKushnir AndrewKushnir added state: blocked requires: TGP This PR requires a passing TGP before merging is allowed action: global presubmit The PR is in need of a google3 global presubmit labels Jan 15, 2025
@pullapprove pullapprove bot removed action: global presubmit The PR is in need of a google3 global presubmit requires: TGP This PR requires a passing TGP before merging is allowed labels Jan 15, 2025
@AndrewKushnir AndrewKushnir added PullApprove: disable action: global presubmit The PR is in need of a google3 global presubmit requires: TGP This PR requires a passing TGP before merging is allowed labels Jan 15, 2025
@AndrewKushnir AndrewKushnir self-assigned this Jan 15, 2025
@AndrewKushnir
Copy link
Contributor

Global presubmit.

@manbearwiz
Copy link
Contributor Author

Not sure what the internal tests are, but I took a look to see if I might have missed anything obvious. I did find a case where this check would warn about the same directive as MissingControlFlowDirectiveCheck. I'm guessing it has nothing to do with what you are seeing, but I did push a separate commit with a fix for what I found.

@AndrewKushnir
Copy link
Contributor

@manbearwiz thanks for additional info. I've looked at the broken targets internally and found out that the diagnostic correctly identified cases when directives were not imported, but used in templates. We'd need to do some cleanup internally to fix those cases (~10 instances) and we can try to land this change once again. We'll keep you updated.

Comment on lines +156 to +228
it('should *not* produce a warning when known control flow directives are used', () => {
const fileName = absoluteFrom('/main.ts');
const {program, templateTypeChecker} = setup([
{
fileName,
templates: {
'TestCmp': `<div *ngIf="exp as value">
<li *ngFor="let item of items; index as i; trackBy: trackByFn">
{{ item.name }}
</li>
<container-element [ngSwitch]="switch_exp">
<div *ngSwitchCase="match_exp"></div>
<div *ngSwitchDefault></div>
</container-element>
</div>`,
},
declarations: [
{
name: 'TestCmp',
type: 'directive',
selector: `[test-cmp]`,
isStandalone: true,
},
],
},
]);
const sf = getSourceFileOrError(program, fileName);
const component = getClass(sf, 'TestCmp');
const extendedTemplateChecker = new ExtendedTemplateCheckerImpl(
templateTypeChecker,
program.getTypeChecker(),
[missingStructuralDirectiveCheck],
{strictNullChecks: true} /* options */,
);
const diags = extendedTemplateChecker.getDiagnosticsForComponent(component);
// No diagnostic messages are expected.
expect(diags.length).toBe(0);
});

Copy link
Contributor

Choose a reason for hiding this comment

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

Question: And how about *ngTemplateOutlet like in<ng-container *ngTemplateOutlet="ref"/> ? I have raised a specific issue Enhance compile-time failure accounting for NG0303 (to detect missing NgTemplateOutlet import) as it is the case for NgClass with NG8002 and thus expecting the diagnostic here to handle that as well. My proposal suggests to cover this in the compiler-cli and the docs to mention the new error reference in the Errors Encyclopedia on ADEV. I'll try to find some time to look again at the PR, but please let me know if you are (planning to) cover(ing) it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good call out. I was able to confirm that existing diagnostics do not warn about this directive, but this new diagnostic will.

▲ [WARNING] NG8114: An unknown structural directive `ngTemplateOutlet` was used in the template, without a corresponding import in the component. Make sure that the directive is included in the `@Component.imports` array of this component. [plugin angular-compiler]

    src/app/app.component.html:314:23:
      314 │         <ng-container *ngTemplateOutlet="svk; context: myContext"...
          ╵                        ~~~~~~~~~~~~~~~~

  Error occurs in the template of component AppComponent.

    src/app/app.component.ts:21:15:
      21 │   templateUrl: './app.component.html',

I will add a test case to explicitly cover this.

Add `ngForOf` and `ngForTrackBy` to the filter for the `MissingStructuralDirectiveCheck`. Previously, a standalone component using an `ngForTrackBy` directive without the `NgFor` import would be warned by both  `MissingStructuralDirectiveCheck` and `MissingControlFlowDirectiveCheck`.

Add a test case for this scenario and to ensure correct warning for a missing ngTemplateOutlet directive.
@manbearwiz manbearwiz force-pushed the check-missing-structural-directives branch from deccfd7 to 988a1be Compare January 19, 2025 06:21
PrajaktaB27 pushed a commit to PrajaktaB27/angular that referenced this pull request Feb 7, 2025
…lar#59443)

Adds a new diagnostic that ensures that a standalone component using custom structural directives in a template has the necessary imports for those directives.

Fixes angular#37322

PR Close angular#59443
PrajaktaB27 pushed a commit to PrajaktaB27/angular that referenced this pull request Feb 7, 2025
@AndrewKushnir AndrewKushnir modified the milestones: Backlog, v20 candidates Feb 20, 2025
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 detected: feature PR contains a feature commit PullApprove: disable requires: TGP This PR requires a passing TGP before merging is allowed 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.

8 participants