}
private void processArtificialRescue(Annotation rescue) {
assert rescue != null;
JReferenceType classType = null;
String[] fields = Empty.STRINGS;
boolean instantiable = false;
String[] methods = Empty.STRINGS;
String typeName = null;
for (MemberValuePair pair : rescue.memberValuePairs()) {
String name = String.valueOf(pair.name);
Expression value = pair.value;
if ("className".equals(name)) {
typeName = value.constant.stringValue();
// Invalid references should be caught in ArtificialRescueChecker
classType = (JReferenceType) program.getTypeFromJsniRef(typeName);
} else if ("fields".equals(name)) {
if (value instanceof StringLiteral) {
fields = new String[] {value.constant.stringValue()};
} else if (value instanceof ArrayInitializer) {
ArrayInitializer init = (ArrayInitializer) value;
fields = new String[init.expressions == null ? 0
: init.expressions.length];
for (int i = 0, j = fields.length; i < j; i++) {
fields[i] = init.expressions[i].constant.stringValue();
}
}
} else if ("instantiable".equals(name)) {
instantiable = value.constant.booleanValue();
} else if ("methods".equals(name)) {
if (value instanceof StringLiteral) {
methods = new String[] {value.constant.stringValue()};
} else if (value instanceof ArrayInitializer) {
ArrayInitializer init = (ArrayInitializer) value;
methods = new String[init.expressions == null ? 0
: init.expressions.length];
for (int i = 0, j = methods.length; i < j; i++) {
methods[i] = init.expressions[i].constant.stringValue();
}
}
} else {
throw new InternalCompilerException(
"Unknown Rescue annotation member " + name);
}
}
assert classType != null : "classType " + typeName;
assert fields != null : "fields";
assert methods != null : "methods";
if (instantiable) {
currentClass.addArtificialRescue(classType);
// Make sure that a class literal for the type has been allocated
program.getLiteralClass(classType);
}
if (classType instanceof JDeclaredType) {
List<String> toRescue = new ArrayList<String>();
Collections.addAll(toRescue, fields);
Collections.addAll(toRescue, methods);
for (String name : toRescue) {
JsniRef ref = JsniRef.parse("@" + classType.getName() + "::" + name);
final String[] errors = {null};
HasEnclosingType node = JsniRefLookup.findJsniRefTarget(ref, program,
new JsniRefLookup.ErrorReporter() {
public void reportError(String error) {
errors[0] = error;