Search in sources :

Example 1 with BeanDefinitionWriter

use of io.micronaut.inject.writer.BeanDefinitionWriter in project micronaut-core by micronaut-projects.

the class JavaBeanDefinitionBuilder method createChildBean.

@Override
protected AbstractBeanDefinitionBuilder createChildBean(FieldElement producerField) {
    final ClassElement parentType = getBeanType();
    return new JavaBeanDefinitionBuilder(JavaBeanDefinitionBuilder.this.getOriginatingElement(), producerField.getGenericField().getType(), JavaBeanDefinitionBuilder.this.metadataBuilder, (JavaVisitorContext) JavaBeanDefinitionBuilder.this.visitorContext) {

        @Override
        public Element getProducingElement() {
            return producerField;
        }

        @Override
        public ClassElement getDeclaringElement() {
            return producerField.getDeclaringType();
        }

        @Override
        protected BeanDefinitionWriter createBeanDefinitionWriter() {
            final BeanDefinitionWriter writer = super.createBeanDefinitionWriter();
            final JavaElementFactory elementFactory = ((JavaVisitorContext) visitorContext).getElementFactory();
            final VariableElement variableElement = (VariableElement) producerField.getNativeType();
            writer.visitBeanFactoryField(parentType, elementFactory.newFieldElement(parentType, variableElement, new AnnotationMetadataHierarchy(parentType.getDeclaredMetadata(), producerField.getDeclaredMetadata())));
            return writer;
        }
    };
}
Also used : ClassElement(io.micronaut.inject.ast.ClassElement) VariableElement(javax.lang.model.element.VariableElement) BeanDefinitionWriter(io.micronaut.inject.writer.BeanDefinitionWriter) AnnotationMetadataHierarchy(io.micronaut.inject.annotation.AnnotationMetadataHierarchy)

Example 2 with BeanDefinitionWriter

use of io.micronaut.inject.writer.BeanDefinitionWriter in project micronaut-core by micronaut-projects.

the class AopProxyWriter method visitBeanDefinitionEnd.

/**
 * Finalizes the proxy. This method should be called before writing the proxy to disk with {@link #writeTo(File)}
 */
