Search in sources :

Example 6 with ParameterElement

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();
}
Also used : ParameterElement(io.micronaut.inject.ast.ParameterElement)

Example 7 with ParameterElement

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++;
    }
}
Also used : ClassElement(io.micronaut.inject.ast.ClassElement) ParameterElement(io.micronaut.inject.ast.ParameterElement) DefaultAnnotationMetadata(io.micronaut.inject.annotation.DefaultAnnotationMetadata) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata)

Example 8 with ParameterElement

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();
}
Also used : GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) ClassElement(io.micronaut.inject.ast.ClassElement) ParameterElement(io.micronaut.inject.ast.ParameterElement) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 9 with ParameterElement

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();
}
Also used : GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) InterceptedProxy(io.micronaut.aop.InterceptedProxy) HotSwappableInterceptedProxy(io.micronaut.aop.HotSwappableInterceptedProxy) ParameterElement(io.micronaut.inject.ast.ParameterElement) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 10 with ParameterElement

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;
}
Also used : BeanContext(io.micronaut.context.BeanContext) DefaultBeanContext(io.micronaut.context.DefaultBeanContext) ArrayList(java.util.ArrayList) ClassElement(io.micronaut.inject.ast.ClassElement) Qualifier(io.micronaut.context.Qualifier) ParameterElement(io.micronaut.inject.ast.ParameterElement) BeanResolutionContext(io.micronaut.context.BeanResolutionContext)

Aggregations

ParameterElement (io.micronaut.inject.ast.ParameterElement)32 AnnotationMetadata (io.micronaut.core.annotation.AnnotationMetadata)13 ClassElement (io.micronaut.inject.ast.ClassElement)13 Type (org.objectweb.asm.Type)13 GeneratorAdapter (org.objectweb.asm.commons.GeneratorAdapter)13 DefaultAnnotationMetadata (io.micronaut.inject.annotation.DefaultAnnotationMetadata)12 MethodElement (io.micronaut.inject.ast.MethodElement)9 ArrayList (java.util.ArrayList)8 List (java.util.List)8 AbstractConstructorInjectionPoint (io.micronaut.context.AbstractConstructorInjectionPoint)7 Label (org.objectweb.asm.Label)7 Argument (io.micronaut.core.type.Argument)6 ConstructorInjectionPoint (io.micronaut.inject.ConstructorInjectionPoint)6 MutableAnnotationMetadata (io.micronaut.inject.annotation.MutableAnnotationMetadata)6 TypedElement (io.micronaut.inject.ast.TypedElement)6 Map (java.util.Map)6 AnnotationMetadataReference (io.micronaut.inject.annotation.AnnotationMetadataReference)5 FieldElement (io.micronaut.inject.ast.FieldElement)5 HashMap (java.util.HashMap)5 ClassWriter (org.objectweb.asm.ClassWriter)5