fix(compiler-cli): compute the correct target output for `$localize` messages (#36989)
In some versions of TypeScript, the transformation of synthetic `$localize` tagged template literals is broken. See https://github.com/microsoft/TypeScript/issues/38485 We now compute what the expected final output target of the compilation will be so that we can generate ES5 compliant `$localize` calls instead of relying upon TS to do the downleveling for us. This is a workaround for the TS compiler bug, which could be removed when this is fixed. But since it only affects ES5 targeted compilations, which is now not the norm, it has limited impact on the majority of Angular projects. So this fix can probably be left in indefinitely. PR Close #36989
This commit is contained in:
parent
b0e362f75b
commit
4e1b5e43fa
|
@ -233,8 +233,8 @@ function transformIvySourceFile(
|
|||
// Generate the constant statements first, as they may involve adding additional imports
|
||||
// to the ImportManager.
|
||||
const constants = constantPool.statements.map(
|
||||
stmt =>
|
||||
translateStatement(stmt, importManager, defaultImportRecorder, ts.ScriptTarget.ES2015));
|
||||
stmt => translateStatement(
|
||||
stmt, importManager, defaultImportRecorder, getLocalizeCompileTarget(context)));
|
||||
|
||||
// Preserve @fileoverview comments required by Closure, since the location might change as a
|
||||
// result of adding extra imports and constant pool statements.
|
||||
|
@ -250,6 +250,22 @@ function transformIvySourceFile(
|
|||
return sf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the correct target output for `$localize` messages generated by Angular
|
||||
*
|
||||
* In some versions of TypeScript, the transformation of synthetic `$localize` tagged template
|
||||
* literals is broken. See https://github.com/microsoft/TypeScript/issues/38485
|
||||
*
|
||||
* Here we compute what the expected final output target of the compilation will
|
||||
* be so that we can generate ES5 compliant `$localize` calls instead of relying upon TS to do the
|
||||
* downleveling for us.
|
||||
*/
|
||||
function getLocalizeCompileTarget(context: ts.TransformationContext):
|
||||
Exclude<ts.ScriptTarget, ts.ScriptTarget.JSON> {
|
||||
const target = context.getCompilerOptions().target || ts.ScriptTarget.ES2015;
|
||||
return target !== ts.ScriptTarget.JSON ? target : ts.ScriptTarget.ES2015;
|
||||
}
|
||||
|
||||
function getFileOverviewComment(statements: ts.NodeArray<ts.Statement>): FileOverviewMeta|null {
|
||||
if (statements.length > 0) {
|
||||
const host = statements[0];
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {AttributeMarker} from '@angular/compiler/src/core';
|
||||
import {setup} from '@angular/compiler/test/aot/test_util';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig} from '../../../compiler/src/compiler';
|
||||
import {decimalDigest} from '../../../compiler/src/i18n/digest';
|
||||
|
@ -3761,6 +3761,23 @@ $` + String.raw`{$I18N_4$}:ICU:\`;
|
|||
}));
|
||||
});
|
||||
|
||||
describe('es5 support', () => {
|
||||
it('should generate ES5 compliant localized messages if the target is ES5', () => {
|
||||
const input = `
|
||||
<div i18n="meaning:A|descA@@idA">Content A</div>
|
||||
`;
|
||||
|
||||
const output = String.raw`
|
||||
var $I18N_0$;
|
||||
…
|
||||
$I18N_0$ = $localize(…__makeTemplateObject([":meaning:A|descA@@idA:Content A"], [":meaning\\:A|descA@@idA:Content A"])…);
|
||||
`;
|
||||
|
||||
verify(
|
||||
input, output, {skipIdBasedCheck: true, compilerOptions: {target: ts.ScriptTarget.ES5}});
|
||||
});
|
||||
});
|
||||
|
||||
describe('errors', () => {
|
||||
const verifyNestedSectionsError = (errorThrown: any, expectedErrorText: string) => {
|
||||
expect(errorThrown.ngParseErrors.length).toBe(1);
|
||||
|
|
Loading…
Reference in New Issue