fix(compiler-cli): generate `let` statements in ES2015+ mode (#38775)

When the target of the compiler is ES2015 or newer then we should
be generating `let` and `const` variable declarations rather than `var`.

PR Close #38775
This commit is contained in:
Pete Bacon Darwin 2020-09-21 13:05:26 +01:00 committed by Misko Hevery
parent 6158dc16b4
commit 123bff7cb6
7 changed files with 48 additions and 44 deletions

View File

@ -69,7 +69,7 @@ B.decorators = [
{ type: OtherB }, { type: OtherB },
{ type: Directive, args: [{ selector: '[b]' }] } { type: Directive, args: [{ selector: '[b]' }] }
]; ];
var C_1; let C_1;
let C = C_1 = class C {}; let C = C_1 = class C {};
C.decorators = [ C.decorators = [
{ type: Directive, args: [{ selector: '[c]' }] }, { type: Directive, args: [{ selector: '[c]' }] },
@ -111,7 +111,7 @@ B.decorators = [
]; ];
return B; return B;
})(); })();
var C_1; let C_1;
let C = C_1 = /** @class */ (() => { let C = C_1 = /** @class */ (() => {
class C {} class C {}
C.decorators = [ C.decorators = [
@ -432,7 +432,7 @@ A.decorators = [
name: _('/node_modules/test-package/some/file.js'), name: _('/node_modules/test-package/some/file.js'),
contents: ` contents: `
import * as tslib_1 from "tslib"; import * as tslib_1 from "tslib";
var D_1; let D_1;
/* A copyright notice */ /* A copyright notice */
import { Directive } from '@angular/core'; import { Directive } from '@angular/core';
const OtherA = () => (node) => { }; const OtherA = () => (node) => { };
@ -681,9 +681,9 @@ export { D };
const stmt3 = new DeclareVarStmt('baz', new LiteralExpr('qux'), undefined, []); const stmt3 = new DeclareVarStmt('baz', new LiteralExpr('qux'), undefined, []);
expect(renderer.printStatement(stmt1, sourceFile, importManager)).toBe('const foo = 42;'); expect(renderer.printStatement(stmt1, sourceFile, importManager)).toBe('const foo = 42;');
expect(renderer.printStatement(stmt2, sourceFile, importManager)).toBe('var bar = true;'); expect(renderer.printStatement(stmt2, sourceFile, importManager)).toBe('let bar = true;');
expect(renderer.printStatement(stmt3, sourceFile, importManager)) expect(renderer.printStatement(stmt3, sourceFile, importManager))
.toBe('var baz = "qux";'); .toBe('let baz = "qux";');
}); });
}); });
}); });

View File

