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 bc7cde0f01
commit c4ce24647b
2 changed files with 120 additions and 107 deletions

View File

@ -2070,7 +2070,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" }
@ -2098,10 +2098,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))),
];
@ -2112,3 +2111,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));
}