fix(compiler): don’t type check templates with `skipTemplateCodegen` (#19909)
This change is needed to prevent users’ builds from breaking. If a user sets `fullTemlateTypeCheck` to true, we will continue to check the templates even when `skipTemplateCodegen` is true as well. Related to #19906 PR Close #19909
This commit is contained in:
parent
b51d57deb8
commit
c92efc15fb
|
@ -426,6 +426,12 @@ export class TsCompilerAotCompilerTypeCheckHostAdapter implements ts.CompilerHos
|
|||
}
|
||||
|
||||
isSourceFile(filePath: string): boolean {
|
||||
// Don't generate any files nor typecheck them
|
||||
// if skipTemplateCodegen is set and fullTemplateTypeCheck is not yet set,
|
||||
// for backwards compatibility.
|
||||
if (this.options.skipTemplateCodegen && !this.options.fullTemplateTypeCheck) {
|
||||
return false;
|
||||
}
|
||||
// If we have a summary from a previous compilation,
|
||||
// treat the file never as a source file.
|
||||
if (this.librarySummaries.has(filePath)) {
|
||||
|
|
|
@ -181,11 +181,13 @@ function createVariableStatementForDeclarations(declarations: Declaration[]): ts
|
|||
/* modifiers */ undefined, ts.createVariableDeclarationList(varDecls, ts.NodeFlags.Const));
|
||||
}
|
||||
|
||||
export function getExpressionLoweringTransformFactory(requestsMap: RequestsMap):
|
||||
(context: ts.TransformationContext) => (sourceFile: ts.SourceFile) => ts.SourceFile {
|
||||
export function getExpressionLoweringTransformFactory(
|
||||
requestsMap: RequestsMap, program: ts.Program): (context: ts.TransformationContext) =>
|
||||
(sourceFile: ts.SourceFile) => ts.SourceFile {
|
||||
// Return the factory
|
||||
return (context: ts.TransformationContext) => (sourceFile: ts.SourceFile): ts.SourceFile => {
|
||||
const requests = requestsMap.getRequests(sourceFile);
|
||||
// We need to use the original SourceFile for reading metadata, and not the transformed one.
|
||||
const requests = requestsMap.getRequests(program.getSourceFile(sourceFile.fileName));
|
||||
if (requests && requests.size) {
|
||||
return transformSourceFile(sourceFile, requests, context);
|
||||
}
|
||||
|
|
|
@ -386,7 +386,7 @@ class AngularCompilerProgram implements Program {
|
|||
customTransformers?: CustomTransformers): ts.CustomTransformers {
|
||||
const beforeTs: ts.TransformerFactory<ts.SourceFile>[] = [];
|
||||
if (!this.options.disableExpressionLowering) {
|
||||
beforeTs.push(getExpressionLoweringTransformFactory(this.metadataCache));
|
||||
beforeTs.push(getExpressionLoweringTransformFactory(this.metadataCache, this.tsProgram));
|
||||
}
|
||||
beforeTs.push(getAngularEmitterTransformFactory(genFiles));
|
||||
if (customTransformers && customTransformers.beforeTs) {
|
||||
|
@ -754,7 +754,7 @@ export function createSrcToOutPathMapper(
|
|||
export function i18nExtract(
|
||||
formatName: string | null, outFile: string | null, host: ts.CompilerHost,
|
||||
options: CompilerOptions, bundle: MessageBundle): string[] {
|
||||
formatName = formatName || 'null';
|
||||
formatName = formatName || 'xlf';
|
||||
// Checks the format and returns the extension
|
||||
const ext = i18nGetExtension(formatName);
|
||||
const content = i18nSerialize(bundle, formatName, options);
|
||||
|
@ -788,7 +788,7 @@ export function i18nSerialize(
|
|||
}
|
||||
|
||||
export function i18nGetExtension(formatName: string): string {
|
||||
const format = (formatName || 'xlf').toLowerCase();
|
||||
const format = formatName.toLowerCase();
|
||||
|
||||
switch (format) {
|
||||
case 'xmb':
|
||||
|
|
|
@ -181,13 +181,15 @@ function convert(annotatedSource: string) {
|
|||
[fileName], {module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2017}, host);
|
||||
const moduleSourceFile = program.getSourceFile(fileName);
|
||||
const transformers: ts.CustomTransformers = {
|
||||
before: [getExpressionLoweringTransformFactory({
|
||||
getRequests(sourceFile: ts.SourceFile): RequestLocationMap{
|
||||
if (sourceFile.fileName == moduleSourceFile.fileName) {
|
||||
return requests;
|
||||
} else {return new Map();}
|
||||
}
|
||||
})]
|
||||
before: [getExpressionLoweringTransformFactory(
|
||||
{
|
||||
getRequests(sourceFile: ts.SourceFile): RequestLocationMap{
|
||||
if (sourceFile.fileName == moduleSourceFile.fileName) {
|
||||
return requests;
|
||||
} else {return new Map();}
|
||||
}
|
||||
},
|
||||
program)]
|
||||
};
|
||||
let result: string = '';
|
||||
const emitResult = program.emit(
|
||||
|
|
|
@ -11,7 +11,7 @@ import * as fs from 'fs';
|
|||
import * as path from 'path';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {CompilerHost, LazyRoute} from '../../src/transformers/api';
|
||||
import {CompilerHost, EmitFlags, LazyRoute} from '../../src/transformers/api';
|
||||
import {createSrcToOutPathMapper} from '../../src/transformers/program';
|
||||
import {GENERATED_FILES, StructureIsReused, tsStructureIsReused} from '../../src/transformers/util';
|
||||
import {TestSupport, expectNoDiagnosticsInProgram, setup} from '../test_support';
|
||||
|
@ -309,11 +309,35 @@ describe('ng program', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should typecheck templates even if skipTemplateCodegen is set', () => {
|
||||
it('should not typecheck templates if skipTemplateCodegen is set but fullTemplateTypeCheck is not',
|
||||
() => {
|
||||
testSupport.writeFiles({
|
||||
'src/main.ts': `
|
||||
import {NgModule} from '@angular/core';
|
||||
|
||||
@NgModule(() => {if (1==1) return null as any;})
|
||||
export class SomeClassWithInvalidMetadata {}
|
||||
`,
|
||||
});
|
||||
const options = testSupport.createCompilerOptions({skipTemplateCodegen: true});
|
||||
const host = ng.createCompilerHost({options});
|
||||
const program = ng.createProgram(
|
||||
{rootNames: [path.resolve(testSupport.basePath, 'src/main.ts')], options, host});
|
||||
expectNoDiagnosticsInProgram(options, program);
|
||||
const emitResult = program.emit({emitFlags: EmitFlags.All});
|
||||
expect(emitResult.diagnostics.length).toBe(0);
|
||||
|
||||
testSupport.shouldExist('built/src/main.metadata.json');
|
||||
});
|
||||
|
||||
it('should typecheck templates if skipTemplateCodegen and fullTemplateTypeCheck is set', () => {
|
||||
testSupport.writeFiles({
|
||||
'src/main.ts': createModuleAndCompSource('main', `{{nonExistent}}`),
|
||||
});
|
||||
const options = testSupport.createCompilerOptions({skipTemplateCodegen: true});
|
||||
const options = testSupport.createCompilerOptions({
|
||||
skipTemplateCodegen: true,
|
||||
fullTemplateTypeCheck: true,
|
||||
});
|
||||
const host = ng.createCompilerHost({options});
|
||||
const program = ng.createProgram(
|
||||
{rootNames: [path.resolve(testSupport.basePath, 'src/main.ts')], options, host});
|
||||
|
|
Loading…
Reference in New Issue