@Override public JExpression injectMagic(final TreeLogger logger, final JMethodCall methodCall, final JMethod enclosingMethod, final Context context, final UnifyAstView ast) throws UnableToCompleteException { final JExpression ctorProvider = super.injectMagic(logger, methodCall, enclosingMethod, context, ast); // Find the invoker method // call the newInstance method on the result of our ctorProvider final JDeclaredType ctor = ast.searchForTypeBySource(Constructor.class.getName()); for (final JMethod method : ctor.getMethods()) { if (method.getName().equals("newInstance")) { final JMethodCall call = new JMethodCall(methodCall.getSourceInfo().makeChild(), ctorProvider, method); call.addArg(methodCall.getArgs().get(2)); return call; } } logger.log(Type.ERROR, "Unable to implement GwtReflect.construct from "+methodCall.toSource()); throw new UnableToCompleteException(); }
public static JClassLiteral extractClassLiteral(TreeLogger logger, JMethodCall methodCall, int paramPosition, UnifyAstView ast) throws UnableToCompleteException { List<JExpression> args = methodCall.getArgs(); JExpression arg = args.get(paramPosition); JClassLiteral classLit = extractClassLiteral(logger, arg, ast, false); if (classLit == null) { logger.log(Type.ERROR, "The method " + methodCall.getTarget().toSource() + " only accepts class literals." + " You sent a " + arg.getClass() + " : " + arg.toSource()+" from method " + methodCall.toSource()+ " with argumetsn " + methodCall.getArgs()+ ";"); throw new UnableToCompleteException(); } return classLit; }
@Override public JExpression injectMagic(final TreeLogger logger, final JMethodCall callSite, final JMethod enclosingMethod, final Context context, final UnifyAstView ast) throws UnableToCompleteException { final boolean isFromGwtReflect = callSite.getArgs().size() == 2; final JExpression inst = isFromGwtReflect ? callSite.getArgs().get(0) : callSite.getInstance(); final JClassLiteral classLit = ReflectionUtilAst.extractClassLiteral(logger, inst, ast, false); final List<JExpression> args = callSite.getArgs(); final 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(); }
protected JMethodCall checkConstPool(UnifyAstView ast, JMethodCall callSite, JExpression classRef, JExpression ... args) throws UnableToCompleteException { com.google.gwt.dev.jjs.ast.JMethod initPool = getMemberPoolInit(ast); JMethodCall getMemberPool = new JMethodCall(initPool.getSourceInfo(), null, initPool); getMemberPool.addArg(classRef); ManifestMap map = manifests.get(); com.google.gwt.dev.jjs.ast.JMethod getter = map.findGetterFor(ast, memberGetter()); JMethodCall checkPool = new JMethodCall(initPool.getSourceInfo(), getMemberPool, getter); for (JExpression arg : args) { checkPool.addArg(arg); } return checkPool; }
findMethods(ast); final JClassLiteral clazz = ReflectionUtilAst.extractClassLiteral(logger, methodCall, 0, ast, false); final SourceInfo info = methodCall.getSourceInfo().makeChild(); if (clazz == null) { final JExpression[] args = methodCall.getArgs().toArray(new JExpression[2]); return new JMethodCall(info, null, newArrayMethod, args); final List<JExpression> args = methodCall.getArgs(); List<JExpression> emptyDims = Lists.create(), sizedDims; JType type = ast.translate(clazz.getRefType()); final List<JExpression> dims = Lists.addAll(sizedDims, emptyDims); final JNewArray newArr = new JNewArray(info, (JArrayType)type, dims, null, classLiteral); return new JMethodCall(info, null, registerArray, newArr, new JClassLiteral(info.makeChild(), type));
SourceInfo methodSource = methodCall.getSourceInfo().makeChild(SourceOrigin.UNKNOWN); JMethod newMethod = new JMethod(methodSource, "enhanceAll", methodCall.getTarget().getEnclosingType(), ast.getProgram().getTypeVoid(), false, true, true, AccessModifier.PUBLIC); newMethod.setOriginalTypes(ast.getProgram().getTypeVoid(), methodCall.getTarget().getOriginalParamTypes()); JMethodBody body = new JMethodBody(methodSource); newMethod.setBody(body); continue; JMethodCall call = new JMethodCall(methodSource.makeChild(SourceOrigin.UNKNOWN), null, magicClass); call.addArg(new JClassLiteral(methodSource.makeChild(SourceOrigin.UNKNOWN), asType)); JExpression invoke = MagicClassInjector.injectMagicClass(logger, call, magicClass, context, ast); if (invoke != null) block.addStmt(invoke.makeStatement()); block.addStmts(((JMethodBody)methodCall.getTarget().getBody()).getStatements()); methodCall.getTarget().getEnclosingType().addMethod(newMethod); JMethodCall call = new JMethodCall(methodSource, null, newMethod); return call.makeStatement().getExpr();
@SuppressWarnings("deprecation") private JExpression handleImplNameOf(final JMethodCall x) { assert (x.getArgs().size() == 1); JExpression arg = x.getArgs().get(0); if (!(arg instanceof JStringLiteral)) { error(x, "Only string literals may be used as arguments to Impl.getNameOf()"); return new JNameOf(x.getSourceInfo(), program.getTypeJavaLangString(), (HasName) node);
/** * Implements a caching layer guarding the {@link #initialize(String, ReflectionGeneratorContext)} method * * @param key * @param params * @return */ protected JExpression get(String key, ReflectionGeneratorContext params) { //because we cache results, super dev mode recompiles need to skip the //cache if the magic class does not exist, thus we test type presence on every get(). JDeclaredType type = params.getAst().searchForTypeByBinary(params.getClazz().getRefType().getName()); String typeName = JGwtCreate.nameOf(type); String generatedName = ReflectionUtilJava.generatedMagicClassName(typeName); try { params.getAst().searchForTypeBySource(generatedName); }catch(NoClassDefFoundError e) { classEnhancers.remove(key); } if (classEnhancers.containsKey(key)) { JMethodCall previous = classEnhancers.get(key); previous = new JMethodCall(previous, previous.getInstance()); previous.addArg(params.getClazz().makeStatement().getExpr()); return previous.makeStatement().getExpr(); } JMethodCall expr = initialize(key, params); classEnhancers.put(key, expr); expr.setArg(0, params.getClazz().makeStatement().getExpr()); return expr.makeStatement().getExpr(); }
private void processThisCallLocalArgs(ReferenceBinding binding, JMethodCall call) { if (binding.syntheticOuterLocalVariables() != null) { for (SyntheticArgumentBinding arg : binding.syntheticOuterLocalVariables()) { JParameter param = (JParameter) curMethod.locals.get(arg); assert param != null; call.addArg(new JParameterRef(call.getSourceInfo(), param)); } } }
call.addArgs(getStringLiteral(info, x.enumConstant.name), JIntLiteral .get(x.enumConstant.binding.original().id)); argType = (ReferenceBinding) argType.erasure(); if (qualifier != null && argType == targetEnclosingType) { call.addArg(qualExpr); } else { JExpression thisRef = makeThisReference(info, argType, false, scope); call.addArg(thisRef); call.addArgs(arguments); JField field = curClass.syntheticFields.get(sb); assert field != null; call.addArg(makeInstanceFieldRef(info, field)); } else if (path[0] instanceof LocalVariableBinding) { JExpression localRef = makeLocalRef(info, (LocalVariableBinding) path[0]); call.addArg(localRef); } else if (path[0] instanceof FieldBinding) { JField field = typeMap.get((FieldBinding) path[0]); assert field != null; call.addArg(makeInstanceFieldRef(info, field)); } else { throw new InternalCompilerException("Unknown emulation path."); assert staticBinding.isStatic(); JMethod staticMethod = typeMap.get(staticBinding); JMethodCall newCall = new JMethodCall(info, null, staticMethod); newCall.addArgs(call.getArgs());
throws UnableToCompleteException { final boolean isDebug = logger.isLoggable(logLevel()); final boolean isFromGwtReflect = callSite.getArgs().size() > 1; final JExpression inst = isFromGwtReflect ? callSite.getArgs().get(0) : callSite.getInstance(); final JExpression annoParam = callSite.getArgs().get(isFromGwtReflect ? 1 : 0); logger.log(logLevel(), "Generating annotation provider for "+annotation+" @ "+callSite.toSource()); return new JFieldRef(callSite.getSourceInfo().makeChild(), null, field, type);
private JExpression unbox(JExpression original, int implicitConversion) { int typeId = implicitConversion & TypeIds.COMPILE_TYPE_MASK; ClassScope scope = curClass.scope; BaseTypeBinding primitiveType = (BaseTypeBinding) TypeBinding.wellKnownType(scope, typeId); ReferenceBinding boxType = (ReferenceBinding) scope.boxing(primitiveType); char[] selector = CharOperation.concat(primitiveType.simpleName, VALUE); MethodBinding valueMethod = boxType.getExactMethod(selector, NO_TYPES, scope.compilationUnitScope()); assert valueMethod != null; JMethod unboxMethod = typeMap.get(valueMethod); JMethodCall call = new JMethodCall(original.getSourceInfo(), original, unboxMethod); return call; }
JConstructor ctor = (JConstructor) typeMap.get(x.binding); JExpression trueQualifier = makeThisRef(info); JMethodCall call = new JMethodCall(info, trueQualifier, ctor); List<JExpression> callArgs = popCallArgs(info, x.arguments, x.binding); call.addArg(enumNameRef); JParameterRef enumOrdinalRef = new JParameterRef(info, curMethod.method.getParams().get(1)); call.addArg(enumOrdinalRef); processSuperCallThisArgs(superClass, call, qualifier, x.qualification); call.addArgs(callArgs); if (nestedSuper) { processSuperCallLocalArgs(superClass, call); processThisCallThisArgs(declaringClass, call); call.addArgs(callArgs); if (nested) { processThisCallLocalArgs(declaringClass, call); call.setStaticDispatchOnly(); push(call.makeStatement()); } catch (Throwable e) { throw translateException(x, e);
info.addCorrelation(info.getCorrelator().by(getSingleton)); final JMethodCall call = new JMethodCall(info, expr, method); final JReturnStatement value = new JReturnStatement(x.getSourceInfo(), call); if (enclosing.getClinitTarget() != null) { final JMethod clinitMethod = clinit.getMethods().get(0); assert (JProgram.isClinit(clinitMethod)); final JMethodCall doClinit = new JMethodCall(clinit.getSourceInfo(), null, clinitMethod); body.getBlock().addStmt(doClinit.makeStatement()); expr = new JMethodCall(info, null, getSingleton); cachedProviders.put(type, expr); return expr;
JMethodCall call = new JMethodCall(info, makeThisRef(info), implmeth); for (int i = 0; i < bridgeMethod.getParams().size(); i++) { JParameter param = bridgeMethod.getParams().get(i); JParameterRef paramRef = new JParameterRef(info, param); call.addArg(maybeCast(implParams.get(i).getType(), paramRef)); body.getBlock().addStmt(call.makeStatement()); } else { body.getBlock().addStmt(new JReturnStatement(info, call));
/** * @param ast * @param logger * @param callSite * @return * @throws UnableToCompleteException */ public JExpression throwNotFoundException(final TreeLogger logger, final JMethodCall callSite, final UnifyAstView ast) throws UnableToCompleteException { final SourceInfo sourceInfo = callSite.getSourceInfo().makeChild(); final MemberPoolMethods memberMap = memberPoolMethods.get(); final IsQualified exceptionType = getNotFoundExceptionType(); final JConstructor ctor = memberMap.findConstructor(logger, exceptionType.getQualifiedName(), exceptionType.getSimpleName()+"() <init>", ast); final JNewInstance newThrowable = new JNewInstance(sourceInfo, ctor); final JMethod throwMethod = memberMap.getThrowMethod(logger, ast); return new JMethodCall(sourceInfo, null, throwMethod, newThrowable); }
assert (methodCall.getArgs().size() == 2); final JExpression classParam = methodCall.getArgs().get(0); final JExpression receiveParam = methodCall.getArgs().get(1); if (!(classParam instanceof JClassLiteral)) { ast.error( return new JMethodCall(method.getSourceInfo(), null, method);
mapClass.addField(mapField); JMethodCall call = new JMethodCall(info, null, typeMap.get(createValueOfMapBinding)); call.addArg(new JFieldRef(info, null, valuesField, mapClass)); JFieldRef mapRef = new JFieldRef(info, null, mapField, mapClass); JDeclarationStatement declStmt = new JDeclarationStatement(info, mapRef, call); JMethodCall call = new JMethodCall(info, null, typeMap.get(valueOfBinding)); call.addArgs(mapRef, nameRef); implementMethod(method, call);
/** * Replaces a call from {@link X_Inject#singleton(Class)} by first a-0) generating a provider which will be * synchronous if an async call hasn't already been made, or a-1) generating a provider which will route * through the async provider, and return null before inited. then b) creates a lazy provider to call into * the synchronous provider finally c) calls .get() on the provider and return the value. If you use the * {@link X_Inject#singletonAsync(Class, xapi.util.api.ReceivesValue)} once, you should not use the * other two synchronous provider methods, as they may return null if you happen to request them before the * code split containing the service is downloaded. * * @param logger - The logger to log to. * @param methodCall - The method call we are overwriting * @param currentMethod - The encapsulated method itself * @param context - The method call context, so you can insert clinits / whatnot * @param ast - A view over UnifyAst, exposing our basic needs * @return - A JExpression to replace this method call with * @throws UnableToCompleteException */ public static JExpression rebindSingleton(final TreeLogger logger, final JMethodCall x, final JMethod currentMethod, final Context context, final UnifyAstView ast) throws UnableToCompleteException { assert (x.getArgs().size() == 1); final JExpression arg = x.getArgs().get(0); if (!(arg instanceof JClassLiteral)) { ast.error(x, "Only class literals may be used as arguments to X_Inject.lazySingleton; you sent " + arg.getClass() + " - " + arg); return null; } final JClassLiteral classLiteral = (JClassLiteral)arg; return injectSingleton(logger, classLiteral, x, ast); }