@Override
public void visitBeanDefinitionEnd() {
    if (declaredConstructor == null) {
        throw new IllegalStateException("The method visitBeanDefinitionConstructor(..) should be called at least once");
    } else {
        initConstructor(declaredConstructor);
    }
    if (parentWriter != null && !isProxyTarget) {
        processAlreadyVisitedMethods(parentWriter);
    }
    interceptorParameter.annotate(AnnotationUtil.ANN_INTERCEPTOR_BINDING_QUALIFIER, builder -> {
        final AnnotationValue<?>[] interceptorBinding = this.interceptorBinding.toArray(new AnnotationValue[0]);
        builder.values(interceptorBinding);
    });
    qualifierParameter.annotate(AnnotationUtil.NULLABLE);
    String constructorDescriptor = getConstructorDescriptor(Arrays.asList(newConstructor.getParameters()));
    ClassWriter proxyClassWriter = this.classWriter;
    this.constructorWriter = proxyClassWriter.visitMethod(ACC_PUBLIC, CONSTRUCTOR_NAME, constructorDescriptor, null, null);
    this.constructorGenerator = new GeneratorAdapter(constructorWriter, Opcodes.ACC_PUBLIC, CONSTRUCTOR_NAME, constructorDescriptor);
    GeneratorAdapter proxyConstructorGenerator = this.constructorGenerator;
    proxyConstructorGenerator.loadThis();
    if (isInterface) {
        proxyConstructorGenerator.invokeConstructor(TYPE_OBJECT, METHOD_DEFAULT_CONSTRUCTOR);
    } else {
        ParameterElement[] existingArguments = declaredConstructor.getParameters();
        for (int i = 0; i < existingArguments.length; i++) {
            proxyConstructorGenerator.loadArg(i);
        }
        String superConstructorDescriptor = getConstructorDescriptor(Arrays.asList(existingArguments));
        proxyConstructorGenerator.invokeConstructor(getTypeReferenceForName(targetClassFullName), new Method(CONSTRUCTOR_NAME, superConstructorDescriptor));
    }
    proxyBeanDefinitionWriter.visitBeanDefinitionConstructor(newConstructor, constructorRequiresReflection, visitorContext);
    GeneratorAdapter targetDefinitionGenerator = null;
    GeneratorAdapter targetTypeGenerator = null;
    if (parentWriter != null) {
        proxyBeanDefinitionWriter.visitBeanDefinitionInterface(ProxyBeanDefinition.class);
        ClassVisitor pcw = proxyBeanDefinitionWriter.getClassWriter();
        targetDefinitionGenerator = new GeneratorAdapter(pcw.visitMethod(ACC_PUBLIC, METHOD_PROXY_TARGET_TYPE.getName(), METHOD_PROXY_TARGET_TYPE.getDescriptor(), null, null), ACC_PUBLIC, METHOD_PROXY_TARGET_TYPE.getName(), METHOD_PROXY_TARGET_TYPE.getDescriptor());
        targetDefinitionGenerator.loadThis();
        targetDefinitionGenerator.push(getTypeReferenceForName(parentWriter.getBeanDefinitionName()));
        targetDefinitionGenerator.returnValue();
        targetTypeGenerator = new GeneratorAdapter(pcw.visitMethod(ACC_PUBLIC, METHOD_PROXY_TARGET_CLASS.getName(), METHOD_PROXY_TARGET_CLASS.getDescriptor(), null, null), ACC_PUBLIC, METHOD_PROXY_TARGET_CLASS.getName(), METHOD_PROXY_TARGET_CLASS.getDescriptor());
        targetTypeGenerator.loadThis();
        targetTypeGenerator.push(getTypeReferenceForName(parentWriter.getBeanTypeName()));
        targetTypeGenerator.returnValue();
    }
    Class<?> interceptedInterface = isIntroduction ? Introduced.class : Intercepted.class;
    Type targetType = getTypeReferenceForName(targetClassFullName);
    // add the $beanLocator field
    if (isProxyTarget) {
        proxyClassWriter.visitField(ACC_PRIVATE | ACC_FINAL, FIELD_BEAN_LOCATOR, TYPE_BEAN_LOCATOR.getDescriptor(), null, null);
        // add the $beanQualifier field
        proxyClassWriter.visitField(ACC_PRIVATE, FIELD_BEAN_QUALIFIER, Type.getType(Qualifier.class).getDescriptor(), null, null);
        writeWithQualifierMethod(proxyClassWriter);
        if (!lazy || cacheLazyTarget) {
            // add the $target field for the target bean
            int modifiers = hotswap ? ACC_PRIVATE : ACC_PRIVATE | ACC_FINAL;
            proxyClassWriter.visitField(modifiers, FIELD_TARGET, targetType.getDescriptor(), null, null);
        }
        if (lazy) {
            interceptedInterface = InterceptedProxy.class;
            proxyClassWriter.visitField(ACC_PRIVATE, FIELD_BEAN_RESOLUTION_CONTEXT, Type.getType(BeanResolutionContext.class).getDescriptor(), null, null);
        } else {
            interceptedInterface = hotswap ? HotSwappableInterceptedProxy.class : InterceptedProxy.class;
            if (hotswap) {
                // Add ReadWriteLock field
                // private final ReentrantReadWriteLock $target_rwl = new ReentrantReadWriteLock();
                proxyClassWriter.visitField(ACC_PRIVATE | ACC_FINAL, FIELD_READ_WRITE_LOCK, TYPE_READ_WRITE_LOCK.getDescriptor(), null, null);
                proxyConstructorGenerator.loadThis();
                pushNewInstance(proxyConstructorGenerator, TYPE_READ_WRITE_LOCK);
                proxyConstructorGenerator.putField(proxyType, FIELD_READ_WRITE_LOCK, TYPE_READ_WRITE_LOCK);
                // Add Read Lock field
                // private final Lock $target_rl = $target_rwl.readLock();
                proxyClassWriter.visitField(ACC_PRIVATE | ACC_FINAL, FIELD_READ_LOCK, TYPE_LOCK.getDescriptor(), null, null);
                proxyConstructorGenerator.loadThis();
                proxyConstructorGenerator.loadThis();
                proxyConstructorGenerator.getField(proxyType, FIELD_READ_WRITE_LOCK, TYPE_READ_WRITE_LOCK);
                proxyConstructorGenerator.invokeInterface(Type.getType(ReadWriteLock.class), Method.getMethod(Lock.class.getName() + " readLock()"));
                proxyConstructorGenerator.putField(proxyType, FIELD_READ_LOCK, TYPE_LOCK);
                // Add Write Lock field
                // private final Lock $target_wl = $target_rwl.writeLock();
                proxyClassWriter.visitField(ACC_PRIVATE | ACC_FINAL, FIELD_WRITE_LOCK, Type.getDescriptor(Lock.class), null, null);
                proxyConstructorGenerator.loadThis();
                proxyConstructorGenerator.loadThis();
                proxyConstructorGenerator.getField(proxyType, FIELD_READ_WRITE_LOCK, TYPE_READ_WRITE_LOCK);
                proxyConstructorGenerator.invokeInterface(Type.getType(ReadWriteLock.class), Method.getMethod(Lock.class.getName() + " writeLock()"));
                proxyConstructorGenerator.putField(proxyType, FIELD_WRITE_LOCK, TYPE_LOCK);
            }
        }
        // assign the bean locator
        proxyConstructorGenerator.loadThis();
        proxyConstructorGenerator.loadArg(beanContextArgumentIndex);
        proxyConstructorGenerator.putField(proxyType, FIELD_BEAN_LOCATOR, TYPE_BEAN_LOCATOR);
        proxyConstructorGenerator.loadThis();
        proxyConstructorGenerator.loadArg(qualifierIndex);
        proxyConstructorGenerator.putField(proxyType, FIELD_BEAN_QUALIFIER, Type.getType(Qualifier.class));
        if (!lazy) {
            proxyConstructorGenerator.loadThis();
            pushResolveProxyTargetBean(proxyConstructorGenerator, targetType);
            proxyConstructorGenerator.putField(proxyType, FIELD_TARGET, targetType);
        } else {
            proxyConstructorGenerator.loadThis();
            proxyConstructorGenerator.loadArg(beanResolutionContextArgumentIndex);
            proxyConstructorGenerator.invokeInterface(Type.getType(BeanResolutionContext.class), Method.getMethod(ReflectionUtils.getRequiredMethod(BeanResolutionContext.class, "copy")));
            proxyConstructorGenerator.putField(proxyType, FIELD_BEAN_RESOLUTION_CONTEXT, Type.getType(BeanResolutionContext.class));
        }
        // Write the Object interceptedTarget() method
        writeInterceptedTargetMethod(proxyClassWriter, targetType);
        // e. T swap(T newInstance);
        if (hotswap && !lazy) {
            writeSwapMethod(proxyClassWriter, targetType);
        }
    }
    String[] interfaces = getImplementedInterfaceInternalNames();
    if (isInterface && implementInterface) {
        String[] adviceInterfaces = { getInternalName(targetClassFullName), Type.getInternalName(interceptedInterface) };
        interfaces = ArrayUtils.concat(interfaces, adviceInterfaces);
    } else {
        String[] adviceInterfaces = { Type.getInternalName(interceptedInterface) };
        interfaces = ArrayUtils.concat(interfaces, adviceInterfaces);
    }
    proxyClassWriter.visit(V1_8, ACC_SYNTHETIC, proxyInternalName, null, isInterface ? TYPE_OBJECT.getInternalName() : getTypeReferenceForName(targetClassFullName).getInternalName(), interfaces);
    // set $proxyMethods field
    proxyConstructorGenerator.loadThis();
    proxyConstructorGenerator.push(proxyMethodCount);
    proxyConstructorGenerator.newArray(EXECUTABLE_METHOD_TYPE);
    proxyConstructorGenerator.putField(proxyType, FIELD_PROXY_METHODS, FIELD_TYPE_PROXY_METHODS);
    // set $interceptors field
    proxyConstructorGenerator.loadThis();
    proxyConstructorGenerator.push(proxyMethodCount);
    proxyConstructorGenerator.newArray(INTERCEPTOR_ARRAY_TYPE);
    proxyConstructorGenerator.putField(proxyType, FIELD_INTERCEPTORS, FIELD_TYPE_INTERCEPTORS);
    // now initialize the held values
    if (isProxyTarget) {
        if (proxiedMethods.size() == proxyMethodCount) {
            Iterator<MethodRef> iterator = proxyTargetMethods.iterator();
            for (int i = 0; i < proxyMethodCount; i++) {
                MethodRef methodRef = iterator.next();
                // The following will initialize the array of $proxyMethod instances
                // Eg. this.$proxyMethods[0] = $PARENT_BEAN.getRequiredMethod("test", new Class[]{String.class});
                proxyConstructorGenerator.loadThis();
                // Step 1: dereference the array - this.$proxyMethods[0]
                proxyConstructorGenerator.getField(proxyType, FIELD_PROXY_METHODS, FIELD_TYPE_PROXY_METHODS);
                proxyConstructorGenerator.push(i);
                // Step 2: lookup the Method instance from the declaring type
                // context.getProxyTargetMethod("test", new Class[]{String.class});
                proxyConstructorGenerator.loadArg(beanContextArgumentIndex);
                buildProxyLookupArgument(proxyConstructorGenerator, targetType);
                proxyConstructorGenerator.loadArg(qualifierIndex);
                pushMethodNameAndTypesArguments(proxyConstructorGenerator, methodRef.name, methodRef.argumentTypes);
                proxyConstructorGenerator.invokeInterface(Type.getType(ExecutionHandleLocator.class), METHOD_GET_PROXY_TARGET);
                // Step 3: store the result in the array
                proxyConstructorGenerator.visitInsn(AASTORE);
                // Step 4: Resolve the interceptors
                // this.$interceptors[0] = InterceptorChain.resolveAroundInterceptors(this.$proxyMethods[0], var2);
                pushResolveInterceptorsCall(proxyConstructorGenerator, i, isIntroduction);
            }
        }
    } else if (!proxiedMethods.isEmpty()) {
        BeanDefinitionWriter beanDefinitionWriter = parentWriter == null ? proxyBeanDefinitionWriter : parentWriter;
        ExecutableMethodsDefinitionWriter executableMethodsDefinitionWriter = beanDefinitionWriter.getExecutableMethodsWriter();
        Type executableMethodsDefinitionType = executableMethodsDefinitionWriter.getClassType();
        proxyConstructorGenerator.newInstance(executableMethodsDefinitionType);
        proxyConstructorGenerator.dup();
        if (executableMethodsDefinitionWriter.isSupportsInterceptedProxy()) {
            proxyConstructorGenerator.push(true);
            proxyConstructorGenerator.invokeConstructor(executableMethodsDefinitionType, new Method(CONSTRUCTOR_NAME, getConstructorDescriptor(boolean.class)));
        } else {
            proxyConstructorGenerator.invokeConstructor(executableMethodsDefinitionType, new Method(CONSTRUCTOR_NAME, DESCRIPTOR_DEFAULT_CONSTRUCTOR));
        }
        int executableMethodsDefinitionIndex = proxyConstructorGenerator.newLocal(executableMethodsDefinitionType);
        proxyConstructorGenerator.storeLocal(executableMethodsDefinitionIndex, executableMethodsDefinitionType);
        for (int i = 0; i < proxyMethodCount; i++) {
            MethodRef methodRef = proxiedMethods.get(i);
            int methodIndex = methodRef.methodIndex;
            boolean introduction = isIntroduction && (executableMethodsDefinitionWriter.isAbstract(methodIndex) || (executableMethodsDefinitionWriter.isInterface(methodIndex) && !executableMethodsDefinitionWriter.isDefault(methodIndex)));
            // The following will initialize the array of $proxyMethod instances
            // Eg. this.proxyMethods[0] = new $blah0();
            proxyConstructorGenerator.loadThis();
            proxyConstructorGenerator.getField(proxyType, FIELD_PROXY_METHODS, FIELD_TYPE_PROXY_METHODS);
            proxyConstructorGenerator.push(i);
            // getExecutableMethodByIndex
            proxyConstructorGenerator.loadLocal(executableMethodsDefinitionIndex);
            proxyConstructorGenerator.push(methodIndex);
            proxyConstructorGenerator.invokeVirtual(executableMethodsDefinitionType, ExecutableMethodsDefinitionWriter.GET_EXECUTABLE_AT_INDEX_METHOD);
            proxyConstructorGenerator.visitInsn(AASTORE);
            pushResolveInterceptorsCall(proxyConstructorGenerator, i, introduction);
        }
    }
    for (Runnable fieldInjectionPoint : deferredInjectionPoints) {
        fieldInjectionPoint.run();
    }
    constructorWriter.visitInsn(RETURN);
    constructorWriter.visitMaxs(DEFAULT_MAX_STACK, 1);
    this.constructorWriter.visitEnd();
    proxyBeanDefinitionWriter.visitBeanDefinitionEnd();
    if (targetDefinitionGenerator != null) {
        targetDefinitionGenerator.visitMaxs(1, 1);
        targetDefinitionGenerator.visitEnd();
    }
    if (targetTypeGenerator != null) {
        targetTypeGenerator.visitMaxs(1, 1);
        targetTypeGenerator.visitEnd();
    }
    proxyClassWriter.visitEnd();
}
Also used : ClassVisitor(org.objectweb.asm.ClassVisitor) InterceptedProxy(io.micronaut.aop.InterceptedProxy) HotSwappableInterceptedProxy(io.micronaut.aop.HotSwappableInterceptedProxy) BeanDefinitionWriter(io.micronaut.inject.writer.BeanDefinitionWriter) HotSwappableInterceptedProxy(io.micronaut.aop.HotSwappableInterceptedProxy) ReadWriteLock(java.util.concurrent.locks.ReadWriteLock) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) Qualifier(io.micronaut.context.Qualifier) ParameterElement(io.micronaut.inject.ast.ParameterElement) ExecutableMethodsDefinitionWriter(io.micronaut.inject.writer.ExecutableMethodsDefinitionWriter) ExecutionHandleLocator(io.micronaut.context.ExecutionHandleLocator) ExecutableMethod(io.micronaut.inject.ExecutableMethod) Method(org.objectweb.asm.commons.Method) ClassWriter(org.objectweb.asm.ClassWriter) ReadWriteLock(java.util.concurrent.locks.ReadWriteLock) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) Lock(java.util.concurrent.locks.Lock) Type(org.objectweb.asm.Type) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) BeanResolutionContext(io.micronaut.context.BeanResolutionContext)

