fix(ivy): compute transitive scopes from NgModuleDef only (#24334)

Previously, the transitive scopes of an NgModuleDef were computed
during execution of the @NgModule decorator. This meant that JIT-
compiled modules could only import other JIT-compiled modules, as
the import mechanism relied on the calculation of transitive scopes
to already have happened for the imported module.

This change moves computation of transitive scopes to a function
`transitiveScopesFor` (and makes it lazy). This opens the door for
AOT -> JIT or JIT -> AOT imports, as transitive scopes for AOT
modules can be calculated when needed by JIT, and AOT modules can
also write expressions that call `transitiveScopesFor` when
importing a JIT-compiled module.

PR Close #24334
This commit is contained in:
Alex Rickabaugh
2018-06-06 11:23:38 -07:00
committed by Miško Hevery
parent 7983f0a69b
commit 113556357a
5 changed files with 194 additions and 79 deletions

View File

@ -13,6 +13,20 @@ import {R3_COMPILE_NGMODULE} from '../ivy_switch';
import {Type} from '../type';
import {TypeDecorator, makeDecorator} from '../util/decorators';
/**
* Represents the expansion of an `NgModule` into its scopes.
*
* A scope is a set of directives and pipes that are visible in a particular context. Each
* `NgModule` has two scopes. The `compilation` scope is the set of directives and pipes that will
* be recognized in the templates of components declared by the module. The `exported` scope is the
* set of directives and pipes exported by a module (that is, module B's exported scope gets added
* to module A's compilation scope when module A imports B).
*/
export interface NgModuleTransitiveScopes {
compilation: {directives: Set<any>; pipes: Set<any>;};
exported: {directives: Set<any>; pipes: Set<any>;};
}
export interface NgModuleDef<T> {
type: T;
bootstrap: Type<any>[];
@ -20,7 +34,12 @@ export interface NgModuleDef<T> {
imports: Type<any>[];
exports: Type<any>[];
transitiveCompileScope: {directives: any[]; pipes: any[];}|undefined;
/**
* Cached value of computed `transitiveCompileScopes` for this module.
*
* This should never be read directly, but accessed via `transitiveScopesFor`.
*/
transitiveCompileScopes: NgModuleTransitiveScopes|null;
}
export function defineNgModule<T>(def: {type: T} & Partial<NgModuleDef<T>>): never {
@ -30,7 +49,7 @@ export function defineNgModule<T>(def: {type: T} & Partial<NgModuleDef<T>>): nev
declarations: def.declarations || [],
imports: def.imports || [],
exports: def.exports || [],
transitiveCompileScope: undefined,
transitiveCompileScopes: null,
};
return res as never;
}