/** * Creates a synthetic forwarding stub in {@code type} with the same signature as {@code * superTypeMethod} that dispatchs to that method.. */ public static JMethod createForwardingMethod(JDeclaredType type, JMethod methodToDelegateTo) { JMethod forwardingMethod = createEmptyMethodFromExample(type, methodToDelegateTo, false); forwardingMethod.setForwarding(); // This is a synthetic forwading method due to a default. if (methodToDelegateTo.isDefaultMethod()) { forwardingMethod.setDefaultMethod(); } // Create the forwarding body. JMethodBody body = (JMethodBody) forwardingMethod.getBody(); // Invoke methodToDelegate JMethodCall forwardingCall = new JMethodCall( methodToDelegateTo.getSourceInfo(), new JThisRef(methodToDelegateTo.getSourceInfo(), type), methodToDelegateTo); forwardingCall.setStaticDispatchOnly(); // copy params for (JParameter p : forwardingMethod.getParams()) { forwardingCall.addArg(new JParameterRef(p.getSourceInfo(), p)); } // return statement if not void return type body.getBlock().addStmt(makeMethodEndStatement(forwardingMethod.getType(), forwardingCall)); return forwardingMethod; }
private static JMethod createEmptyMethodFromExample( JDeclaredType inType, JMethod exampleMethod, boolean isAbstract) { JMethod emptyMethod = new JMethod( exampleMethod.getSourceInfo(), exampleMethod.getName(), inType, exampleMethod.getType(), isAbstract, false, false, exampleMethod.getAccess()); emptyMethod.addThrownExceptions(exampleMethod.getThrownExceptions()); emptyMethod.setSynthetic(); // Copy parameters. for (JParameter param : exampleMethod.getParams()) { emptyMethod.addParam( new JParameter( param.getSourceInfo(), param.getName(), param.getType(), param.isFinal(), param.isThis(), emptyMethod)); } JMethodBody body = new JMethodBody(exampleMethod.getSourceInfo()); emptyMethod.setBody(body); emptyMethod.freezeParamTypes(); inType.addMethod(emptyMethod); return emptyMethod; }
public JExpression doRebind(String clsName, ReflectionGeneratorContext params) throws UnableToCompleteException { // generate params.getLogger().log(Type.INFO, "Binding magic class for " + clsName); // JType type = params.getClazz().getRefType(); JDeclaredType type = params.getAst().searchForTypeBySource(params.getClazz().getRefType().getName()); StandardGeneratorContext ctx = params.getGeneratorContext(); Class<? extends Generator> generator = MagicClassGenerator.class; String result = ctx.runGenerator(params.getLogger(), generator, SourceUtil.toSourceName(type.getName())); ctx.finish(params.getLogger()); params.getLogger().log(Type.INFO, "Generated Class Enhancer: " + result); JDeclaredType success = params.getAst().searchForTypeBySource(result); // Okay, we've generated the correct magic class subtype; // Now pull off its static accessor method to grab our generated class. for (JMethod method : success.getMethods()) { if (method.isStatic() && method.getName().equals("enhanceClass")) { JMethodCall call = new JMethodCall(method.getSourceInfo(), null, method); call.addArg(params.getClazz().makeStatement().getExpr()); return call; } } params.getLogger().log(Type.ERROR, "Unable to load " + result + ".enhanceClass()"); throw new UnableToCompleteException(); }