Example 3 with BeanDefinitionWriter

use of io.micronaut.inject.writer.BeanDefinitionWriter in project micronaut-core by micronaut-projects.

the class AopProxyWriter method visitAroundMethod.

/**
 * Visit a method that is to be proxied.
 *
 * @param beanType      The bean type.
 * @param methodElement The method element
 */
public void visitAroundMethod(TypedElement beanType, MethodElement methodElement) {
    ClassElement returnType = methodElement.isSuspend() ? ClassElement.of(Object.class) : methodElement.getReturnType();
    Type returnTypeObject = JavaModelUtils.getTypeReference(returnType);
    boolean isPrimitive = returnType.isPrimitive();
    boolean isVoidReturn = isPrimitive && returnTypeObject.equals(Type.VOID_TYPE);
    final Optional<MethodElement> overridden = methodElement.getOwningType().getEnclosedElement(ElementQuery.ALL_METHODS.onlyInstance().named(name -> name.equals(methodElement.getName())).filter(el -> el.overrides(methodElement)));
    if (overridden.isPresent()) {
        MethodElement overriddenBy = overridden.get();
        String methodElementKey = methodElement.getName() + Arrays.stream(methodElement.getSuspendParameters()).map(p -> p.getType().getName()).collect(Collectors.joining(","));
        String overriddenByKey = overriddenBy.getName() + Arrays.stream(methodElement.getSuspendParameters()).map(p -> p.getGenericType().getName()).collect(Collectors.joining(","));
        if (!methodElementKey.equals(overriddenByKey)) {
            buildMethodDelegate(methodElement, overriddenBy, isVoidReturn);
            return;
        }
    }
    String methodName = methodElement.getName();
    List<ParameterElement> argumentTypeList = Arrays.asList(methodElement.getSuspendParameters());
    int argumentCount = argumentTypeList.size();
    final Type declaringTypeReference = JavaModelUtils.getTypeReference(beanType);
    MethodRef methodKey = new MethodRef(methodName, argumentTypeList, returnTypeObject);
    if (!proxiedMethodsRefSet.contains(methodKey)) {
        String interceptedProxyClassName = null;
        String interceptedProxyBridgeMethodName = null;
        if (!isProxyTarget) {
            if (!methodElement.isAbstract() || methodElement.isDefault()) {
                interceptedProxyClassName = proxyFullName;
                interceptedProxyBridgeMethodName = "$$access$$" + methodName;
                String bridgeDesc = getMethodDescriptor(returnType, argumentTypeList);
                // now build a bridge to invoke the original method
                MethodVisitor bridgeWriter = classWriter.visitMethod(ACC_SYNTHETIC, interceptedProxyBridgeMethodName, bridgeDesc, null, null);
                GeneratorAdapter bridgeGenerator = new GeneratorAdapter(bridgeWriter, ACC_SYNTHETIC, interceptedProxyBridgeMethodName, bridgeDesc);
                bridgeGenerator.loadThis();
                for (int i = 0; i < argumentTypeList.size(); i++) {
                    bridgeGenerator.loadArg(i);
                }
                String desc = getMethodDescriptor(returnType, argumentTypeList);
                bridgeWriter.visitMethodInsn(INVOKESPECIAL, declaringTypeReference.getInternalName(), methodName, desc, this.isInterface && methodElement.isDefault());
                pushReturnValue(bridgeWriter, returnType);
                bridgeWriter.visitMaxs(DEFAULT_MAX_STACK, 1);
                bridgeWriter.visitEnd();
            }
        }
        BeanDefinitionWriter beanDefinitionWriter = parentWriter == null ? proxyBeanDefinitionWriter : parentWriter;
        int methodIndex = beanDefinitionWriter.visitExecutableMethod(beanType, methodElement, interceptedProxyClassName, interceptedProxyBridgeMethodName);
        int index = proxyMethodCount++;
        methodKey.methodIndex = methodIndex;
        proxiedMethods.add(methodKey);
        proxiedMethodsRefSet.add(methodKey);
        proxyTargetMethods.add(methodKey);
        buildMethodOverride(returnType, methodName, index, argumentTypeList, argumentCount, isVoidReturn);
    }
}
Also used : ElementQuery(io.micronaut.inject.ast.ElementQuery) Arrays(java.util.Arrays) InterceptedProxy(io.micronaut.aop.InterceptedProxy) MethodVisitor(org.objectweb.asm.MethodVisitor) BeanContext(io.micronaut.context.BeanContext) ArrayUtils(io.micronaut.core.util.ArrayUtils) FieldElement(io.micronaut.inject.ast.FieldElement) DefaultBeanContext(io.micronaut.context.DefaultBeanContext) Type(org.objectweb.asm.Type) ProxyingBeanDefinitionVisitor(io.micronaut.inject.writer.ProxyingBeanDefinitionVisitor) Introduced(io.micronaut.aop.Introduced) MethodInterceptorChain(io.micronaut.aop.chain.MethodInterceptorChain) Map(java.util.Map) BeanResolutionContext(io.micronaut.context.BeanResolutionContext) AbstractClassFileWriter(io.micronaut.inject.writer.AbstractClassFileWriter) HotSwappableInterceptedProxy(io.micronaut.aop.HotSwappableInterceptedProxy) BeanLocator(io.micronaut.context.BeanLocator) ClassVisitor(org.objectweb.asm.ClassVisitor) ReadWriteLock(java.util.concurrent.locks.ReadWriteLock) Set(java.util.Set) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) StringUtils(io.micronaut.core.util.StringUtils) List(java.util.List) Interceptor(io.micronaut.aop.Interceptor) AnnotationUtil(io.micronaut.core.annotation.AnnotationUtil) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) ProxyBeanDefinition(io.micronaut.inject.ProxyBeanDefinition) MethodElement(io.micronaut.inject.ast.MethodElement) Optional(java.util.Optional) InterceptorChain(io.micronaut.aop.chain.InterceptorChain) BeanDefinitionWriter(io.micronaut.inject.writer.BeanDefinitionWriter) ConfigurationMetadata(io.micronaut.inject.configuration.ConfigurationMetadata) JavaModelUtils(io.micronaut.inject.processing.JavaModelUtils) ClassWriter(org.objectweb.asm.ClassWriter) BeanRegistration(io.micronaut.context.BeanRegistration) OriginatingElements(io.micronaut.inject.writer.OriginatingElements) Qualifier(io.micronaut.context.Qualifier) Label(org.objectweb.asm.Label) ClassElement(io.micronaut.inject.ast.ClassElement) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) Toggleable(io.micronaut.core.util.Toggleable) DefaultAnnotationMetadata(io.micronaut.inject.annotation.DefaultAnnotationMetadata) Constructor(java.lang.reflect.Constructor) ExecutableMethod(io.micronaut.inject.ExecutableMethod) ParameterElement(io.micronaut.inject.ast.ParameterElement) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Method(org.objectweb.asm.commons.Method) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) TypedElement(io.micronaut.inject.ast.TypedElement) AnnotationMetadataReference(io.micronaut.inject.annotation.AnnotationMetadataReference) ConfigurationReader(io.micronaut.context.annotation.ConfigurationReader) Argument(io.micronaut.core.type.Argument) ClassWriterOutputVisitor(io.micronaut.inject.writer.ClassWriterOutputVisitor) LinkedHashSet(java.util.LinkedHashSet) ExecutableMethodsDefinitionWriter(io.micronaut.inject.writer.ExecutableMethodsDefinitionWriter) OutputStream(java.io.OutputStream) Opcodes(org.objectweb.asm.Opcodes) Element(io.micronaut.inject.ast.Element) Iterator(java.util.Iterator) InterceptedMethodUtil(io.micronaut.aop.internal.intercepted.InterceptedMethodUtil) IOException(java.io.IOException) OptionalValues(io.micronaut.core.value.OptionalValues) ReflectionUtils(io.micronaut.core.reflect.ReflectionUtils) File(java.io.File) InterceptorKind(io.micronaut.aop.InterceptorKind) NonNull(io.micronaut.core.annotation.NonNull) ExecutionHandleLocator(io.micronaut.context.ExecutionHandleLocator) VisitorContext(io.micronaut.inject.visitor.VisitorContext) Lock(java.util.concurrent.locks.Lock) ConfigurationMetadataBuilder(io.micronaut.inject.configuration.ConfigurationMetadataBuilder) BeanDefinitionVisitor(io.micronaut.inject.writer.BeanDefinitionVisitor) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) BeanDefinition(io.micronaut.inject.BeanDefinition) Collections(java.util.Collections) Intercepted(io.micronaut.aop.Intercepted) MethodElement(io.micronaut.inject.ast.MethodElement) ClassElement(io.micronaut.inject.ast.ClassElement) BeanDefinitionWriter(io.micronaut.inject.writer.BeanDefinitionWriter) MethodVisitor(org.objectweb.asm.MethodVisitor) Type(org.objectweb.asm.Type) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) ParameterElement(io.micronaut.inject.ast.ParameterElement)

