// further field dereferences
// factor off a typename from the path
Type rootType = typeGroup.match(pathList);
if (rootType == null) {
throw new TypeException("FieldExpression.typeCheck : invalid path " + getPath(pathList.length) + " to static method " + name + getPos());
}
// find out how many of the path elements are included in the type name
String rootTypeName = rootType.getName();
int idx = getPathCount(rootTypeName);
if (idx < pathList.length) {
// create a static field reference using the type name and the first field name and wrap it with
// enough field references to use up all the path
String fieldName = pathList[idx++];
Expression recipient = new StaticExpression(rule, Type.UNDEFINED, token, fieldName, rootTypeName);
while (idx < pathList.length) {
recipient = new FieldExpression(rule, Type.UNDEFINED, token, pathList[idx++], recipient, null);
}
this.recipient = recipient;
} else {
// ok, this method reference is actually a static method call -- record the root type for later
this.recipient = null;
this.rootType = rootType;
}
// get rid of the path list now
this.pathList = null;
// not strictly necessary?
if (this.recipient != null) {
this.recipient.bind();
}
}
// if we don't have a recipient and we didn't find a static class for the method then this is
// a builtin
boolean isBuiltIn = false;
if (recipient == null) {
if (rootType == null) {
isBuiltIn = true;
Type ruleType = typeGroup.create(rule.getHelperClass().getCanonicalName());
recipient = new DollarExpression(rule, ruleType, token, DollarExpression.HELPER_IDX);
recipient.bind();
rootType = recipient.typeCheck(Type.UNDEFINED);
}
} else {
rootType = recipient.typeCheck(Type.UNDEFINED);
}
// see if we can find a method for this call
findMethod(isBuiltIn);
// now go back and identify the parameter types
this. paramTypes = new ArrayList<Type>();
Class<?>[] paramClasses = method.getParameterTypes();
for (int i = 0; i < arguments.size(); i++) {
Class<?> paramClass = paramClasses[i];
paramTypes.add(typeGroup.ensureType(paramClass));
}
type = typeGroup.ensureType(method.getReturnType());
if (Type.dereference(expected).isDefined() && !expected.isAssignableFrom(type)) {
throw new TypeException("MethodExpression.typeCheck : invalid expected type " + expected.getName() + getPos());
}
return type;
}