fix(compiler-cli): ensure that ngI18nClosureMode is guarded in generated code (#34211)

If the `ngI18nClosureMode` global check actually makes it
through to the runtime, then checks for its existence should
be guarded to prevent `Reference undefined` errors in strict
mode.

(Normally, it is stripped out by dead code elimination during
build optimization.)

This comment ensures that generated template code guards
this global check.

PR Close #34211
This commit is contained in:
Pete Bacon Darwin
2019-12-03 11:58:10 +00:00
committed by Miško Hevery
parent 25462614db
commit 4d025562c4
2 changed files with 120 additions and 107 deletions

View File

@ -2045,7 +2045,7 @@ const NG_I18N_CLOSURE_MODE = 'ngI18nClosureMode';
*
* ```
* var I18N_1;
* if (ngI18nClosureMode) {
* if (typeof ngI18nClosureMode !== undefined && ngI18nClosureMode) {
* var MSG_EXTERNAL_XXX = goog.getMsg(
* "Some message with {$interpolation}!",
* { "interpolation": "\uFFFD0\uFFFD" }
@ -2073,10 +2073,9 @@ export function getTranslationDeclStmts(
const statements: o.Statement[] = [
declareI18nVariable(variable),
o.ifStmt(
o.variable(NG_I18N_CLOSURE_MODE),
createGoogleGetMsgStatements(
variable, message, closureVar,
i18nFormatPlaceholderNames(params, /* useCamelCase */ true)),
createClosureModeGuard(), createGoogleGetMsgStatements(
variable, message, closureVar,
i18nFormatPlaceholderNames(params, /* useCamelCase */ true)),
createLocalizeStatements(
variable, message, i18nFormatPlaceholderNames(params, /* useCamelCase */ false))),
];
@ -2087,3 +2086,17 @@ export function getTranslationDeclStmts(
return statements;
}
/**
* Create the expression that will be used to guard the closure mode block
* It is equivalent to:
*
* ```
* typeof ngI18nClosureMode !== undefined && ngI18nClosureMode
* ```
*/
function createClosureModeGuard(): o.BinaryOperatorExpr {
return o.typeofExpr(o.variable(NG_I18N_CLOSURE_MODE))
.notIdentical(o.literal('undefined', o.STRING_TYPE))
.and(o.variable(NG_I18N_CLOSURE_MODE));
}