use of io.micronaut.inject.ast.ParameterElement in project micronaut-core by micronaut-projects.
the class AbstractClassFileWriter method getConstructorDescriptor.
/**
* @param argList The argument list
* @return The constructor descriptor
*/
protected static String getConstructorDescriptor(Collection<ParameterElement> argList) {
StringBuilder builder = new StringBuilder();
builder.append('(');
for (ParameterElement argumentType : argList) {
builder.append(getTypeDescriptor(argumentType));
}
return builder.append(")V").toString();
}
use of io.micronaut.inject.ast.ParameterElement in project micronaut-core by micronaut-projects.
the class AbstractClassFileWriter method pushBuildArgumentsForMethod.
/**
* @param declaringElementName The declaring element name
* @param owningType The owning type
* @param declaringClassWriter The declaring class writer
* @param generatorAdapter The {@link GeneratorAdapter}
* @param argumentTypes The argument types
* @param defaults The annotation defaults
* @param loadTypeMethods The load type methods
*/
protected static void pushBuildArgumentsForMethod(String declaringElementName, Type owningType, ClassWriter declaringClassWriter, GeneratorAdapter generatorAdapter, Collection<ParameterElement> argumentTypes, Map<String, Integer> defaults, Map<String, GeneratorAdapter> loadTypeMethods) {
int len = argumentTypes.size();
pushNewArray(generatorAdapter, Argument.class, len);
int i = 0;
for (ParameterElement entry : argumentTypes) {
// the array index position
generatorAdapter.push(i);
ClassElement classElement = entry.getGenericType();
String argumentName = entry.getName();
AnnotationMetadata annotationMetadata = entry.getAnnotationMetadata();
Map<String, ClassElement> typeArguments = classElement.getTypeArguments();
pushCreateArgument(declaringElementName, owningType, declaringClassWriter, generatorAdapter, argumentName, classElement, annotationMetadata, typeArguments, defaults, loadTypeMethods);
// store the type reference
generatorAdapter.visitInsn(AASTORE);
// if we are not at the end of the array duplicate array onto the stack
if (i != (len - 1)) {
generatorAdapter.visitInsn(DUP);
}
i++;
}
}
use of io.micronaut.inject.ast.ParameterElement in project micronaut-core by micronaut-projects.
the class AopProxyWriter method buildMethodDelegate.
private void buildMethodDelegate(MethodElement methodElement, MethodElement overriddenBy, boolean isVoidReturn) {
String desc = getMethodDescriptor(methodElement.getReturnType().getType(), Arrays.asList(methodElement.getSuspendParameters()));
MethodVisitor overridden = classWriter.visitMethod(ACC_PUBLIC, methodElement.getName(), desc, null, null);
GeneratorAdapter overriddenMethodGenerator = new GeneratorAdapter(overridden, ACC_PUBLIC, methodElement.getName(), desc);
overriddenMethodGenerator.loadThis();
int i = 0;
for (ParameterElement param : methodElement.getSuspendParameters()) {
overriddenMethodGenerator.loadArg(i++);
pushCastToType(overriddenMethodGenerator, param.getGenericType());
}
overriddenMethodGenerator.visitMethodInsn(INVOKESPECIAL, proxyType.getInternalName(), overriddenBy.getName(), getMethodDescriptor(overriddenBy.getReturnType().getType(), Arrays.asList(overriddenBy.getSuspendParameters())), this.isInterface && overriddenBy.isDefault());
if (isVoidReturn) {
overriddenMethodGenerator.returnValue();
} else {
ClassElement returnType = overriddenBy.getReturnType();
pushCastToType(overriddenMethodGenerator, returnType);
pushReturnValue(overriddenMethodGenerator, overriddenBy.getReturnType());
}
overriddenMethodGenerator.visitMaxs(DEFAULT_MAX_STACK, 1);
overriddenMethodGenerator.visitEnd();
}
use of io.micronaut.inject.ast.ParameterElement in project micronaut-core by micronaut-projects.
the class AopProxyWriter method buildMethodOverride.
private void buildMethodOverride(TypedElement returnType, String methodName, int index, List<ParameterElement> argumentTypeList, int argumentCount, boolean isVoidReturn) {
// override the original method
String desc = getMethodDescriptor(returnType, argumentTypeList);
MethodVisitor overridden = classWriter.visitMethod(ACC_PUBLIC, methodName, desc, null, null);
GeneratorAdapter overriddenMethodGenerator = new GeneratorAdapter(overridden, ACC_PUBLIC, methodName, desc);
// store the proxy method instance in a local variable
// ie ExecutableMethod executableMethod = this.proxyMethods[0];
overriddenMethodGenerator.loadThis();
overriddenMethodGenerator.getField(proxyType, FIELD_PROXY_METHODS, FIELD_TYPE_PROXY_METHODS);
overriddenMethodGenerator.push(index);
overriddenMethodGenerator.visitInsn(AALOAD);
int methodProxyVar = overriddenMethodGenerator.newLocal(EXECUTABLE_METHOD_TYPE);
overriddenMethodGenerator.storeLocal(methodProxyVar);
// store the interceptors in a local variable
// ie Interceptor[] interceptors = this.interceptors[0];
overriddenMethodGenerator.loadThis();
overriddenMethodGenerator.getField(proxyType, FIELD_INTERCEPTORS, FIELD_TYPE_INTERCEPTORS);
overriddenMethodGenerator.push(index);
overriddenMethodGenerator.visitInsn(AALOAD);
int interceptorsLocalVar = overriddenMethodGenerator.newLocal(INTERCEPTOR_ARRAY_TYPE);
overriddenMethodGenerator.storeLocal(interceptorsLocalVar);
// instantiate the MethodInterceptorChain
// ie InterceptorChain chain = new MethodInterceptorChain(interceptors, this, executableMethod, name);
overriddenMethodGenerator.newInstance(TYPE_METHOD_INTERCEPTOR_CHAIN);
overriddenMethodGenerator.dup();
// first argument: interceptors
overriddenMethodGenerator.loadLocal(interceptorsLocalVar);
// second argument: this or target
overriddenMethodGenerator.loadThis();
if (isProxyTarget) {
if (hotswap || lazy) {
overriddenMethodGenerator.invokeInterface(Type.getType(InterceptedProxy.class), Method.getMethod("java.lang.Object interceptedTarget()"));
} else {
overriddenMethodGenerator.getField(proxyType, FIELD_TARGET, getTypeReferenceForName(targetClassFullName));
}
}
// third argument: the executable method
overriddenMethodGenerator.loadLocal(methodProxyVar);
if (argumentCount > 0) {
// fourth argument: array of the argument values
overriddenMethodGenerator.push(argumentCount);
overriddenMethodGenerator.newArray(Type.getType(Object.class));
// now pass the remaining arguments from the original method
for (int i = 0; i < argumentCount; i++) {
overriddenMethodGenerator.dup();
ParameterElement argType = argumentTypeList.get(i);
overriddenMethodGenerator.push(i);
overriddenMethodGenerator.loadArg(i);
pushBoxPrimitiveIfNecessary(argType, overriddenMethodGenerator);
overriddenMethodGenerator.visitInsn(AASTORE);
}
// invoke MethodInterceptorChain constructor with parameters
overriddenMethodGenerator.invokeConstructor(TYPE_METHOD_INTERCEPTOR_CHAIN, Method.getMethod(CONSTRUCTOR_METHOD_INTERCEPTOR_CHAIN));
} else {
// invoke MethodInterceptorChain constructor without parameters
overriddenMethodGenerator.invokeConstructor(TYPE_METHOD_INTERCEPTOR_CHAIN, Method.getMethod(CONSTRUCTOR_METHOD_INTERCEPTOR_CHAIN_NO_PARAMS));
}
int chainVar = overriddenMethodGenerator.newLocal(TYPE_METHOD_INTERCEPTOR_CHAIN);
overriddenMethodGenerator.storeLocal(chainVar);
overriddenMethodGenerator.loadLocal(chainVar);
overriddenMethodGenerator.visitMethodInsn(INVOKEVIRTUAL, TYPE_INTERCEPTOR_CHAIN.getInternalName(), "proceed", getMethodDescriptor(Object.class.getName()), false);
if (isVoidReturn) {
returnVoid(overriddenMethodGenerator);
} else {
pushCastToType(overriddenMethodGenerator, returnType);
pushReturnValue(overriddenMethodGenerator, returnType);
}
overriddenMethodGenerator.visitMaxs(DEFAULT_MAX_STACK, chainVar);
overriddenMethodGenerator.visitEnd();
}
use of io.micronaut.inject.ast.ParameterElement in project micronaut-core by micronaut-projects.
the class AopProxyWriter method initConstructor.
private void initConstructor(MethodElement constructor) {
final ClassElement interceptorList = ClassElement.of(List.class, AnnotationMetadata.EMPTY_METADATA, Collections.singletonMap("E", ClassElement.of(BeanRegistration.class, AnnotationMetadata.EMPTY_METADATA, Collections.singletonMap("T", ClassElement.of(Interceptor.class)))));
this.interceptorParameter = ParameterElement.of(interceptorList, "$interceptors");
this.qualifierParameter = ParameterElement.of(Qualifier.class, "$qualifier");
ClassElement proxyClass = ClassElement.of(proxyType.getClassName());
ParameterElement[] constructorParameters = constructor.getParameters();
List<ParameterElement> newConstructorParameters = new ArrayList<>(constructorParameters.length + 4);
newConstructorParameters.addAll(Arrays.asList(constructorParameters));
newConstructorParameters.add(ParameterElement.of(BeanResolutionContext.class, "$beanResolutionContext"));
newConstructorParameters.add(ParameterElement.of(BeanContext.class, "$beanContext"));
newConstructorParameters.add(qualifierParameter);
newConstructorParameters.add(interceptorParameter);
this.newConstructor = MethodElement.of(proxyClass, constructor.getAnnotationMetadata(), proxyClass, proxyClass, "<init>", newConstructorParameters.toArray(new ParameterElement[0]));
this.beanResolutionContextArgumentIndex = constructorParameters.length;
this.beanContextArgumentIndex = constructorParameters.length + 1;
this.qualifierIndex = constructorParameters.length + 2;
this.interceptorArgumentIndex = constructorParameters.length + 3;
}
Aggregations