Search in sources :

Example 21 with SoyType

use of com.google.template.soy.types.SoyType in project closure-templates by google.

the class EvalVisitor method visitNullSafeItemAccessNode.

private SoyValue visitNullSafeItemAccessNode(ItemAccessNode itemAccess) {
    SoyValue base = visitNullSafeNodeRecurse(itemAccess.getBaseExprChild());
    // attempting item access on non-SoyMap
    if (!(base instanceof SoyLegacyObjectMap || base instanceof SoyMap)) {
        if (base == NullSafetySentinel.INSTANCE) {
            // Bail out if base expression failed a null-safety check.
            return NullSafetySentinel.INSTANCE;
        }
        if (itemAccess.isNullSafe()) {
            if (isNullOrUndefinedBase(base)) {
                // Return the sentinel value that indicates that a null-safety check failed.
                return NullSafetySentinel.INSTANCE;
            } else {
                throw RenderException.create(String.format("While evaluating \"%s\", encountered non-map/list just before accessing \"%s\".", itemAccess.toSourceString(), itemAccess.getSourceStringSuffix()));
            }
        }
        // TODO: If feasible, find and fix existing instances, then throw RenderException here.
        return UndefinedData.INSTANCE;
    }
    // base is a valid SoyMap or SoyLegacyObjectMap: get value
    maybeMarkBadProtoAccess(itemAccess, base);
    SoyValue key = visit(itemAccess.getKeyExprChild());
    SoyType baseType = SoyTypes.tryRemoveNull(itemAccess.getBaseExprChild().getType());
    // We need to know whether to invoke the SoyMap or SoyLegacyObjectMap method.
    // An instanceof check on the runtime value of base is insufficient, since
    // DictImpl implements both interfaces. Instead, look at the declared type of the base
    // expression.
    boolean shouldUseNewMap = MapType.ANY_MAP.isAssignableFrom(baseType);
    SoyValue value = shouldUseNewMap ? ((SoyMap) base).get(key) : ((SoyLegacyObjectMap) base).getItem(key);
    if (value != null && !TofuTypeChecks.isInstance(itemAccess.getType(), value)) {
        throw RenderException.create(String.format("Expected value of type '%s', but actual type was '%s'.", itemAccess.getType(), value.getClass().getSimpleName()));
    }
    if (value != null) {
        return value;
    } else if (shouldUseNewMap) {
        // UndefinedData is a misfeature. The new map type should return null for failed lookups.
        return NullData.INSTANCE;
    } else {
        return UndefinedData.INSTANCE;
    }
}
Also used : SoyLegacyObjectMap(com.google.template.soy.data.SoyLegacyObjectMap) SoyType(com.google.template.soy.types.SoyType) SoyMap(com.google.template.soy.data.SoyMap) SoyValue(com.google.template.soy.data.SoyValue)

Example 22 with SoyType

use of com.google.template.soy.types.SoyType in project closure-templates by google.

the class VeLogValidationPass method validateNodeAgainstConfig.

/**
 * Type checks both expressions and assigns the {@link VeLogNode#getLoggingId()} field.
 */
private void validateNodeAgainstConfig(VeLogNode node) {
    ValidatedLoggableElement config = loggingConfig.getElement(node.getName().identifier());
    if (config == null) {
        reporter.report(node.getName().location(), NO_CONFIG_FOR_ELEMENT, SoyErrors.getDidYouMeanMessage(loggingConfig.allKnownIdentifiers(), node.getName().identifier()));
    } else {
        node.setLoggingId(config.getId());
        if (node.getConfigExpression() != null) {
            SoyType type = node.getConfigExpression().getType();
            Optional<String> protoName = config.getProtoName();
            if (!protoName.isPresent()) {
                reporter.report(node.getConfigExpression().getSourceLocation(), UNEXPECTED_CONFIG, node.getName().identifier());
            } else if (type.getKind() != Kind.ERROR && (type.getKind() != Kind.PROTO || !((SoyProtoType) type).getDescriptor().getFullName().equals(protoName.get()))) {
                reporter.report(node.getConfigExpression().getSourceLocation(), WRONG_TYPE, protoName.get(), type);
            }
        }
        if (node.getLogonlyExpression() != null) {
            SoyType type = node.getLogonlyExpression().getType();
            if (type.getKind() != Kind.BOOL) {
                reporter.report(node.getLogonlyExpression().getSourceLocation(), WRONG_TYPE, BoolType.getInstance(), type);
            }
        }
    }
}
Also used : SoyType(com.google.template.soy.types.SoyType) ValidatedLoggableElement(com.google.template.soy.logging.ValidatedLoggingConfig.ValidatedLoggableElement)

Example 23 with SoyType

use of com.google.template.soy.types.SoyType in project closure-templates by google.

the class ExpressionCompilerTest method testNullCoalescingOpNode.

