use of com.google.template.soy.data.SoyMap 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;
}
}
Aggregations