@ -32,6 +32,8 @@ import {getRootFiles, makeTestEntryPointBundle} from '../helpers/utils';
class TestRenderingFormatter implements RenderingFormatter { class TestRenderingFormatter implements RenderingFormatter {
private printer = ts.createPrinter({newLine: ts.NewLineKind.LineFeed}); private printer = ts.createPrinter({newLine: ts.NewLineKind.LineFeed});
constructor(private isEs5: boolean) {}
addImports(output: MagicString, imports: Import[], sf: ts.SourceFile) { addImports(output: MagicString, imports: Import[], sf: ts.SourceFile) {
output.prepend('\n// ADD IMPORTS\n'); output.prepend('\n// ADD IMPORTS\n');
} }
@ -63,7 +65,8 @@ class TestRenderingFormatter implements RenderingFormatter {
} }
printStatement(stmt: Statement, sourceFile: ts.SourceFile, importManager: ImportManager): string { printStatement(stmt: Statement, sourceFile: ts.SourceFile, importManager: ImportManager): string {
const node = translateStatement( const node = translateStatement(
stmt, importManager, NOOP_DEFAULT_IMPORT_RECORDER, ts.ScriptTarget.ES2015); stmt, importManager, NOOP_DEFAULT_IMPORT_RECORDER,
this.isEs5 ? ts.ScriptTarget.ES5 : ts.ScriptTarget.ES2015);
const code = this.printer.printNode(ts.EmitHint.Unspecified, node, sourceFile); const code = this.printer.printNode(ts.EmitHint.Unspecified, node, sourceFile);
return `// TRANSPILED\n${code}`; return `// TRANSPILED\n${code}`;
@ -94,7 +97,7 @@ function createTestRenderer(
.analyzeProgram(bundle.src.program); .analyzeProgram(bundle.src.program);
const privateDeclarationsAnalyses = const privateDeclarationsAnalyses =
new PrivateDeclarationsAnalyzer(host, referencesRegistry).analyzeProgram(bundle.src.program); new PrivateDeclarationsAnalyzer(host, referencesRegistry).analyzeProgram(bundle.src.program);
const testFormatter = new TestRenderingFormatter(); const testFormatter = new TestRenderingFormatter(isEs5);
spyOn(testFormatter, 'addExports').and.callThrough(); spyOn(testFormatter, 'addExports').and.callThrough();
spyOn(testFormatter, 'addImports').and.callThrough(); spyOn(testFormatter, 'addImports').and.callThrough();
spyOn(testFormatter, 'addDefinitions').and.callThrough(); spyOn(testFormatter, 'addDefinitions').and.callThrough();
@ -569,7 +572,7 @@ UndecoratedBase.ɵfac = function UndecoratedBase_Factory(t) { return new (t || U
UndecoratedBase.ɵdir = ɵngcc0.ɵɵdefineDirective({ type: UndecoratedBase, viewQuery: function UndecoratedBase_Query(rf, ctx) { if (rf & 1) { UndecoratedBase.ɵdir = ɵngcc0.ɵɵdefineDirective({ type: UndecoratedBase, viewQuery: function UndecoratedBase_Query(rf, ctx) { if (rf & 1) {
ɵngcc0.ɵɵstaticViewQuery(_c0, true); ɵngcc0.ɵɵstaticViewQuery(_c0, true);
} if (rf & 2) { } if (rf & 2) {
var _t; let _t;
ɵngcc0.ɵɵqueryRefresh(_t = ɵngcc0.ɵɵloadQuery()) && (ctx.test = _t.first); ɵngcc0.ɵɵqueryRefresh(_t = ɵngcc0.ɵɵloadQuery()) && (ctx.test = _t.first);
} } });`); } } });`);
}); });

View File

@ -134,15 +134,16 @@ class ExpressionTranslatorVisitor implements ExpressionVisitor, StatementVisitor
private scriptTarget: Exclude<ts.ScriptTarget, ts.ScriptTarget.JSON>) {} private scriptTarget: Exclude<ts.ScriptTarget, ts.ScriptTarget.JSON>) {}
visitDeclareVarStmt(stmt: DeclareVarStmt, context: Context): ts.VariableStatement { visitDeclareVarStmt(stmt: DeclareVarStmt, context: Context): ts.VariableStatement {
const isConst = const varType = this.scriptTarget < ts.ScriptTarget.ES2015 ?
this.scriptTarget >= ts.ScriptTarget.ES2015 && stmt.hasModifier(StmtModifier.Final); ts.NodeFlags.None :
stmt.hasModifier(StmtModifier.Final) ? ts.NodeFlags.Const : ts.NodeFlags.Let;
const varDeclaration = ts.createVariableDeclaration( const varDeclaration = ts.createVariableDeclaration(
/* name */ stmt.name, /* name */ stmt.name,
/* type */ undefined, /* type */ undefined,
/* initializer */ stmt.value?.visitExpression(this, context.withExpressionMode)); /* initializer */ stmt.value?.visitExpression(this, context.withExpressionMode));
const declarationList = ts.createVariableDeclarationList( const declarationList = ts.createVariableDeclarationList(
/* declarations */[varDeclaration], /* declarations */[varDeclaration],
/* flags */ isConst ? ts.NodeFlags.Const : ts.NodeFlags.None); /* flags */ varType);
const varStatement = ts.createVariableStatement(undefined, declarationList); const varStatement = ts.createVariableStatement(undefined, declarationList);
return attachComments(varStatement, stmt.leadingComments); return attachComments(varStatement, stmt.leadingComments);
} }

View File

@ -1638,7 +1638,7 @@ describe('compiler compliance', () => {
$r3$.ɵɵviewQuery(SomeDirective, true); $r3$.ɵɵviewQuery(SomeDirective, true);
} }
if (rf & 2) { if (rf & 2) {
var $tmp$; let $tmp$;
$r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.someDir = $tmp$.first); $r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.someDir = $tmp$.first);
$r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.someDirs = $tmp$); $r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.someDirs = $tmp$);
} }
@ -1697,7 +1697,7 @@ describe('compiler compliance', () => {
$r3$.ɵɵviewQuery($e1_attrs$, true); $r3$.ɵɵviewQuery($e1_attrs$, true);
} }
if (rf & 2) { if (rf & 2) {
var $tmp$; let $tmp$;
$r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.myRef = $tmp$.first); $r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.myRef = $tmp$.first);
$r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.myRefs = $tmp$); $r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.myRefs = $tmp$);
} }
@ -1748,7 +1748,7 @@ describe('compiler compliance', () => {
$r3$.ɵɵviewQuery($refs$, true); $r3$.ɵɵviewQuery($refs$, true);
} }
if (rf & 2) { if (rf & 2) {
var $tmp$; let $tmp$;
$r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.someDir = $tmp$.first); $r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.someDir = $tmp$.first);
$r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.foo = $tmp$.first); $r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.foo = $tmp$.first);
} }
@ -1814,7 +1814,7 @@ describe('compiler compliance', () => {
$r3$.ɵɵviewQuery(SomeDirective, true, TemplateRef); $r3$.ɵɵviewQuery(SomeDirective, true, TemplateRef);
} }
if (rf & 2) { if (rf & 2) {
var $tmp$; let $tmp$;
$r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.myRef = $tmp$.first); $r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.myRef = $tmp$.first);
$r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.someDir = $tmp$.first); $r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.someDir = $tmp$.first);
$r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.myRefs = $tmp$); $r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.myRefs = $tmp$);
@ -1875,7 +1875,7 @@ describe('compiler compliance', () => {
$r3$.ɵɵcontentQuery(dirIndex, SomeDirective, false); $r3$.ɵɵcontentQuery(dirIndex, SomeDirective, false);
} }
if (rf & 2) { if (rf & 2) {
var $tmp$; let $tmp$;
$r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.someDir = $tmp$.first); $r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.someDir = $tmp$.first);
$r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.someDirList = $tmp$); $r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.someDirList = $tmp$);
} }
@ -1935,7 +1935,7 @@ describe('compiler compliance', () => {
$r3$.ɵɵcontentQuery(dirIndex, $e1_attrs$, false); $r3$.ɵɵcontentQuery(dirIndex, $e1_attrs$, false);
} }
if (rf & 2) { if (rf & 2) {
var $tmp$; let $tmp$;
$r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.myRef = $tmp$.first); $r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.myRef = $tmp$.first);
$r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.myRefs = $tmp$); $r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.myRefs = $tmp$);
} }
@ -1994,7 +1994,7 @@ describe('compiler compliance', () => {
$r3$.ɵɵcontentQuery(dirIndex, $ref0$, true); $r3$.ɵɵcontentQuery(dirIndex, $ref0$, true);
} }
if (rf & 2) { if (rf & 2) {
var $tmp$; let $tmp$;
$r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.someDir = $tmp$.first); $r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.someDir = $tmp$.first);
$r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.foo = $tmp$.first); $r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.foo = $tmp$.first);
} }
@ -2061,7 +2061,7 @@ describe('compiler compliance', () => {
$r3$.ɵɵcontentQuery(dirIndex, SomeDirective, false, TemplateRef); $r3$.ɵɵcontentQuery(dirIndex, SomeDirective, false, TemplateRef);
} }
if (rf & 2) { if (rf & 2) {
var $tmp$; let $tmp$;
$r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.myRef = $tmp$.first); $r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.myRef = $tmp$.first);
$r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.someDir = $tmp$.first); $r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.someDir = $tmp$.first);
$r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.myRefs = $tmp$); $r3$.ɵɵqueryRefresh($tmp$ = $r3$.ɵɵloadQuery()) && (ctx.myRefs = $tmp$);