Example 4 with BeanDefinitionWriter

use of io.micronaut.inject.writer.BeanDefinitionWriter in project micronaut-core by micronaut-projects.

the class JavaBeanDefinitionBuilder method createChildBean.

@Override
protected AbstractBeanDefinitionBuilder createChildBean(MethodElement producerMethod) {
    final ClassElement parentType = getBeanType();
    return new JavaBeanDefinitionBuilder(JavaBeanDefinitionBuilder.this.getOriginatingElement(), producerMethod.getGenericReturnType(), JavaBeanDefinitionBuilder.this.metadataBuilder, (JavaVisitorContext) JavaBeanDefinitionBuilder.this.visitorContext) {

        @Override
        public Element getProducingElement() {
            return producerMethod;
        }

        @Override
        public ClassElement getDeclaringElement() {
            return producerMethod.getDeclaringType();
        }

        @Override
        protected BeanDefinitionWriter createBeanDefinitionWriter() {
            final BeanDefinitionWriter writer = super.createBeanDefinitionWriter();
            final JavaElementFactory elementFactory = ((JavaVisitorContext) visitorContext).getElementFactory();
            final ExecutableElement variableElement = (ExecutableElement) producerMethod.getNativeType();
            writer.visitBeanFactoryMethod(parentType, elementFactory.newMethodElement(parentType, variableElement, new AnnotationMetadataHierarchy(parentType.getDeclaredMetadata(), producerMethod.getDeclaredMetadata())));
            return writer;
        }
    };
}
Also used : ExecutableElement(javax.lang.model.element.ExecutableElement) ClassElement(io.micronaut.inject.ast.ClassElement) BeanDefinitionWriter(io.micronaut.inject.writer.BeanDefinitionWriter) AnnotationMetadataHierarchy(io.micronaut.inject.annotation.AnnotationMetadataHierarchy)

