![JAR search and dependency download from the Maven repository](/logo.png)
com.google.gwt.reflect.rebind.generators.FieldGenerator Maven / Gradle / Ivy
package com.google.gwt.reflect.rebind.generators;
import java.util.List;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.TreeLogger.Type;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.dev.jjs.MagicMethodGenerator;
import com.google.gwt.dev.jjs.UnifyAstView;
import com.google.gwt.dev.jjs.ast.Context;
import com.google.gwt.dev.jjs.ast.JClassLiteral;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JExpression;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JMethodCall;
import com.google.gwt.dev.jjs.ast.JStringLiteral;
import com.google.gwt.dev.jjs.ast.JType;
import com.google.gwt.reflect.rebind.ReflectionManifest;
import com.google.gwt.reflect.rebind.ReflectionUtilAst;
import com.google.gwt.reflect.rebind.ReflectionUtilType;
public abstract class FieldGenerator extends MemberGenerator implements MagicMethodGenerator {
protected abstract boolean isDeclared();
protected JMethodCall getFactoryMethod(TreeLogger logger, JMethodCall callSite,
JMethod enclosingMethod, Context context, JClassLiteral classLit, JExpression inst, JExpression arg0, UnifyAstView ast)
throws UnableToCompleteException {
if (classLit == null) {
if (logger.isLoggable(logLevel()))
logger.log(logLevel(),
"Non-final class literal used to invoke reflection field; "
+ ReflectionUtilAst.debug(callSite.getInstance()));
return checkConstPool(ast, callSite, inst, arg0);
}
JStringLiteral stringLit = ReflectionUtilAst.extractImmutableNode(logger, JStringLiteral.class, arg0, ast, false);
if (stringLit == null) {
if (logger.isLoggable(logLevel()))
logger.log(logLevel(),
"Non-final string arg used to retrieve reflection field; "
+ ReflectionUtilAst.debug(arg0));
return checkConstPool(ast, callSite, inst, arg0);
}
String name = stringLit.getValue();
// We got all our literals; the class, method name and parameter classes
// now get the requested method
JType ref = classLit.getRefType();
JClassType oracleType = ast.getTypeOracle().findType(ref.getName().replace('$', '.'));
com.google.gwt.core.ext.typeinfo.JField field =
ReflectionUtilType.findField(logger, oracleType, name, isDeclared());
if (field == null) {
// We fail here because the requested method is not findable.
if (shouldFailIfMissing(logger, ast, classLit)) {
logger.log(Type.ERROR, "Unable to find field " + oracleType.getQualifiedSourceName()+"."+name+ ";");
logger.log(Type.ERROR, "Did you forget to call StandardGeneratorContext.finish()?");
throw new UnableToCompleteException();
} else {
return checkConstPool(ast, callSite, inst, arg0);
}
}
if (logger.isLoggable(logLevel())) {
logger.log(logLevel(), "Found injectable field " + field);
}
// now, get or make a handle to the requested method,
return getFieldProvider(logger, ast, field, classLit, isDeclared());
}
@Override
public JExpression injectMagic(TreeLogger logger, JMethodCall callSite,
JMethod enclosingMethod, Context context, UnifyAstView ast)
throws UnableToCompleteException {
boolean isFromGwtReflect = callSite.getArgs().size() == 2;
JExpression inst = isFromGwtReflect ? callSite.getArgs().get(0) : callSite.getInstance();
JClassLiteral classLit = ReflectionUtilAst.extractClassLiteral(logger, inst, ast, false);
List args = callSite.getArgs();
JExpression arg0 = args.get(isFromGwtReflect?1:0);
// and return a call to the generated Method provider
return
getFactoryMethod(logger, callSite, enclosingMethod, context, classLit, inst, arg0, ast)
.makeStatement().getExpr();
}
public JMethodCall getFieldProvider(TreeLogger logger, UnifyAstView ast, com.google.gwt.core.ext.typeinfo.JField field,
JClassLiteral classLit, boolean declaredOnly) throws UnableToCompleteException {
String clsName = classLit.getRefType().getName();
ReflectionManifest manifest = ReflectionManifest.getReflectionManifest(logger, clsName, ast.getGeneratorContext());
String factoryCls = getOrMakeFieldFactory(logger, ast.getRebindPermutationOracle().getGeneratorContext(), field, field.getEnclosingType(), manifest, declaredOnly);
ast.getGeneratorContext().finish(logger);
JDeclaredType factory = ast.searchForTypeBySource(factoryCls);
// pull out the static accessor method
for (JMethod factoryMethod : factory.getMethods()) {
if (factoryMethod.isStatic() && factoryMethod.getName().equals("instantiate")) {
return new JMethodCall(factoryMethod.getSourceInfo(), null, factoryMethod);
}
}
logger.log(Type.ERROR, "Unable to find static initializer for Field subclass "+factoryCls);
throw new UnableToCompleteException();
}
public String getOrMakeFieldFactory(TreeLogger logger, GeneratorContext ctx, com.google.gwt.core.ext.typeinfo.JField field,
com.google.gwt.core.ext.typeinfo.JType classType, ReflectionManifest manifest, boolean declaredOnly) throws UnableToCompleteException {
// get cached manifest for this type
String clsName = classType.getQualifiedSourceName();
TypeOracle oracle = ctx.getTypeOracle();
String name = field.getName();
JClassType cls = oracle.findType(clsName);
if (cls == null) {
logger.log(Type.ERROR, "Unable to find enclosing class "+clsName);
throw new UnableToCompleteException();
}
String fieldFactoryName = getFieldFactoryName(cls, name);
JClassType factory;
String pkgName = field.getEnclosingType().getPackage().getName();
factory = oracle.findType(pkgName, fieldFactoryName);
if (factory == null) {
return generateFieldFactory(logger, ctx, field, fieldFactoryName, manifest);
} else
return (pkgName.length()==0?"":pkgName+".")+ fieldFactoryName;
}
@Override
protected String memberGetter() {
return "get"+(isDeclared()?"Declared":"")+"Field";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy