refactor(compiler): create a new root `BindingScope` for each template (#36362)

Previously we had a singleton `ROOT_SCOPE` object, from
which all `BindingScope`s derived. But this caused ngcc to
produce non-deterministic output when running multiple workers
in parallel, since each process had its own `ROOT_SCOPE`.

In reality there is no need for `BindingScope` reference names
to be unique across an entire application (or in the case of ngcc
across all the libraries). Instead we just need uniqueness within
a template.

This commit changes the compiler to create a new root `BindingScope`
each time it compiles a component's template.

Resolves #35180

PR Close #36362
This commit is contained in:
Pete Bacon Darwin 2020-04-01 10:02:26 +01:00 committed by atscott
parent 9e78f55c32
commit e526f74dfd
2 changed files with 3 additions and 8 deletions

View File

@ -177,7 +177,7 @@ export function compileComponentFromMetadata(
const template = meta.template; const template = meta.template;
const templateBuilder = new TemplateDefinitionBuilder( const templateBuilder = new TemplateDefinitionBuilder(
constantPool, BindingScope.ROOT_SCOPE, 0, templateTypeName, null, null, templateName, constantPool, BindingScope.createRootScope(), 0, templateTypeName, null, null, templateName,
directiveMatcher, directivesUsed, meta.pipes, pipesUsed, R3.namespaceHTML, directiveMatcher, directivesUsed, meta.pipes, pipesUsed, R3.namespaceHTML,
meta.relativeContextFilePath, meta.i18nUseExternalIds); meta.relativeContextFilePath, meta.i18nUseExternalIds);

View File

@ -1605,13 +1605,8 @@ export class BindingScope implements LocalResolver {
private map = new Map<string, BindingData>(); private map = new Map<string, BindingData>();
private referenceNameIndex = 0; private referenceNameIndex = 0;
private restoreViewVariable: o.ReadVarExpr|null = null; private restoreViewVariable: o.ReadVarExpr|null = null;
private static _ROOT_SCOPE: BindingScope; static createRootScope(): BindingScope {
return new BindingScope().set(0, '$event', o.variable('$event'));
static get ROOT_SCOPE(): BindingScope {
if (!BindingScope._ROOT_SCOPE) {
BindingScope._ROOT_SCOPE = new BindingScope().set(0, '$event', o.variable('$event'));
}
return BindingScope._ROOT_SCOPE;
} }
private constructor(public bindingLevel: number = 0, private parent: BindingScope|null = null) {} private constructor(public bindingLevel: number = 0, private parent: BindingScope|null = null) {}