Example 5 with BeanDefinitionWriter

use of io.micronaut.inject.writer.BeanDefinitionWriter in project micronaut-core by micronaut-projects.

the class GroovyBeanDefinitionBuilder method createChildBean.

@Override
protected AbstractBeanDefinitionBuilder createChildBean(FieldElement producerField) {
    final ClassElement parentType = getBeanType();
    return new GroovyBeanDefinitionBuilder(GroovyBeanDefinitionBuilder.this.getOriginatingElement(), producerField.getGenericField().getType(), GroovyBeanDefinitionBuilder.this.metadataBuilder, GroovyBeanDefinitionBuilder.this.visitorContext) {

        @Override
        public Element getProducingElement() {
            return producerField;
        }

        @Override
        public ClassElement getDeclaringElement() {
            return producerField.getDeclaringType();
        }

        @Override
        protected BeanDefinitionWriter createBeanDefinitionWriter() {
            final BeanDefinitionWriter writer = super.createBeanDefinitionWriter();
            final GroovyElementFactory elementFactory = ((GroovyVisitorContext) visitorContext).getElementFactory();
            final FieldNode fieldNode = (FieldNode) producerField.getNativeType();
            writer.visitBeanFactoryField(parentType, elementFactory.newFieldElement(parentType, fieldNode, new AnnotationMetadataHierarchy(parentType.getDeclaredMetadata(), producerField.getDeclaredMetadata())));
            return writer;
        }
    };
}
Also used : FieldNode(org.codehaus.groovy.ast.FieldNode) ClassElement(io.micronaut.inject.ast.ClassElement) BeanDefinitionWriter(io.micronaut.inject.writer.BeanDefinitionWriter) AnnotationMetadataHierarchy(io.micronaut.inject.annotation.AnnotationMetadataHierarchy)

