List<Value> result = new ArrayList<Value>(listValue.getValues().size());
for (Value val : listValue.getValues()) {
if (val.isFunctionValue() != null) {
// Recursively perform substitution on a function's values
FunctionValue fnVal = val.isFunctionValue();
ListValue newVals = substituteDefs(fnVal.getValues());
result.add(new FunctionValue(fnVal.getName(), newVals));
continue;
}
IdentValue maybeIdent = val.isIdentValue();
if (maybeIdent == null) {
// Not an ident, append as-is to result
result.add(val);
continue;
}
String identStr = maybeIdent.getIdent();
CssDef def = substitutions.get(identStr);
if (def == null) {
// No substitution found, append as-is to result
result.add(val);
continue;
} else if (def instanceof CssUrl) {
assert def.getValues().size() == 1;
assert def.getValues().get(0).isDotPathValue() != null;
DotPathValue functionName = def.getValues().get(0).isDotPathValue();
JType methodType = null;
try {
methodType = ResourceGeneratorUtil.getMethodByPath(context.getClientBundleType(),
functionName.getParts(), null).getReturnType();
} catch (NotFoundException e) {
logger.log(TreeLogger.ERROR, e.getMessage());
throw new CssCompilerException("Cannot find data method");
}
if (!(methodType instanceof JClassType) ||
(!dataResourceType.isAssignableFrom((JClassType) methodType) &&
!imageResourceType.isAssignableFrom((JClassType) methodType))) {
String message = "Invalid method type for url substitution: " + methodType + ". " +
"Only DataResource and ImageResource are supported.";
logger.log(TreeLogger.ERROR, message);
throw new CssCompilerException(message);
}
StringBuilder expression = new StringBuilder();
expression.append("\"url('\" + ");
expression.append(context.getImplementationSimpleSourceName());
expression.append(".this.");
expression.append(functionName.getExpression());
expression.append(".getSafeUri().asString()");
expression.append(" + \"')\"");
result.add(new ExpressionValue(expression.toString()));
} else {
for (Value defValue : def.getValues()) {
result.add(defValue);
}
}
}
return new ListValue(result);
}