-
Notifications
You must be signed in to change notification settings - Fork 25.9k
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
base: main
Are you sure you want to change the base?
feat(compiler-cli): detect missing structural directive imports #59443
Conversation
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.
LGTM, thanks for the PR.
The diagnostic is named control flow, but might be fine. Also adding @thePunderWoman as the original author IIRC
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? |
|
@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? |
|
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 |
f0b2991 to
9cdc812
Compare
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.
LGTM! Thanks!
|
@manbearwiz It looks like you have legitimate test failures. Can you take a look? |
|
@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. |
|
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 |
|
@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. |
| 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); | ||
| }); | ||
|
|
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.
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
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.
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.
deccfd7 to
988a1be
Compare
…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
…ts (angular#59443)" (angular#59544) This reverts commit ed705a8. PR Close angular#59544
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: #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?
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.