Aggregations

BeanDefinitionWriter (io.micronaut.inject.writer.BeanDefinitionWriter)6 ClassElement (io.micronaut.inject.ast.ClassElement)5 AnnotationMetadataHierarchy (io.micronaut.inject.annotation.AnnotationMetadataHierarchy)4 HotSwappableInterceptedProxy (io.micronaut.aop.HotSwappableInterceptedProxy)2 InterceptedProxy (io.micronaut.aop.InterceptedProxy)2 BeanResolutionContext (io.micronaut.context.BeanResolutionContext)2 ExecutionHandleLocator (io.micronaut.context.ExecutionHandleLocator)2 Qualifier (io.micronaut.context.Qualifier)2 AnnotationValue (io.micronaut.core.annotation.AnnotationValue)2 ExecutableMethod (io.micronaut.inject.ExecutableMethod)2 ParameterElement (io.micronaut.inject.ast.ParameterElement)2 Intercepted (io.micronaut.aop.Intercepted)1 Interceptor (io.micronaut.aop.Interceptor)1 InterceptorKind (io.micronaut.aop.InterceptorKind)1 Introduced (io.micronaut.aop.Introduced)1 InterceptorChain (io.micronaut.aop.chain.InterceptorChain)1 MethodInterceptorChain (io.micronaut.aop.chain.MethodInterceptorChain)1 InterceptedMethodUtil (io.micronaut.aop.internal.intercepted.InterceptedMethodUtil)1 BeanContext (io.micronaut.context.BeanContext)1 BeanLocator (io.micronaut.context.BeanLocator)1