@Test
public void testNullCoalescingOpNode() {
    assertExpression("1 ?: 2").evaluatesTo(1L);
    // force the type checker to interpret the left hand side as a nullable string, the literal null
    // is rejected by the type checker.
    assertExpression("(true ? null : 'a') ?: 2").evaluatesTo(IntegerData.forValue(2));
    assertExpression("(true ? null : 'a') ?: 'b'").evaluatesTo(StringData.forValue("b"));
    assertExpression("(false ? null : 'a') ?: 'b'").evaluatesTo(StringData.forValue("a"));
    variables.put("p1", untypedBoxedSoyExpression(SoyExpression.forString(constantNull(STRING_TYPE))));
    variables.put("p2", SoyExpression.forString(constant("a")).box());
    assertExpression("$p1 ?: $p2").evaluatesTo(StringData.forValue("a"));
    SoyType htmlType = SanitizedType.getTypeForContentKind(SanitizedContentKind.HTML);
    variables.put("p1", SoyExpression.forSoyValue(htmlType, MethodRef.ORDAIN_AS_SAFE.invoke(constant("<b>hello</b>"), constant(ContentKind.HTML))));
    variables.put("p2", SoyExpression.forString(constant("")).box());
    assertExpression("$p1 ?: $p2").evaluatesTo(SanitizedContents.constantHtml("<b>hello</b>"));
    variables.put("p1", SoyExpression.forSoyValue(htmlType, constantNull(Type.getType(SanitizedContent.class))).asNullable());
    assertExpression("$p1 ?: $p2").evaluatesTo(StringData.forValue(""));
}
Also used : SoyType(com.google.template.soy.types.SoyType) Test(org.junit.Test)

Example 24 with SoyType

use of com.google.template.soy.types.SoyType in project closure-templates by google.

the class TofuTypeChecksTest method testUnionTypeIsInstance.

@Test
public void testUnionTypeIsInstance() {
    SoyType utype = UnionType.of(IntType.getInstance(), StringType.getInstance());
    assertIsInstance(utype, INTEGER_DATA, STRING_DATA, HTML_DATA, ATTRIBUTES_DATA, CSS_DATA, URI_DATA, TRUSTED_RESOURCE_URI_DATA, JS_DATA);
    assertIsNotInstance(utype, NULL_DATA, BOOLEAN_DATA, FLOAT_DATA, LIST_DATA, MAP_DATA, DICT_DATA);
}
Also used : SoyType(com.google.template.soy.types.SoyType) Test(org.junit.Test)

Example 25 with SoyType

use of com.google.template.soy.types.SoyType in project closure-templates by google.

the class MapToLegacyObjectMapFunction method computeForJbcSrc.

@Override
public SoyExpression computeForJbcSrc(JbcSrcPluginContext context, List<SoyExpression> args) {
    SoyExpression soyExpression = Iterables.getOnlyElement(args);
    SoyType originalType = soyExpression.soyRuntimeType().soyType();
    LegacyObjectMapType newType;
    if (originalType instanceof MapType) {
        newType = LegacyObjectMapType.of(((MapType) originalType).getKeyType(), ((MapType) originalType).getValueType());
    } else if (originalType instanceof UnknownType) {
        newType = LegacyObjectMapType.of(UnknownType.getInstance(), UnknownType.getInstance());
    } else {
        throw new IllegalArgumentException("mapToLegacyObjectMap() expects input to be MAP, get " + originalType.getKind());
    }
    return SoyExpression.forLegacyObjectMap(newType, JbcSrcMethods.MAP_TO_LEGACY_OBJECT_MAP.invoke(soyExpression.box().checkedCast(SoyMap.class)));
}
Also used : UnknownType(com.google.template.soy.types.UnknownType) SoyExpression(com.google.template.soy.jbcsrc.restricted.SoyExpression) SoyType(com.google.template.soy.types.SoyType) LegacyObjectMapType(com.google.template.soy.types.LegacyObjectMapType) LegacyObjectMapType(com.google.template.soy.types.LegacyObjectMapType) MapType(com.google.template.soy.types.MapType)

Aggregations

SoyType (com.google.template.soy.types.SoyType)26 MapType (com.google.template.soy.types.MapType)5 ExprNode (com.google.template.soy.exprtree.ExprNode)4 SoyExpression (com.google.template.soy.jbcsrc.restricted.SoyExpression)4 CodeChunk (com.google.template.soy.jssrc.dsl.CodeChunk)4 LegacyObjectMapType (com.google.template.soy.types.LegacyObjectMapType)4 ListType (com.google.template.soy.types.ListType)4 LinkedHashMap (java.util.LinkedHashMap)4 FieldDescriptor (com.google.protobuf.Descriptors.FieldDescriptor)3 ParentExprNode (com.google.template.soy.exprtree.ExprNode.ParentExprNode)3 TemplateParam (com.google.template.soy.soytree.defn.TemplateParam)3 SoyProtoEnumType (com.google.template.soy.types.SoyProtoEnumType)3 SoyProtoType (com.google.template.soy.types.SoyProtoType)3 UnionType (com.google.template.soy.types.UnionType)3 HashSet (java.util.HashSet)3 Map (java.util.Map)3 ImmutableMap (com.google.common.collect.ImmutableMap)2 FunctionNode (com.google.template.soy.exprtree.FunctionNode)2 VarRefNode (com.google.template.soy.exprtree.VarRefNode)2 RecordType (com.google.template.soy.types.RecordType)2