argTypes = new GeneratorTypeInfo[0];
}
GeneratorTypeInfo objectType = inType;
boolean searchingThis = objectType.equals(myClass);
boolean asyncMethod = false;
GeneratorMethodInfo getterMethod = null;
for(;;) {
GeneratorTypeInfo[] syncArgTypesWildcard = new GeneratorTypeInfo[argTypes.length];
GeneratorTypeInfo[] asyncArgTypesWildcard = new GeneratorTypeInfo[argTypes.length+1];
asyncArgTypesWildcard[argTypes.length] = commonTypes.asyncCallback;
GeneratorTypeInfo[] asyncArgTypes = Arrays.copyOf(argTypes, argTypes.length+1);
asyncArgTypes[argTypes.length] = commonTypes.asyncCallback;
HashSet<String> candidates = new HashSet<String>();
candidates.add(getterMethodName);
String capGetterMethodName = capitalize(getterMethodName);
candidates.add("get"+capGetterMethodName);
candidates.add("is"+capGetterMethodName);
for(String candidate : candidates) {
getterMethod = objectType.findMethodMatching(candidate, true, null, argTypes);
if(getterMethod == null)
getterMethod = objectType.findMethodMatching(candidate, true, null, syncArgTypesWildcard);
if(getterMethod != null) {
asyncMethod = false;
type = getterMethod.getReturnType();
break;
}
if(matchAsync) {
getterMethod = objectType.findMethodMatching(candidate, true, null, asyncArgTypes);
if(getterMethod == null)
getterMethod = objectType.findMethodMatching(candidate, true, null, asyncArgTypesWildcard);
if(getterMethod != null) {
asyncMethod = true;
type = getterMethod.getAsyncReturnType();
if(type == null) type = commonTypes.object;
break;
}
}
}
if(searchingThis && getterMethod == null && objectType instanceof GeneratedInnerClassInfo) {
objectType = objectType.getFieldType(PARENT_VIEW_FIELD_NAME, true);
if(objectType == null)
break;
expr = expr+"."+PARENT_VIEW_FIELD_NAME;
//System.out.println("Ascending to "+expr+" "+objectType);
} else break;
}
if (getterMethod == null) {
logger.log(TreeLogger.ERROR, "findAccessors(): Unable to find a "+(staticAccess?"static":"instance")+" method with the right number of arguments ("
+ args.length + (matchAsync?" [ + optional AsyncCallback]":"")+") with name '" + getterMethodName + "' in " + inType
+ " for expression '" + path + "'", null);
throw new UnableToCompleteException();
}
StringBuffer getterBuf = new StringBuffer();
getterBuf.append(expr).append('.').append(getterMethod.getName()).append('(');
for (int i = 0; i < args.length; i++) {
if(i > 0) getterBuf.append(", ");
getterBuf.append(args[i].conversionExpr(getterMethod.getParameterTypes()[i]));
}
if(asyncMethod) {
if(args.length > 0) getterBuf.append(","); // trailing comma for async methods so we can append the callback parameter when we call the method
} else getterBuf.append(')');
getter = getterBuf.toString();
asyncGetter = asyncMethod;
type = asyncMethod?getterMethod.getAsyncReturnType():getterMethod.getReturnType();
// Find the matching setter method (if any).
String setterMethodName = getterMethod.getName().replaceFirst("^(is|get)", "set");
GeneratorTypeInfo[] setterArgTypes = Arrays.copyOf(argTypes, argTypes.length+1);
setterArgTypes[argTypes.length] = type;
GeneratorMethodInfo setterMethod = objectType.findMethodMatching(setterMethodName, true, null, setterArgTypes);
// If searching for something matching the types we got doesn't work, try it a wildcard for the type
if(setterMethod == null) {
setterArgTypes = new GeneratorTypeInfo[argTypes.length+1];
setterArgTypes[argTypes.length] = type;
setterMethod = objectType.findMethodMatching(setterMethodName, true, null, setterArgTypes);
}
if(setterMethod == null) {
setterArgTypes = Arrays.copyOf(argTypes, argTypes.length+2);
setterArgTypes[argTypes.length] = type;
setterArgTypes[argTypes.length+1] = commonTypes.asyncCallback;
setterMethod = objectType.findMethodMatching(setterMethodName, true, PrimitiveTypeInfo.VOID, setterArgTypes);
if(setterMethod == null) {
setterArgTypes = new GeneratorTypeInfo[argTypes.length+2];
setterArgTypes[argTypes.length] = type;
setterArgTypes[argTypes.length+1] = commonTypes.asyncCallback;
setterMethod = objectType.findMethodMatching(setterMethodName, true, PrimitiveTypeInfo.VOID, setterArgTypes);
}
if(setterMethod != null)
asyncSetter = true;
} else {
asyncSetter = false;
}
if(setterMethod != null) {
StringBuffer setterBuf = new StringBuffer();
setterBuf.append(expr).append('.').append(setterMethod.getName()).append('(');
for (int i = 0; i < args.length; i++) {
if(i > 0) setterBuf.append(", ");
String convertedArg = args[i].conversionExpr(setterMethod.getParameterTypes()[i]);
if(convertedArg.isEmpty()) {
throw new IllegalStateException("Got empty result back from "+args[i]+" converted to "+setterMethod.getParameterTypes()[i]);
}
setterBuf.append(convertedArg);
}
if(args.length > 0)
setterBuf.append(","); // trailing comma for setters so we can append the value parameter and possibly the async callback
setter = setterBuf.toString();
}
} else {
// No array or function specifier, so look for a normal property or field
String baseExpr = (expr.equals("this") ? "" : expr + ".");
name = identifier(name);
String getterName = "get" + capitalize(name);
String setterName = "set" + capitalize(name);
GeneratorMethodInfo getterMethod = inType.findMethodMatching(getterName, true, null);
if(getterMethod == null && matchAsync) { // Check for async version, if allowed in this context
getterMethod = inType.findMethodMatching(getterName, true, PrimitiveTypeInfo.VOID, commonTypes.asyncCallback);
asyncGetter = getterMethod != null;
}
if (getterMethod == null) {
getterName = "is" + capitalize(name);
getterMethod = inType.findMethodMatching(getterName, true, null);
if(getterMethod == null && matchAsync) { // Check for async version, if allowed in this context
getterMethod = inType.findMethodMatching(getterName, true, PrimitiveTypeInfo.VOID, commonTypes.asyncCallback);
asyncGetter = getterMethod != null;
}
}
if (getterMethod != null) {
getter = baseExpr + getterName + (asyncGetter?"":"()"); // No trailing brackets for an async call
if(asyncGetter) {
type = getterMethod.getAsyncReturnType();
if(type == null) type = commonTypes.object;
} else {
type = getterMethod.getReturnType();
}
} else {
asyncGetter = false;
// Try direct field access
type = inType.getFieldType(name, baseExpr.startsWith("this."));
if(type != null) {
getter = baseExpr + name;
setter = baseExpr + name + "=";
asyncSetter = false;
asyncGetter = false;
} else {
getter = null;
}
}
if(setter == null) {
GeneratorMethodInfo setterMethod;
// Only look for the setter if this is the last (or only) part of the chain. i.e. for an expression
// a.b.c we would only look for a setter for c, not a or b.
if(lastOrOnlyPartOfTheExpression) {
setterMethod = inType.findMethodMatching(setterName, true, null, (GeneratorTypeInfo)null);
if(setterMethod == null) {
setterMethod = inType.findMethodMatching(setterName, true, PrimitiveTypeInfo.VOID, (GeneratorTypeInfo)null, commonTypes.asyncCallback);
asyncSetter = setterMethod != null;
}
if(setterMethod != null) {
//System.out.println("Found setter "+setterMethod);
setter = baseExpr + setterName + "(";
type = setterMethod.getParameterTypes()[0];
}
}
}
}