feat(ivy): first steps towards JIT compilation (#23833)
This commit adds a mechanism by which the @angular/core annotations for @Component, @Injectable, and @NgModule become decorators which, when executed at runtime, trigger just-in-time compilation of their associated types. The activation of these decorators is configured by the ivy_switch mechanism, ensuring that the Ivy JIT engine does not get included in Angular bundles unless specifically requested. PR Close #23833
This commit is contained in:

committed by
Matias Niemelä

parent
1b6b936ef4
commit
919f42fea1
@ -14,22 +14,72 @@ import * as o from '../output/output_ast';
|
||||
import {OutputContext} from '../util';
|
||||
|
||||
import {Identifiers as R3} from './r3_identifiers';
|
||||
import {convertMetaToOutput, mapToMapExpression} from './util';
|
||||
|
||||
function convertMetaToOutput(meta: any, ctx: OutputContext): o.Expression {
|
||||
if (Array.isArray(meta)) {
|
||||
return o.literalArr(meta.map(entry => convertMetaToOutput(entry, ctx)));
|
||||
}
|
||||
if (meta instanceof StaticSymbol) {
|
||||
return ctx.importExpr(meta);
|
||||
}
|
||||
if (meta == null) {
|
||||
return o.literal(meta);
|
||||
}
|
||||
|
||||
throw new Error(`Internal error: Unsupported or unknown metadata: ${meta}`);
|
||||
export interface R3NgModuleDef {
|
||||
expression: o.Expression;
|
||||
type: o.Type;
|
||||
additionalStatements: o.Statement[];
|
||||
}
|
||||
|
||||
export function compileNgModule(
|
||||
/**
|
||||
* Metadata required by the module compiler to generate a `ngModuleDef` for a type.
|
||||
*/
|
||||
export interface R3NgModuleMetadata {
|
||||
/**
|
||||
* An expression representing the module type being compiled.
|
||||
*/
|
||||
type: o.Expression;
|
||||
|
||||
/**
|
||||
* An array of expressions representing the bootstrap components specified by the module.
|
||||
*/
|
||||
bootstrap: o.Expression[];
|
||||
|
||||
/**
|
||||
* An array of expressions representing the directives and pipes declared by the module.
|
||||
*/
|
||||
declarations: o.Expression[];
|
||||
|
||||
/**
|
||||
* An array of expressions representing the imports of the module.
|
||||
*/
|
||||
imports: o.Expression[];
|
||||
|
||||
/**
|
||||
* An array of expressions representing the exports of the module.
|
||||
*/
|
||||
exports: o.Expression[];
|
||||
|
||||
/**
|
||||
* Whether to emit the selector scope values (declarations, imports, exports) inline into the
|
||||
* module definition, or to generate additional statements which patch them on. Inline emission
|
||||
* does not allow components to be tree-shaken, but is useful for JIT mode.
|
||||
*/
|
||||
emitInline: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an `R3NgModuleDef` for the given `R3NgModuleMetadata`.
|
||||
*/
|
||||
export function compileNgModule(meta: R3NgModuleMetadata): R3NgModuleDef {
|
||||
const {type: moduleType, bootstrap, declarations, imports, exports} = meta;
|
||||
const expression = o.importExpr(R3.defineNgModule).callFn([mapToMapExpression({
|
||||
type: moduleType,
|
||||
bootstrap: o.literalArr(bootstrap),
|
||||
declarations: o.literalArr(declarations),
|
||||
imports: o.literalArr(imports),
|
||||
exports: o.literalArr(exports),
|
||||
})]);
|
||||
|
||||
// TODO(alxhub): write a proper type reference when AOT compilation of @NgModule is implemented.
|
||||
const type = new o.ExpressionType(o.NULL_EXPR);
|
||||
const additionalStatements: o.Statement[] = [];
|
||||
return {expression, type, additionalStatements};
|
||||
}
|
||||
|
||||
// TODO(alxhub): integrate this with `compileNgModule`. Currently the two are separate operations.
|
||||
export function compileNgModuleFromRender2(
|
||||
ctx: OutputContext, ngModule: CompileShallowModuleMetadata,
|
||||
injectableCompiler: InjectableCompiler): void {
|
||||
const className = identifierName(ngModule.type) !;
|
||||
@ -57,4 +107,9 @@ export function compileNgModule(
|
||||
/* getters */[],
|
||||
/* constructorMethod */ new o.ClassMethod(null, [], []),
|
||||
/* methods */[]));
|
||||
}
|
||||
}
|
||||
|
||||
function accessExportScope(module: o.Expression): o.Expression {
|
||||
const selectorScope = new o.ReadPropExpr(module, 'ngModuleDef');
|
||||
return new o.ReadPropExpr(selectorScope, 'exported');
|
||||
}
|
||||
|
Reference in New Issue
Block a user