use of com.google.template.soy.jbcsrc.restricted.Expression in project closure-templates by google.
the class SoyNodeCompiler method getEscapingDirectivesList.
private Expression getEscapingDirectivesList(CallNode node) {
ImmutableList<SoyPrintDirective> escapingDirectives = node.getEscapingDirectives();
List<Expression> directiveExprs = new ArrayList<>(escapingDirectives.size());
for (SoyPrintDirective directive : escapingDirectives) {
directiveExprs.add(parameterLookup.getRenderContext().getPrintDirective(directive.getName()));
}
return BytecodeUtils.asImmutableList(directiveExprs);
}
use of com.google.template.soy.jbcsrc.restricted.Expression in project closure-templates by google.
the class SoyNodeCompiler method prepareParamsHelper.
private Expression prepareParamsHelper(CallNode node, Label reattachPoint) {
if (node.numChildren() == 0) {
// Easy, just use the data attribute
return getDataExpression(node, reattachPoint);
} else {
// Otherwise we need to build a dictionary from {param} statements.
Expression paramStoreExpression = getParamStoreExpression(node, reattachPoint);
for (CallParamNode child : node.getChildren()) {
String paramKey = child.getKey().identifier();
Expression valueExpr;
if (child instanceof CallParamContentNode) {
valueExpr = lazyClosureCompiler.compileLazyContent("param", (CallParamContentNode) child, paramKey);
} else {
valueExpr = lazyClosureCompiler.compileLazyExpression("param", child, paramKey, ((CallParamValueNode) child).getExpr());
}
// ParamStore.setField return 'this' so we can just chain the invocations together.
paramStoreExpression = MethodRef.PARAM_STORE_SET_FIELD.invoke(paramStoreExpression, BytecodeUtils.constant(paramKey), valueExpr);
}
return paramStoreExpression;
}
}
use of com.google.template.soy.jbcsrc.restricted.Expression in project closure-templates by google.
the class TemplateCompiler method generateConstructor.
/**
* Generate a public constructor that assigns our final field and checks for missing required
* params.
*
* <p>This constructor is called by the generate factory classes.
*
* @param fieldInitializers additional statements to initialize fields (other than params)
*/
private void generateConstructor(Statement fieldInitializers) {
final Label start = new Label();
final Label end = new Label();
final LocalVariable thisVar = createThisVar(template.typeInfo(), start, end);
final LocalVariable paramsVar = createLocal("params", 1, SOY_RECORD_TYPE, start, end);
final LocalVariable ijVar = createLocal("ij", 2, SOY_RECORD_TYPE, start, end);
final List<Statement> assignments = new ArrayList<>();
// for other fields needed by the compiler.
assignments.add(fieldInitializers);
assignments.add(paramsField.putInstanceField(thisVar, paramsVar));
assignments.add(ijField.putInstanceField(thisVar, ijVar));
for (TemplateParam param : template.node().getAllParams()) {
Expression paramProvider = getParam(paramsVar, ijVar, param);
assignments.add(paramFields.get(param.name()).putInstanceField(thisVar, paramProvider));
}
Statement constructorBody = new Statement() {
@Override
protected void doGen(CodeBuilder ga) {
ga.mark(start);
// call super()
thisVar.gen(ga);
ga.invokeConstructor(OBJECT.type(), NULLARY_INIT);
for (Statement assignment : assignments) {
assignment.gen(ga);
}
ga.visitInsn(Opcodes.RETURN);
ga.visitLabel(end);
thisVar.tableEntry(ga);
paramsVar.tableEntry(ga);
ijVar.tableEntry(ga);
}
};
constructorBody.writeMethod(Opcodes.ACC_PUBLIC, template.constructor().method(), writer);
}
use of com.google.template.soy.jbcsrc.restricted.Expression in project closure-templates by google.
the class TemplateCompiler method getParam.
/**
* Returns an expression that fetches the given param from the params record or the ij record and
* enforces the {@link TemplateParam#isRequired()} flag, throwing SoyDataException if a required
* parameter is missing.
*/
private static Expression getParam(LocalVariable paramsVar, LocalVariable ijVar, TemplateParam param) {
Expression fieldName = BytecodeUtils.constant(param.name());
Expression record = param.isInjected() ? ijVar : paramsVar;
// here instead they will just turn into null. Existing templates depend on this.
return MethodRef.RUNTIME_GET_FIELD_PROVIDER.invoke(record, fieldName);
}
use of com.google.template.soy.jbcsrc.restricted.Expression in project closure-templates by google.
the class TemplateVariableManager method enterScope.
/**
* Enters a new scope. Variables may only be defined within a scope.
*/
Scope enterScope() {
final Map<VarKey, Variable> currentFrame = new LinkedHashMap<>();
final Label scopeExit = new Label();
frames.push(currentFrame);
return new Scope() {
boolean exited;
@Override
Variable createSynthetic(SyntheticVarName varName, Expression initExpr, SaveStrategy strategy) {
checkState(!exited, "Scope already exited");
VarKey key = VarKey.create(Kind.SYNTHETIC, varName.name());
// synthetics are prefixed by $ by convention
String name = fieldNames.generateName("$" + varName.name());
return doCreate(name, new Label(), scopeExit, initExpr, key, strategy);
}
@Override
Variable createTemporary(String name, Expression initExpr) {
checkState(!exited, "Scope already exited");
VarKey key = VarKey.create(Kind.TEMPORARY, name);
name = fieldNames.generateName("$$" + name);
return doCreate(name, new Label(), scopeExit, initExpr, key, SaveStrategy.NEVER);
}
@Override
Variable create(String name, Expression initExpr, SaveStrategy strategy) {
checkState(!exited, "Scope already exited");
VarKey key = VarKey.create(Kind.USER_DEFINED, name);
name = fieldNames.generateName(name);
return doCreate(name, new Label(), scopeExit, initExpr, key, strategy);
}
@Override
Statement exitScope() {
checkState(!exited, "Scope already exited");
exited = true;
frames.pop();
// Use identity semantics to make sure we visit each label at most once. visiting a label
// more than once tends to corrupt internal asm state.
final Set<Label> endLabels = Sets.newIdentityHashSet();
for (Variable var : currentFrame.values()) {
endLabels.add(var.local.end());
availableSlots.clear(var.local.index(), var.local.index() + var.local.resultType().getSize());
}
return new Statement() {
// TODO(lukes): we could generate null writes for when object typed fields go out of
// scope. This would potentially allow intermediate results to be collected sooner.
@Override
protected void doGen(CodeBuilder adapter) {
for (Label label : endLabels) {
adapter.visitLabel(label);
}
}
};
}
private Variable doCreate(String name, Label start, Label end, Expression initExpr, VarKey key, SaveStrategy strategy) {
int index = reserveSlotFor(initExpr.resultType());
LocalVariable local = LocalVariable.createLocal(name, index, initExpr.resultType(), start, end);
Variable var;
switch(strategy) {
case DERIVED:
var = new DerivedVariable(initExpr, local);
break;
case NEVER:
var = new TemporaryVariable(initExpr, local);
break;
case STORE:
var = new FieldSavedVariable(initExpr, local);
break;
default:
throw new AssertionError();
}
currentFrame.put(key, var);
allVariables.add(var);
return var;
}
};
}
Aggregations