refactor(core): add a checkIndex to the compiler view nodes
Each node now has two index: nodeIndex and checkIndex. nodeIndex is the index in both the view definition and the view data. checkIndex is the index in in the update function (update directives and update renderer). While nodeIndex and checkIndex have the same value for now, having both of them will allow changing the structure of view definition after compilation (ie for runtime translations).
This commit is contained in:

committed by
Alex Rickabaugh

parent
caa51950e8
commit
0833b59aab
@ -230,12 +230,15 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
|
||||
}
|
||||
|
||||
visitText(ast: TextAst, context: any): any {
|
||||
// textDef(ngContentIndex: number, constants: string[]): NodeDef;
|
||||
// Static text nodes have no check function
|
||||
const checkIndex = -1;
|
||||
this.nodes.push(() => ({
|
||||
sourceSpan: ast.sourceSpan,
|
||||
nodeFlags: NodeFlags.TypeText,
|
||||
nodeDef: o.importExpr(Identifiers.textDef).callFn([
|
||||
o.literal(ast.ngContentIndex), o.literalArr([o.literal(ast.value)])
|
||||
o.literal(checkIndex),
|
||||
o.literal(ast.ngContentIndex),
|
||||
o.literalArr([o.literal(ast.value)]),
|
||||
])
|
||||
}));
|
||||
}
|
||||
@ -252,12 +255,17 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
|
||||
(expr, bindingIndex) => this._preprocessUpdateExpression(
|
||||
{nodeIndex, bindingIndex, sourceSpan: ast.sourceSpan, context: COMP_VAR, value: expr}));
|
||||
|
||||
// textDef(ngContentIndex: number, constants: string[]): NodeDef;
|
||||
// Check index is the same as the node index during compilation
|
||||
// They might only differ at runtime
|
||||
const checkIndex = nodeIndex;
|
||||
|
||||
this.nodes[nodeIndex] = () => ({
|
||||
sourceSpan: ast.sourceSpan,
|
||||
nodeFlags: NodeFlags.TypeText,
|
||||
nodeDef: o.importExpr(Identifiers.textDef).callFn([
|
||||
o.literal(ast.ngContentIndex), o.literalArr(inter.strings.map(s => o.literal(s)))
|
||||
o.literal(checkIndex),
|
||||
o.literal(ast.ngContentIndex),
|
||||
o.literalArr(inter.strings.map(s => o.literal(s))),
|
||||
]),
|
||||
updateRenderer: updateRendererExpressions
|
||||
});
|
||||
@ -344,18 +352,15 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
|
||||
compRendererType = this.outputCtx.importExpr(compAst.directive.rendererType);
|
||||
}
|
||||
|
||||
// elementDef(
|
||||
// flags: NodeFlags, matchedQueriesDsl: [string | number, QueryValueType][],
|
||||
// ngContentIndex: number, childCount: number, namespaceAndName: string,
|
||||
// fixedAttrs: [string, string][] = [],
|
||||
// bindings?: [BindingFlags, string, string | SecurityContext][],
|
||||
// outputs?: ([OutputType.ElementOutput | OutputType.DirectiveHostOutput, string, string])[],
|
||||
// handleEvent?: ElementHandleEventFn,
|
||||
// componentView?: () => ViewDefinition, componentRendererType?: RendererType2): NodeDef;
|
||||
// Check index is the same as the node index during compilation
|
||||
// They might only differ at runtime
|
||||
const checkIndex = nodeIndex;
|
||||
|
||||
this.nodes[nodeIndex] = () => ({
|
||||
sourceSpan: ast.sourceSpan,
|
||||
nodeFlags: NodeFlags.TypeElement | flags,
|
||||
nodeDef: o.importExpr(Identifiers.elementDef).callFn([
|
||||
o.literal(checkIndex),
|
||||
o.literal(flags),
|
||||
queryMatchesExpr,
|
||||
o.literal(ast.ngContentIndex),
|
||||
@ -561,20 +566,22 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
|
||||
eventAst: hostEventAst, dirAst,
|
||||
}));
|
||||
|
||||
// Check index is the same as the node index during compilation
|
||||
// They might only differ at runtime
|
||||
const checkIndex = nodeIndex;
|
||||
|
||||
// directiveDef(
|
||||
// flags: NodeFlags, matchedQueries: [string, QueryValueType][], childCount: number, ctor:
|
||||
// any,
|
||||
// deps: ([DepFlags, any] | any)[], props?: {[name: string]: [number, string]},
|
||||
// outputs?: {[name: string]: string}, component?: () => ViewDefinition): NodeDef;
|
||||
this.nodes[nodeIndex] = () => ({
|
||||
sourceSpan: dirAst.sourceSpan,
|
||||
nodeFlags: NodeFlags.TypeDirective | flags,
|
||||
nodeDef: o.importExpr(Identifiers.directiveDef).callFn([
|
||||
o.literal(flags), queryMatchExprs.length ? o.literalArr(queryMatchExprs) : o.NULL_EXPR,
|
||||
o.literal(childCount), providerExpr, depsExpr,
|
||||
o.literal(checkIndex),
|
||||
o.literal(flags),
|
||||
queryMatchExprs.length ? o.literalArr(queryMatchExprs) : o.NULL_EXPR,
|
||||
o.literal(childCount),
|
||||
providerExpr,
|
||||
depsExpr,
|
||||
inputDefs.length ? new o.LiteralMapExpr(inputDefs) : o.NULL_EXPR,
|
||||
outputDefs.length ? new o.LiteralMapExpr(outputDefs) : o.NULL_EXPR
|
||||
outputDefs.length ? new o.LiteralMapExpr(outputDefs) : o.NULL_EXPR,
|
||||
]),
|
||||
updateDirectives: updateDirectiveExpressions,
|
||||
directive: dirAst.directive.type,
|
||||
@ -687,15 +694,18 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
|
||||
return () => valueExpr;
|
||||
}
|
||||
|
||||
const nodeIndex = this.nodes.length;
|
||||
// pureArrayDef(argCount: number): NodeDef;
|
||||
const checkIndex = this.nodes.length;
|
||||
|
||||
this.nodes.push(() => ({
|
||||
sourceSpan,
|
||||
nodeFlags: NodeFlags.TypePureArray,
|
||||
nodeDef: o.importExpr(Identifiers.pureArrayDef).callFn([o.literal(argCount)])
|
||||
nodeDef: o.importExpr(Identifiers.pureArrayDef).callFn([
|
||||
o.literal(checkIndex),
|
||||
o.literal(argCount),
|
||||
])
|
||||
}));
|
||||
|
||||
return (args: o.Expression[]) => callCheckStmt(nodeIndex, args);
|
||||
return (args: o.Expression[]) => callCheckStmt(checkIndex, args);
|
||||
}
|
||||
|
||||
private _createLiteralMapConverter(
|
||||
@ -705,28 +715,32 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
|
||||
return () => valueExpr;
|
||||
}
|
||||
|
||||
// function pureObjectDef(propToIndex: {[p: string]: number}): NodeDef
|
||||
const map = o.literalMap(keys.map((e, i) => ({...e, value: o.literal(i)})));
|
||||
const nodeIndex = this.nodes.length;
|
||||
const checkIndex = this.nodes.length;
|
||||
this.nodes.push(() => ({
|
||||
sourceSpan,
|
||||
nodeFlags: NodeFlags.TypePureObject,
|
||||
nodeDef: o.importExpr(Identifiers.pureObjectDef).callFn([map])
|
||||
nodeDef: o.importExpr(Identifiers.pureObjectDef).callFn([
|
||||
o.literal(checkIndex),
|
||||
map,
|
||||
])
|
||||
}));
|
||||
|
||||
return (args: o.Expression[]) => callCheckStmt(nodeIndex, args);
|
||||
return (args: o.Expression[]) => callCheckStmt(checkIndex, args);
|
||||
}
|
||||
|
||||
private _createPipeConverter(expression: UpdateExpression, name: string, argCount: number):
|
||||
BuiltinConverter {
|
||||
const pipe = this.usedPipes.find((pipeSummary) => pipeSummary.name === name) !;
|
||||
if (pipe.pure) {
|
||||
const nodeIndex = this.nodes.length;
|
||||
// function purePipeDef(argCount: number): NodeDef;
|
||||
const checkIndex = this.nodes.length;
|
||||
this.nodes.push(() => ({
|
||||
sourceSpan: expression.sourceSpan,
|
||||
nodeFlags: NodeFlags.TypePurePipe,
|
||||
nodeDef: o.importExpr(Identifiers.purePipeDef).callFn([o.literal(argCount)])
|
||||
nodeDef: o.importExpr(Identifiers.purePipeDef).callFn([
|
||||
o.literal(checkIndex),
|
||||
o.literal(argCount),
|
||||
])
|
||||
}));
|
||||
|
||||
// find underlying pipe in the component view
|
||||
@ -742,7 +756,7 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
|
||||
|
||||
return (args: o.Expression[]) => callUnwrapValue(
|
||||
expression.nodeIndex, expression.bindingIndex,
|
||||
callCheckStmt(nodeIndex, [pipeValueExpr].concat(args)));
|
||||
callCheckStmt(checkIndex, [pipeValueExpr].concat(args)));
|
||||
} else {
|
||||
const nodeIndex = this._createPipe(expression.sourceSpan, pipe);
|
||||
const nodeValueExpr =
|
||||
|
Reference in New Issue
Block a user