feat(ivy): implement template variables (#21760)

PR Close #21760
This commit is contained in:
Chuck Jazdzewski
2018-01-24 11:19:39 -08:00
committed by Misko Hevery
parent 08aa54e1d9
commit bbb8f386f1
2 changed files with 246 additions and 7 deletions

View File

@ -32,6 +32,9 @@ const TEMPORARY_NAME = '_t';
/** The prefix reference variables */
const REFERENCE_PREFIX = '_r';
/** The name of the implicit context reference */
const IMPLICIT_REFERENCE = '$implicit';
export function compileDirective(
outputCtx: OutputContext, directive: CompileDirectiveMetadata, reflector: CompileReflector) {
const definitionMapValues: {key: string, quoted: boolean, value: o.Expression}[] = [];
@ -98,7 +101,7 @@ export function compileComponent(
new TemplateDefinitionBuilder(
outputCtx, outputCtx.constantPool, reflector, CONTEXT_NAME, ROOT_SCOPE.nestedScope(), 0,
templateTypeName, templateName)
.buildTemplateFunction(template);
.buildTemplateFunction(template, []);
definitionMapValues.push({key: 'template', value: templateFunctionExpression, quoted: false});
@ -223,7 +226,24 @@ class TemplateDefinitionBuilder implements TemplateAstVisitor, LocalResolver {
private bindingScope: BindingScope, private level = 0, private contextName: string|null,
private templateName: string|null) {}
buildTemplateFunction(asts: TemplateAst[]): o.FunctionExpr {
buildTemplateFunction(asts: TemplateAst[], variables: VariableAst[]): o.FunctionExpr {
// Create variable bindings
for (const variable of variables) {
const variableName = variable.name;
const expression =
o.variable(this.contextParameter).prop(variable.value || IMPLICIT_REFERENCE);
const scopedName = this.bindingScope.freshReferenceName();
const declaration = o.variable(scopedName).set(expression).toDeclStmt(o.INFERRED_TYPE, [
o.StmtModifier.Final
]);
// Add the reference to the local scope.
this.bindingScope.set(variableName, scopedName);
// Declare the local variable in binding mode
this._bindingMode.push(declaration);
}
templateVisitAll(this, asts);
return o.fn(
@ -395,8 +415,9 @@ class TemplateDefinitionBuilder implements TemplateAstVisitor, LocalResolver {
this, implicit, input.value, this.bindingContext(), BindingForm.TrySimple, interpolate);
this._bindingMode.push(...convertedBinding.stmts);
this.instruction(
this._bindingMode, directive.sourceSpan, R3.elementProperty,
o.literal(input.templateName), o.literal(nodeIndex), convertedBinding.currValExpr);
this._bindingMode, directive.sourceSpan, R3.elementProperty, o.literal(nodeIndex),
o.literal(input.templateName),
o.importExpr(R3.bind).callFn([convertedBinding.currValExpr]));
}
// e.g. TodoComponentDef.r(0, 0);
@ -445,7 +466,7 @@ class TemplateDefinitionBuilder implements TemplateAstVisitor, LocalResolver {
const templateVisitor = new TemplateDefinitionBuilder(
this.outputCtx, this.constantPool, this.reflector, templateContext,
this.bindingScope.nestedScope(), this.level + 1, contextName, templateName);
const templateFunctionExpr = templateVisitor.buildTemplateFunction(ast.children);
const templateFunctionExpr = templateVisitor.buildTemplateFunction(ast.children, ast.variables);
this._postfix.push(templateFunctionExpr.toDeclStmt(templateName, null));
}