From a45fad3dd9c3d8ef9b6030603e6ce40ecb2c6082 Mon Sep 17 00:00:00 2001 From: Alex Rickabaugh Date: Wed, 13 Jun 2018 08:39:32 -0700 Subject: [PATCH] fix(ivy): keep JIT symbol table and r3_identifiers in sync (#24479) At runtime in JIT mode, when the compiler writes a reference to a symbol that symbol is resolved through a symbol table named angularCoreEnv in render3/jit/environment. Previously, this symbol table was not kept up-to-date with the Ivy instruction set and the names of symbols the compiler could reference. This change brings the symbol table in sync, and also adds a test that verifies every symbol the compiler can reference is available at runtime in the symbol table. PR Close #24479 --- .../compiler/src/render3/r3_identifiers.ts | 4 -- packages/core/src/render3/jit/environment.ts | 9 +++- packages/core/test/render3/BUILD.bazel | 1 + .../core/test/render3/jit_environment_spec.ts | 43 +++++++++++++++++++ 4 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 packages/core/test/render3/jit_environment_spec.ts diff --git a/packages/compiler/src/render3/r3_identifiers.ts b/packages/compiler/src/render3/r3_identifiers.ts index f665b557dd..51dc0bcafe 100644 --- a/packages/compiler/src/render3/r3_identifiers.ts +++ b/packages/compiler/src/render3/r3_identifiers.ts @@ -84,10 +84,6 @@ export class Identifiers { static projection: o.ExternalReference = {name: 'ɵP', moduleName: CORE}; static projectionDef: o.ExternalReference = {name: 'ɵpD', moduleName: CORE}; - static refreshComponent: o.ExternalReference = {name: 'ɵr', moduleName: CORE}; - - static directiveLifeCycle: o.ExternalReference = {name: 'ɵl', moduleName: CORE}; - static inject: o.ExternalReference = {name: 'inject', moduleName: CORE}; static injectAttribute: o.ExternalReference = {name: 'ɵinjectAttribute', moduleName: CORE}; diff --git a/packages/core/src/render3/jit/environment.ts b/packages/core/src/render3/jit/environment.ts index 3db548c1da..b4e0b8f0b5 100644 --- a/packages/core/src/render3/jit/environment.ts +++ b/packages/core/src/render3/jit/environment.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {defineInjectable} from '../../di/defs'; +import {defineInjectable, defineInjector,} from '../../di/defs'; import {inject} from '../../di/injector'; import {defineNgModule} from '../../metadata/ng_module'; import * as r3 from '../index'; @@ -21,7 +21,9 @@ export const angularCoreEnv: {[name: string]: Function} = { 'ɵdefineComponent': r3.defineComponent, 'ɵdefineDirective': r3.defineDirective, 'defineInjectable': defineInjectable, + 'defineInjector': defineInjector, 'ɵdefineNgModule': defineNgModule, + 'ɵdefinePipe': r3.definePipe, 'ɵdirectiveInject': r3.directiveInject, 'inject': inject, 'ɵinjectAttribute': r3.injectAttribute, @@ -60,18 +62,23 @@ export const angularCoreEnv: {[name: string]: Function} = { 'ɵi6': r3.i6, 'ɵi7': r3.i7, 'ɵi8': r3.i8, + 'ɵiV': r3.iV, 'ɵk': r3.k, 'ɵkn': r3.kn, 'ɵL': r3.L, 'ɵld': r3.ld, + 'ɵP': r3.P, 'ɵp': r3.p, 'ɵpb1': r3.pb1, 'ɵpb2': r3.pb2, 'ɵpb3': r3.pb3, 'ɵpb4': r3.pb4, 'ɵpbV': r3.pbV, + 'ɵpD': r3.pD, + 'ɵPp': r3.Pp, 'ɵQ': r3.Q, 'ɵqR': r3.qR, + 'ɵrS': r3.rS, 'ɵs': r3.s, 'ɵsn': r3.sn, 'ɵst': r3.st, diff --git a/packages/core/test/render3/BUILD.bazel b/packages/core/test/render3/BUILD.bazel index a3f89ee72f..52546212b3 100644 --- a/packages/core/test/render3/BUILD.bazel +++ b/packages/core/test/render3/BUILD.bazel @@ -21,6 +21,7 @@ ts_library( "//packages/animations/browser", "//packages/animations/browser/testing", "//packages/common", + "//packages/compiler", "//packages/core", "//packages/core/testing", "//packages/platform-browser", diff --git a/packages/core/test/render3/jit_environment_spec.ts b/packages/core/test/render3/jit_environment_spec.ts new file mode 100644 index 0000000000..c451f856a0 --- /dev/null +++ b/packages/core/test/render3/jit_environment_spec.ts @@ -0,0 +1,43 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * 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 {ExternalReference} from '@angular/compiler'; +import {Identifiers} from '@angular/compiler/src/render3/r3_identifiers'; + +import {angularCoreEnv} from '../../src/render3/jit/environment'; + +const INTERFACE_EXCEPTIONS = new Set([ + 'ComponentDef', + 'DirectiveDef', +]); + +describe('r3 jit environment', () => { + // This test keeps render3/jit/environment and r3_identifiers in the compiler in sync, ensuring + // that if the compiler writes a reference to a render3 symbol, it will be resolvable at runtime + // in JIT mode. + it('should support all r3 symbols', () => { + Object + // Map over the static properties of Identifiers. + .keys(Identifiers) + .map(key => (Identifiers as any as{[key: string]: string | ExternalReference})[key]) + // A few such properties are string constants. Ignore them, and focus on ExternalReferences. + .filter(isExternalReference) + // Some references are to interface types. Only take properties which have runtime values. + .filter(sym => !INTERFACE_EXCEPTIONS.has(sym.name)) + .forEach(sym => { + // Assert that angularCoreEnv has a reference to the runtime symbol. + expect(angularCoreEnv.hasOwnProperty(sym.name)) + .toBe(true, `Missing symbol ${sym.name} in render3/jit/environment`); + }); + }); +}); + +function isExternalReference(sym: ExternalReference | string): sym is ExternalReference& + {name: string} { + return typeof sym === 'object' && sym.name !== null && sym.moduleName !== null; +}