View File

@ -209,7 +209,7 @@ describe('compiler compliance: bindings', () => {
template: function MyComponent_Template(rf, ctx) { template: function MyComponent_Template(rf, ctx) {
if (rf & 2) { if (rf & 2) {
var $tmp0$ = null; let $tmp0$ = null;
$r3$.ɵɵproperty("title", ctx.myTitle)("id", ($tmp0$ = $r3$.ɵɵpipeBind1(1, 3, ($tmp0$ = ctx.auth()) == null ? null : $tmp0$.identity())) == null ? null : $tmp0$.id)("tabindex", 1); $r3$.ɵɵproperty("title", ctx.myTitle)("id", ($tmp0$ = $r3$.ɵɵpipeBind1(1, 3, ($tmp0$ = ctx.auth()) == null ? null : $tmp0$.identity())) == null ? null : $tmp0$.id)("tabindex", 1);
} }
} }
@ -750,7 +750,7 @@ describe('compiler compliance: bindings', () => {
hostVars: 1, hostVars: 1,
hostBindings: function HostBindingDir_HostBindings(rf, ctx) { hostBindings: function HostBindingDir_HostBindings(rf, ctx) {
if (rf & 2) { if (rf & 2) {
var $tmp0$ = null; let $tmp0$ = null;
$r3$.ɵɵhostProperty("id", ($tmp0$ = ctx.getData()) == null ? null : $tmp0$.id); $r3$.ɵɵhostProperty("id", ($tmp0$ = ctx.getData()) == null ? null : $tmp0$.id);
} }
} }

View File

@ -212,7 +212,7 @@ describe('compiler compliance: dependency injection', () => {
MyService.ɵprov = $r3$.ɵɵdefineInjectable({ MyService.ɵprov = $r3$.ɵɵdefineInjectable({
token: MyService, token: MyService,
factory: function MyService_Factory(t) { factory: function MyService_Factory(t) {
var r = null; let r = null;
if (t) { if (t) {
r = new t(); r = new t();
} else { } else {
@ -285,7 +285,7 @@ describe('compiler compliance: dependency injection', () => {
MyService.ɵprov = $r3$.ɵɵdefineInjectable({ MyService.ɵprov = $r3$.ɵɵdefineInjectable({
token: MyService, token: MyService,
factory: function MyService_Factory(t) { factory: function MyService_Factory(t) {
var r = null; let r = null;
if (t) { if (t) {
r = new t(); r = new t();
} else { } else {

View File

@ -251,7 +251,7 @@ const i18nMsg = (message: string, placeholders: Placeholder[] = [], meta?: Meta)
const closurePlaceholders = i18nPlaceholdersToString(placeholders); const closurePlaceholders = i18nPlaceholdersToString(placeholders);
const locMessageWithPlaceholders = i18nMsgInsertLocalizePlaceholders(message, placeholders); const locMessageWithPlaceholders = i18nMsgInsertLocalizePlaceholders(message, placeholders);
return String.raw` return String.raw`
var ${varName}; let ${varName};
if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) { if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
${i18nMsgClosureMeta(meta)} ${i18nMsgClosureMeta(meta)}
const $MSG_EXTERNAL_${msgIndex}$ = goog.getMsg("${message}"${closurePlaceholders}); const $MSG_EXTERNAL_${msgIndex}$ = goog.getMsg("${message}"${closurePlaceholders});
@ -304,7 +304,7 @@ describe('i18n support in the template compiler', () => {
// Keeping this block as a raw string, since it checks escaping of special chars. // Keeping this block as a raw string, since it checks escaping of special chars.
const i18n_6 = String.raw` const i18n_6 = String.raw`
var $i18n_23$; let $i18n_23$;
if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) { if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
/** /**
* @desc [BACKUP_$` + * @desc [BACKUP_$` +
@ -321,7 +321,7 @@ describe('i18n support in the template compiler', () => {
// Keeping this block as a raw string, since it checks escaping of special chars. // Keeping this block as a raw string, since it checks escaping of special chars.
const i18n_7 = String.raw` const i18n_7 = String.raw`
var $i18n_7$; let $i18n_7$;
if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) { if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
/** /**
* @desc Some text \' [BACKUP_MESSAGE_ID: xxx] * @desc Some text \' [BACKUP_MESSAGE_ID: xxx]
@ -780,7 +780,7 @@ describe('i18n support in the template compiler', () => {
$r3$.ɵɵelementEnd(); $r3$.ɵɵelementEnd();
} }
if (rf & 2) { if (rf & 2) {
var $tmp_0_0$ = null; let $tmp_0_0$ = null;
$r3$.ɵɵi18nExp(($tmp_0_0$ = ctx.valueA.getRawValue()) == null ? null : $tmp_0_0$.getTitle()); $r3$.ɵɵi18nExp(($tmp_0_0$ = ctx.valueA.getRawValue()) == null ? null : $tmp_0_0$.getTitle());
$r3$.ɵɵi18nApply(1); $r3$.ɵɵi18nApply(1);
} }
@ -942,7 +942,7 @@ describe('i18n support in the template compiler', () => {
verify(input, output); verify(input, output);
}); });
it('should sanitize ids and generate proper var names', () => { it('should sanitize ids and generate proper variable names', () => {
const input = ` const input = `
<div i18n="@@ID.WITH.INVALID.CHARS.2" i18n-title="@@ID.WITH.INVALID.CHARS" title="Element title"> <div i18n="@@ID.WITH.INVALID.CHARS.2" i18n-title="@@ID.WITH.INVALID.CHARS" title="Element title">
Some content Some content
@ -951,7 +951,7 @@ describe('i18n support in the template compiler', () => {
// Keeping raw content (avoiding `i18nMsg`) to illustrate message id sanitization. // Keeping raw content (avoiding `i18nMsg`) to illustrate message id sanitization.
const output = String.raw` const output = String.raw`
var $I18N_0$; let $I18N_0$;
if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) { if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
const $MSG_EXTERNAL_ID_WITH_INVALID_CHARS$$APP_SPEC_TS_1$ = goog.getMsg("Element title"); const $MSG_EXTERNAL_ID_WITH_INVALID_CHARS$$APP_SPEC_TS_1$ = goog.getMsg("Element title");
$I18N_0$ = $MSG_EXTERNAL_ID_WITH_INVALID_CHARS$$APP_SPEC_TS_1$; $I18N_0$ = $MSG_EXTERNAL_ID_WITH_INVALID_CHARS$$APP_SPEC_TS_1$;
@ -960,7 +960,7 @@ describe('i18n support in the template compiler', () => {
$I18N_0$ = $localize \`:@@ID.WITH.INVALID.CHARS:Element title\`; $I18N_0$ = $localize \`:@@ID.WITH.INVALID.CHARS:Element title\`;
} }
var $I18N_2$; let $I18N_2$;
if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) { if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
const $MSG_EXTERNAL_ID_WITH_INVALID_CHARS_2$$APP_SPEC_TS_4$ = goog.getMsg(" Some content "); const $MSG_EXTERNAL_ID_WITH_INVALID_CHARS_2$$APP_SPEC_TS_4$ = goog.getMsg(" Some content ");
$I18N_2$ = $MSG_EXTERNAL_ID_WITH_INVALID_CHARS_2$$APP_SPEC_TS_4$; $I18N_2$ = $MSG_EXTERNAL_ID_WITH_INVALID_CHARS_2$$APP_SPEC_TS_4$;
@ -1018,7 +1018,7 @@ describe('i18n support in the template compiler', () => {
// Keeping raw content (avoiding `i18nMsg`) to illustrate quotes escaping. // Keeping raw content (avoiding `i18nMsg`) to illustrate quotes escaping.
const output = String.raw` const output = String.raw`
var $I18N_0$; let $I18N_0$;
if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) { if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
const $MSG_EXTERNAL_4924931801512133405$$APP_SPEC_TS_0$ = goog.getMsg("Some text 'with single quotes', \"with double quotes\", ` + const $MSG_EXTERNAL_4924931801512133405$$APP_SPEC_TS_0$ = goog.getMsg("Some text 'with single quotes', \"with double quotes\", ` +
'`with backticks`' + String.raw` and without quotes."); '`with backticks`' + String.raw` and without quotes.");
@ -1036,7 +1036,7 @@ describe('i18n support in the template compiler', () => {
const input = '<div i18n>`{{ count }}`</div>'; const input = '<div i18n>`{{ count }}`</div>';
// Keeping raw content (avoiding `i18nMsg`) to illustrate backticks escaping. // Keeping raw content (avoiding `i18nMsg`) to illustrate backticks escaping.
const output = String.raw` const output = String.raw`
var $I18N_0$; let $I18N_0$;
if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) { if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
const $MSG_APP_SPEC_TS_1$ = goog.getMsg("` + const $MSG_APP_SPEC_TS_1$ = goog.getMsg("` +
'`{$interpolation}`' + String.raw`", { "interpolation": "\uFFFD0\uFFFD" }); '`{$interpolation}`' + String.raw`", { "interpolation": "\uFFFD0\uFFFD" });
@ -1108,7 +1108,7 @@ describe('i18n support in the template compiler', () => {
// Keeping raw content (avoiding `i18nMsg`) to illustrate how named interpolations are // Keeping raw content (avoiding `i18nMsg`) to illustrate how named interpolations are
// generated. // generated.
const i18n_0 = String.raw` const i18n_0 = String.raw`
var $I18N_0$; let $I18N_0$;
if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) { if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
const $MSG_EXTERNAL_7597881511811528589$$APP_SPEC_TS_0$ = goog.getMsg(" Named interpolation: {$phA} Named interpolation with spaces: {$phB} ", { const $MSG_EXTERNAL_7597881511811528589$$APP_SPEC_TS_0$ = goog.getMsg(" Named interpolation: {$phA} Named interpolation with spaces: {$phB} ", {
"phA": "\uFFFD0\uFFFD", "phA": "\uFFFD0\uFFFD",
@ -1209,7 +1209,7 @@ describe('i18n support in the template compiler', () => {
$r3$.ɵɵelementEnd(); $r3$.ɵɵelementEnd();
} }
if (rf & 2) { if (rf & 2) {
var $tmp_2_0$ = null; let $tmp_2_0$ = null;
$r3$.ɵɵadvance(2); $r3$.ɵɵadvance(2);
$r3$.ɵɵi18nExp($r3$.ɵɵpipeBind1(2, 3, ctx.valueA)) $r3$.ɵɵi18nExp($r3$.ɵɵpipeBind1(2, 3, ctx.valueA))
(ctx.valueA == null ? null : ctx.valueA.a == null ? null : ctx.valueA.a.b) (ctx.valueA == null ? null : ctx.valueA.a == null ? null : ctx.valueA.a.b)
@ -2487,7 +2487,7 @@ describe('i18n support in the template compiler', () => {
// Keeping raw content (avoiding `i18nMsg`) to illustrate message layout // Keeping raw content (avoiding `i18nMsg`) to illustrate message layout
// in case of whitespace preserving mode. // in case of whitespace preserving mode.
const i18n_0 = String.raw` const i18n_0 = String.raw`
var $I18N_0$; let $I18N_0$;
if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) { if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
const $MSG_EXTERNAL_963542717423364282$$APP_SPEC_TS_0$ = goog.getMsg("\n Some text\n {$startTagSpan}Text inside span{$closeTagSpan}\n ", { const $MSG_EXTERNAL_963542717423364282$$APP_SPEC_TS_0$ = goog.getMsg("\n Some text\n {$startTagSpan}Text inside span{$closeTagSpan}\n ", {
"startTagSpan": "\uFFFD#3\uFFFD", "startTagSpan": "\uFFFD#3\uFFFD",
@ -2571,7 +2571,7 @@ describe('i18n support in the template compiler', () => {
`; `;
const output = String.raw` const output = String.raw`
var $I18N_0$; let $I18N_0$;
if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) { if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
const $MSG_EXTERNAL_4166854826696768832$$APP_SPEC_TS_0$ = goog.getMsg("{VAR_SELECT, select, single {'single quotes'} double {\"double quotes\"} other {other}}"); const $MSG_EXTERNAL_4166854826696768832$$APP_SPEC_TS_0$ = goog.getMsg("{VAR_SELECT, select, single {'single quotes'} double {\"double quotes\"} other {other}}");
$I18N_0$ = $MSG_EXTERNAL_4166854826696768832$$APP_SPEC_TS_0$; $I18N_0$ = $MSG_EXTERNAL_4166854826696768832$$APP_SPEC_TS_0$;
@ -2914,7 +2914,7 @@ describe('i18n support in the template compiler', () => {
// Keeping raw content here to illustrate the difference in placeholders generated for // Keeping raw content here to illustrate the difference in placeholders generated for
// goog.getMsg and $localize calls (see last i18n block). // goog.getMsg and $localize calls (see last i18n block).
const i18n_0 = String.raw` const i18n_0 = String.raw`
var $I18N_1$; let $I18N_1$;
if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) { if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
const $MSG_APP_SPEC_TS_1$ = goog.getMsg("{VAR_SELECT, select, male {male} female {female} other {other}}"); const $MSG_APP_SPEC_TS_1$ = goog.getMsg("{VAR_SELECT, select, male {male} female {female} other {other}}");
$I18N_1$ = $MSG_APP_SPEC_TS_1$; $I18N_1$ = $MSG_APP_SPEC_TS_1$;
@ -2925,7 +2925,7 @@ describe('i18n support in the template compiler', () => {
$I18N_1$ = $r3$.ɵɵi18nPostprocess($I18N_1$, { $I18N_1$ = $r3$.ɵɵi18nPostprocess($I18N_1$, {
"VAR_SELECT": "\uFFFD0\uFFFD" "VAR_SELECT": "\uFFFD0\uFFFD"
}); });
var $I18N_2$; let $I18N_2$;
if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) { if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
const $MSG_APP_SPEC_TS_2$ = goog.getMsg("{VAR_SELECT, select, male {male} female {female} other {other}}"); const $MSG_APP_SPEC_TS_2$ = goog.getMsg("{VAR_SELECT, select, male {male} female {female} other {other}}");
$I18N_2$ = $MSG_APP_SPEC_TS_2$; $I18N_2$ = $MSG_APP_SPEC_TS_2$;
@ -2936,7 +2936,7 @@ describe('i18n support in the template compiler', () => {
$I18N_2$ = $r3$.ɵɵi18nPostprocess($I18N_2$, { $I18N_2$ = $r3$.ɵɵi18nPostprocess($I18N_2$, {
"VAR_SELECT": "\uFFFD1\uFFFD" "VAR_SELECT": "\uFFFD1\uFFFD"
}); });
var $I18N_4$; let $I18N_4$;
if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) { if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
const $MSG_APP_SPEC_TS__4$ = goog.getMsg("{VAR_SELECT, select, male {male} female {female} other {other}}"); const $MSG_APP_SPEC_TS__4$ = goog.getMsg("{VAR_SELECT, select, male {male} female {female} other {other}}");
$I18N_4$ = $MSG_APP_SPEC_TS__4$; $I18N_4$ = $MSG_APP_SPEC_TS__4$;
@ -2947,7 +2947,7 @@ describe('i18n support in the template compiler', () => {
$I18N_4$ = $r3$.ɵɵi18nPostprocess($I18N_4$, { $I18N_4$ = $r3$.ɵɵi18nPostprocess($I18N_4$, {
"VAR_SELECT": "\uFFFD0:1\uFFFD" "VAR_SELECT": "\uFFFD0:1\uFFFD"
}); });
var $I18N_0$; let $I18N_0$;
if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) { if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
const $MSG_APP_SPEC_TS_0$ = goog.getMsg(" {$icu} {$startTagDiv} {$icu} {$closeTagDiv}{$startTagDiv_1} {$icu} {$closeTagDiv}", { const $MSG_APP_SPEC_TS_0$ = goog.getMsg(" {$icu} {$startTagDiv} {$icu} {$closeTagDiv}{$startTagDiv_1} {$icu} {$closeTagDiv}", {
"startTagDiv": "\uFFFD#2\uFFFD", "startTagDiv": "\uFFFD#2\uFFFD",
@ -3345,7 +3345,7 @@ describe('i18n support in the template compiler', () => {
const input = `<div i18n>Some Message</div>`; const input = `<div i18n>Some Message</div>`;
const output = String.raw` const output = String.raw`
var $I18N_0$; let $I18N_0$;
if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) { } if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) { }
else { else {
$I18N_0$ = $localize \`:␟ec93160d6d6a8822214060dd7938bf821c22b226␟6795333002533525253:Some Message\`; $I18N_0$ = $localize \`:␟ec93160d6d6a8822214060dd7938bf821c22b226␟6795333002533525253:Some Message\`;
@ -3360,7 +3360,7 @@ describe('i18n support in the template compiler', () => {
const input = `<div i18n>Some Message</div>`; const input = `<div i18n>Some Message</div>`;
const output = String.raw` const output = String.raw`
var $I18N_0$; let $I18N_0$;
if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) { } if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) { }
else { else {
$I18N_0$ = $localize \`:␟ec93160d6d6a8822214060dd7938bf821c22b226␟6795333002533525253:Some Message\`; $I18N_0$ = $localize \`:␟ec93160d6d6a8822214060dd7938bf821c22b226␟6795333002533525253:Some Message\`;
@ -3523,7 +3523,7 @@ $` + String.raw`{$I18N_4$}:ICU:\`;
`; `;
const i18n_0 = String.raw` const i18n_0 = String.raw`
var $I18N_0$; let $I18N_0$;
if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) { if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
const $MSG_EXTERNAL_7128002169381370313$$APP_SPEC_TS_1$ = goog.getMsg("{$startTagXhtmlDiv} Count: {$startTagXhtmlSpan}5{$closeTagXhtmlSpan}{$closeTagXhtmlDiv}", { const $MSG_EXTERNAL_7128002169381370313$$APP_SPEC_TS_1$ = goog.getMsg("{$startTagXhtmlDiv} Count: {$startTagXhtmlSpan}5{$closeTagXhtmlSpan}{$closeTagXhtmlDiv}", {
"startTagXhtmlDiv": "\uFFFD#3\uFFFD", "startTagXhtmlDiv": "\uFFFD#3\uFFFD",
@ -3584,7 +3584,7 @@ $` + String.raw`{$I18N_4$}:ICU:\`;
`; `;
const i18n_0 = String.raw` const i18n_0 = String.raw`
var $I18N_0$; let $I18N_0$;
if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) { if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
const $MSG_EXTERNAL_7428861019045796010$$APP_SPEC_TS_1$ = goog.getMsg(" Count: {$startTagXhtmlSpan}5{$closeTagXhtmlSpan}", { const $MSG_EXTERNAL_7428861019045796010$$APP_SPEC_TS_1$ = goog.getMsg(" Count: {$startTagXhtmlSpan}5{$closeTagXhtmlSpan}", {
"startTagXhtmlSpan": "\uFFFD#4\uFFFD", "startTagXhtmlSpan": "\uFFFD#4\uFFFD",