use of com.google.template.soy.types.SoyType in project closure-templates by google.
the class KeysFunction method computeForJbcSrc.
@Override
public SoyExpression computeForJbcSrc(JbcSrcPluginContext context, List<SoyExpression> args) {
SoyExpression soyExpression = args.get(0);
SoyType argType = soyExpression.soyType();
// TODO(lukes): this logic should live in ResolveExpressionTypesVisitor
SoyType listElementType;
if (argType.getKind() == Kind.LEGACY_OBJECT_MAP) {
// pretty much just string
listElementType = ((LegacyObjectMapType) argType).getKeyType();
} else if (argType.getKind() == Kind.LIST) {
listElementType = IntType.getInstance();
} else {
listElementType = UnknownType.getInstance();
}
return SoyExpression.forList(ListType.of(listElementType), JbcSrcMethods.KEYS_FN.invoke(soyExpression.box().checkedCast(SoyLegacyObjectMap.class)));
}
use of com.google.template.soy.types.SoyType in project closure-templates by google.
the class ResolveExpressionTypesVisitorTest method testTypeParser.
@Test
public void testTypeParser() {
SoyType type = parseSoyType("string");
assertThat(type).isEqualTo(StringType.getInstance());
type = parseSoyType("int");
assertThat(type).isEqualTo(IntType.getInstance());
type = parseSoyType("list<any>");
assertThat(type.getKind()).isEqualTo(SoyType.Kind.LIST);
assertThat(((ListType) type).getElementType()).isEqualTo(AnyType.getInstance());
type = parseSoyType("map<string, ?>");
assertThat(type.getKind()).isEqualTo(Kind.MAP);
assertThat(((MapType) type).getKeyType()).isEqualTo(StringType.getInstance());
assertThat(((MapType) type).getValueType()).isEqualTo(UnknownType.getInstance());
}
use of com.google.template.soy.types.SoyType in project closure-templates by google.
the class ResolveExpressionTypesVisitorTest method assertTypes.
/**
* Traverses the tree and checks all the calls to {@code assertType}
*/
private void assertTypes(SoyNode node) {
for (FunctionNode fn : SoyTreeUtils.getAllNodesOfType(node, FunctionNode.class)) {
if (fn.getFunctionName().equals("assertType")) {
StringNode expected = (StringNode) fn.getChild(0);
SoyType actualType = fn.getChild(1).getType();
assertWithMessage("assertion @ " + fn.getSourceLocation()).that(actualType.toString()).isEqualTo(expected.getValue());
}
}
}
use of com.google.template.soy.types.SoyType in project closure-templates by google.
the class SharedTestUtils method createTemplateBodyForExpression.
/**
* Returns a template body for the given soy expression. With type specializations.
*/
public static String createTemplateBodyForExpression(String soyExpr, final Map<String, SoyType> typeMap) {
ExprNode expr = SoyFileParser.parseExpression(soyExpr, PluginResolver.nullResolver(Mode.ALLOW_UNDEFINED, ErrorReporter.exploding()), ErrorReporter.exploding());
final Set<String> loopVarNames = new HashSet<>();
final Set<String> names = new HashSet<>();
new AbstractExprNodeVisitor<Void>() {
@Override
protected void visitVarRefNode(VarRefNode node) {
if (!node.isDollarSignIjParameter()) {
names.add(node.getName());
}
}
@Override
protected void visitFunctionNode(FunctionNode node) {
switch(node.getFunctionName()) {
case "index":
case "isFirst":
case "isLast":
loopVarNames.add(((VarRefNode) node.getChild(0)).getName());
break;
// fall out
default:
}
visitChildren(node);
}
@Override
protected void visitExprNode(ExprNode node) {
if (node instanceof ParentExprNode) {
visitChildren((ParentExprNode) node);
}
}
}.exec(expr);
final StringBuilder templateBody = new StringBuilder();
for (String varName : Sets.difference(names, loopVarNames)) {
SoyType type = typeMap.get(varName);
if (type == null) {
type = UnknownType.getInstance();
}
templateBody.append("{@param " + varName + ": " + type + "}\n");
}
String contents = "{" + soyExpr + "}\n";
for (String loopVar : loopVarNames) {
contents = "{for $" + loopVar + " in [null]}\n" + contents + "\n{/for}";
}
templateBody.append(contents);
return templateBody.toString();
}
use of com.google.template.soy.types.SoyType in project closure-templates by google.
the class TranslateExprNodeVisitor method genMapKeyCode.
/**
* Soy strings can be represented by SanitizedContent objects at runtime, so care needs to be
* taken when indexing into a map with a Soy "string". For pre-ES6 object maps, this isn't a
* problem, since bracket access implicitly calls toString() on the key, and SanitizedContent
* overrides toString appropriately. But ES6 Maps and jspb.Maps don't do this automatically, so we
* need to set it up.
*/
private CodeChunk.WithValue genMapKeyCode(ExprNode keyNode) {
CodeChunk.WithValue key = visit(keyNode);
// We need to coerce if the value could possibly a sanitizedcontent object
boolean needsRuntimeCoercionLogic = false;
SoyType type = keyNode.getType();
for (SoyType member : (type instanceof UnionType ? ((UnionType) type).getMembers() : ImmutableList.of(type))) {
Kind kind = member.getKind();
needsRuntimeCoercionLogic |= kind.isKnownStringOrSanitizedContent() || kind == Kind.UNKNOWN || kind == Kind.UNION || kind == Kind.ANY;
}
return needsRuntimeCoercionLogic ? SOY_MAP_MAYBE_COERCE_KEY_TO_STRING.call(key) : key;
}
Aggregations