Skip to content

Commit 71d0063

Browse files
JoostKjosephperrott
authored andcommitted
fix(compiler-cli): report missing pipes when fullTemplateTypeCheck is disabled (#39320)
Even if `fullTemplateTypeCheck` is disabled should missing pipes still be reported, as was the case in View Engine. Fixes #38195 PR Close #39320
1 parent 85d5242 commit 71d0063

File tree

2 files changed

+39
-13
lines changed

2 files changed

+39
-13
lines changed

packages/compiler-cli/src/ngtsc/typecheck/src/type_check_block.ts

+14-13
Original file line numberDiff line numberDiff line change
@@ -895,11 +895,11 @@ export class Context {
895895
return ts.createIdentifier(`_t${this.nextId++}`);
896896
}
897897

898-
getPipeByName(name: string): ts.Expression|null {
898+
getPipeByName(name: string): Reference<ClassDeclaration<ts.ClassDeclaration>>|null {
899899
if (!this.pipes.has(name)) {
900900
return null;
901901
}
902-
return this.env.pipeInst(this.pipes.get(name)!);
902+
return this.pipes.get(name)!;
903903
}
904904
}
905905

@@ -1389,19 +1389,20 @@ class TcbExpressionTranslator {
13891389
return ts.createIdentifier('ctx');
13901390
} else if (ast instanceof BindingPipe) {
13911391
const expr = this.translate(ast.exp);
1392+
const pipeRef = this.tcb.getPipeByName(ast.name);
13921393
let pipe: ts.Expression|null;
1393-
if (this.tcb.env.config.checkTypeOfPipes) {
1394-
pipe = this.tcb.getPipeByName(ast.name);
1395-
if (pipe === null) {
1396-
// No pipe by that name exists in scope. Record this as an error.
1397-
this.tcb.oobRecorder.missingPipe(this.tcb.id, ast);
1398-
1399-
// Return an 'any' value to at least allow the rest of the expression to be checked.
1400-
pipe = NULL_AS_ANY;
1401-
}
1394+
if (pipeRef === null) {
1395+
// No pipe by that name exists in scope. Record this as an error.
1396+
this.tcb.oobRecorder.missingPipe(this.tcb.id, ast);
1397+
1398+
// Use an 'any' value to at least allow the rest of the expression to be checked.
1399+
pipe = NULL_AS_ANY;
1400+
} else if (this.tcb.env.config.checkTypeOfPipes) {
1401+
// Use a variable declared as the pipe's type.
1402+
pipe = this.tcb.env.pipeInst(pipeRef);
14021403
} else {
1403-
pipe = ts.createParen(ts.createAsExpression(
1404-
ts.createNull(), ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)));
1404+
// Use an 'any' value when not checking the type of the pipe.
1405+
pipe = NULL_AS_ANY;
14051406
}
14061407
const args = ast.args.map(arg => this.translate(arg));
14071408
const result = tsCallMethod(pipe, 'transform', [expr, ...args]);

packages/compiler-cli/test/ngtsc/template_typecheck_spec.ts

+25
Original file line numberDiff line numberDiff line change
@@ -1080,6 +1080,31 @@ export declare class AnimationEvent {
10801080
expect(getSourceCodeForDiagnostic(diags[0])).toBe('unknown');
10811081
});
10821082

1083+
it('should report an error with an unknown pipe even if `fullTemplateTypeCheck` is disabled',
1084+
() => {
1085+
env.tsconfig({ivyTemplateTypeCheck: true, fullTemplateTypeCheck: false});
1086+
env.write('test.ts', `
1087+
import {Component, NgModule} from '@angular/core';
1088+
1089+
@Component({
1090+
selector: 'test',
1091+
template: '{{expr | unknown}}',
1092+
})
1093+
class TestCmp {
1094+
expr = 3;
1095+
}
1096+
1097+
@NgModule({
1098+
declarations: [TestCmp],
1099+
})
1100+
class Module {}
1101+
`);
1102+
const diags = env.driveDiagnostics();
1103+
expect(diags.length).toBe(1);
1104+
expect(diags[0].messageText).toBe(`No pipe found with name 'unknown'.`);
1105+
expect(getSourceCodeForDiagnostic(diags[0])).toBe('unknown');
1106+
});
1107+
10831108
it('should report an error with pipe bindings', () => {
10841109
env.write('test.ts', `
10851110
import {CommonModule} from '@angular/common';

0 commit comments

Comments
 (0)