diff --git a/packages/compiler-cli/src/ngtsc/typecheck/extended/checks/missing_control_flow_directive/index.ts b/packages/compiler-cli/src/ngtsc/typecheck/extended/checks/missing_control_flow_directive/index.ts index 8bd0088523c08e..56b11237fbd49b 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/extended/checks/missing_control_flow_directive/index.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/extended/checks/missing_control_flow_directive/index.ts @@ -15,14 +15,18 @@ import {NgTemplateDiagnostic} from '../../../api'; import {TemplateCheckFactory, TemplateCheckWithVisitor, TemplateContext} from '../../api'; /** - * The list of known control flow directives present in the `CommonModule`. + * The list of known control flow directives present in the `CommonModule`, + * and their corresponding imports. * * Note: there is no `ngSwitch` here since it's typically used as a regular * binding (e.g. `[ngSwitch]`), however the `ngSwitchCase` and `ngSwitchDefault` * are used as structural directives and a warning would be generated. Once the * `CommonModule` is included, the `ngSwitch` would also be covered. */ -const KNOWN_CONTROL_FLOW_DIRECTIVES = new Set(['ngIf', 'ngFor', 'ngSwitchCase', 'ngSwitchDefault']); +const KNOWN_CONTROL_FLOW_DIRECTIVES = new Map([ + ['ngIf', 'NgIf'], ['ngFor', 'NgForOf'], ['ngSwitchCase', 'NgSwitchCase'], + ['ngSwitchDefault', 'NgSwitchDefault'] +]); /** * Ensures that there are no known control flow directives (such as *ngIf and *ngFor) @@ -64,9 +68,13 @@ class MissingControlFlowDirectiveCheck extends } const sourceSpan = controlFlowAttr.keySpan || controlFlowAttr.sourceSpan; - const errorMessage = `The \`*${controlFlowAttr.name}\` directive was used in the template, ` + - `but the \`CommonModule\` was not imported. Please make sure that the \`CommonModule\` ` + - `is included into the \`@Component.imports\` array of this component.`; + const correspondingImport = KNOWN_CONTROL_FLOW_DIRECTIVES.get(controlFlowAttr.name); + const errorMessage = + `The \`*${controlFlowAttr.name}\` directive was used in the template, ` + + `but the \`*${ + correspondingImport}\` directive or the \`CommonModule\` were not imported. ` + + `Please make sure that the \`*${correspondingImport}\` directive or the \`CommonModule\` ` + + `are included in the \`@Component.imports\` array of this component.`; const diagnostic = ctx.makeTemplateDiagnostic(sourceSpan, errorMessage); return [diagnostic]; } diff --git a/packages/compiler-cli/src/ngtsc/typecheck/extended/test/checks/missing_control_flow_directive/missing_control_flow_directive_spec.ts b/packages/compiler-cli/src/ngtsc/typecheck/extended/test/checks/missing_control_flow_directive/missing_control_flow_directive_spec.ts index c8fe7e4c406d6d..415599f337f3b3 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/extended/test/checks/missing_control_flow_directive/missing_control_flow_directive_spec.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/extended/test/checks/missing_control_flow_directive/missing_control_flow_directive_spec.ts @@ -17,10 +17,11 @@ import {factory as missingControlFlowDirectiveCheck} from '../../../checks/missi import {ExtendedTemplateCheckerImpl} from '../../../src/extended_template_checker'; const KNOWN_CONTROL_FLOW_DIRECTIVES = ['ngIf', 'ngFor', 'ngSwitchCase', 'ngSwitchDefault']; +const CORRESPONDING_IMPORTS = ['NgIf', 'NgForOf', 'NgSwitchCase', 'NgSwitchDefault']; runInEachFileSystem(() => { describe('MissingControlFlowDirectiveCheck', () => { - KNOWN_CONTROL_FLOW_DIRECTIVES.forEach(directive => { + KNOWN_CONTROL_FLOW_DIRECTIVES.forEach((directive, index) => { ['div', 'ng-template', 'ng-container', 'ng-content'].forEach(element => { it(`should produce a warning when the '${directive}' directive is not imported ` + `(when used on the '${element}' element)`, @@ -47,6 +48,15 @@ runInEachFileSystem(() => { expect(diags.length).toBe(1); expect(diags[0].category).toBe(ts.DiagnosticCategory.Warning); expect(diags[0].code).toBe(ngErrorCode(ErrorCode.MISSING_CONTROL_FLOW_DIRECTIVE)); + const correspondingImport = CORRESPONDING_IMPORTS[index]; + expect(diags[0].messageText) + .toBe( + `The \`*${directive}\` directive was used in the template, ` + + `but the \`*${ + correspondingImport}\` directive or the \`CommonModule\` were not imported. ` + + `Please make sure that the \`*${ + correspondingImport}\` directive or the \`CommonModule\` ` + + `are included in the \`@Component.imports\` array of this component.`); expect(getSourceCodeForDiagnostic(diags[0])).toBe(directive); });