Search in sources :

Example 26 with ParameterElement

use of io.micronaut.inject.ast.ParameterElement in project micronaut-core by micronaut-projects.

the class BeanDefinitionWriter method applyDefaultNamedToParameters.

private void applyDefaultNamedToParameters(List<ParameterElement> argumentTypes) {
    for (ParameterElement parameterElement : argumentTypes) {
        final AnnotationMetadata annotationMetadata = parameterElement.getAnnotationMetadata();
        DefaultAnnotationMetadata.contributeDefaults(this.annotationMetadata, annotationMetadata);
        DefaultAnnotationMetadata.contributeRepeatable(this.annotationMetadata, parameterElement.getGenericType());
        autoApplyNamedIfPresent(parameterElement, annotationMetadata);
    }
}
Also used : ParameterElement(io.micronaut.inject.ast.ParameterElement) MutableAnnotationMetadata(io.micronaut.inject.annotation.MutableAnnotationMetadata) DefaultAnnotationMetadata(io.micronaut.inject.annotation.DefaultAnnotationMetadata) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata)

Example 27 with ParameterElement

use of io.micronaut.inject.ast.ParameterElement in project micronaut-core by micronaut-projects.

the class BeanDefinitionWriter method visitSetterValue.

@Override
public void visitSetterValue(TypedElement declaringType, MethodElement methodElement, boolean requiresReflection, boolean isOptional) {
    if (!requiresReflection) {
        ParameterElement parameter = methodElement.getParameters()[0];
        AnnotationMetadataHierarchy annotationMetadata = new AnnotationMetadataHierarchy(parameter.getAnnotationMetadata(), methodElement.getAnnotationMetadata());
        Label falseCondition = isOptional ? pushPropertyContainsCheck(injectMethodVisitor, parameter.getType(), parameter.getName(), annotationMetadata) : null;
        AnnotationMetadata currentAnnotationMetadata = methodElement.getAnnotationMetadata();
        ClassElement genericType = parameter.getGenericType();
        if (isConfigurationProperties && isValueType(currentAnnotationMetadata)) {
            injectMethodVisitor.loadLocal(injectInstanceLocalVarIndex, beanType);
            Optional<String> property = currentAnnotationMetadata.stringValue(Property.class, "name");
            Optional<String> valueValue = parameter.stringValue(Value.class);
            if (isInnerType(genericType)) {
                boolean isArray = genericType.isArray();
                boolean isCollection = genericType.isAssignable(Collection.class);
                if (isCollection || isArray) {
                    ClassElement typeArgument = genericType.isArray() ? genericType.fromArray() : genericType.getFirstTypeArgument().orElse(null);
                    if (typeArgument != null && !typeArgument.isPrimitive()) {
                        pushInvokeGetBeansOfTypeForSetter(injectMethodVisitor, methodElement.getName(), parameter);
                    } else {
                        pushInvokeGetBeanForSetter(injectMethodVisitor, methodElement.getName(), parameter);
                    }
                } else {
                    pushInvokeGetBeanForSetter(injectMethodVisitor, methodElement.getName(), parameter);
                }
            } else if (property.isPresent()) {
                pushInvokeGetPropertyValueForSetter(injectMethodVisitor, methodElement.getName(), parameter, property.get());
            } else if (valueValue.isPresent()) {
                pushInvokeGetPropertyPlaceholderValueForSetter(injectMethodVisitor, methodElement.getName(), parameter, valueValue.get());
            } else {
                throw new IllegalStateException();
            }
            Type declaringTypeRef = JavaModelUtils.getTypeReference(declaringType);
            String methodDescriptor = getMethodDescriptor(methodElement.getReturnType(), Arrays.asList(methodElement.getParameters()));
            injectMethodVisitor.visitMethodInsn(isInterface ? INVOKEINTERFACE : INVOKEVIRTUAL, declaringTypeRef.getInternalName(), methodElement.getName(), methodDescriptor, isInterface);
            if (methodElement.getReturnType() != PrimitiveElement.VOID) {
                injectMethodVisitor.pop();
            }
            if (keepConfPropInjectPoints) {
                final MethodVisitData methodVisitData = new MethodVisitData(declaringType, methodElement, false);
                methodInjectionPoints.add(methodVisitData);
                allMethodVisits.add(methodVisitData);
                currentMethodIndex++;
            }
        } else {
            final MethodVisitData methodVisitData = new MethodVisitData(declaringType, methodElement, false);
            visitMethodInjectionPointInternal(methodVisitData, injectMethodVisitor, injectInstanceLocalVarIndex);
            methodInjectionPoints.add(methodVisitData);
            allMethodVisits.add(methodVisitData);
            currentMethodIndex++;
        }
        if (falseCondition != null) {
            injectMethodVisitor.visitLabel(falseCondition);
        }
    } else {
        final MethodVisitData methodVisitData = new MethodVisitData(declaringType, methodElement, false);
        methodInjectionPoints.add(methodVisitData);
        allMethodVisits.add(methodVisitData);
        currentMethodIndex++;
    }
}
Also used : Type(org.objectweb.asm.Type) AdvisedBeanType(io.micronaut.inject.AdvisedBeanType) Label(org.objectweb.asm.Label) ClassElement(io.micronaut.inject.ast.ClassElement) ParameterElement(io.micronaut.inject.ast.ParameterElement) AnnotationMetadataHierarchy(io.micronaut.inject.annotation.AnnotationMetadataHierarchy) MutableAnnotationMetadata(io.micronaut.inject.annotation.MutableAnnotationMetadata) DefaultAnnotationMetadata(io.micronaut.inject.annotation.DefaultAnnotationMetadata) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata)

Example 28 with ParameterElement

use of io.micronaut.inject.ast.ParameterElement in project micronaut-core by micronaut-projects.

the class BeanDefinitionWriter method visitBuildMethodDefinition.

private void visitBuildMethodDefinition(MethodElement constructor, boolean requiresReflection) {
    if (buildMethodVisitor == null) {
        boolean isIntercepted = isConstructorIntercepted(constructor);
        final ParameterElement[] parameterArray = constructor.getParameters();
        List<ParameterElement> parameters = Arrays.asList(parameterArray);
        boolean isParametrized = isParametrized(parameterArray);
        defineBuilderMethod(isParametrized);
        // load this
        GeneratorAdapter buildMethodVisitor = this.buildMethodVisitor;
        // build the parameters into an Object[] and build a constructor invocation
        if (isIntercepted) {
            final int constructorIndex = initInterceptedConstructorWriter(buildMethodVisitor, parameters, null);
            // populate an Object[] of all constructor arguments
            final int parametersIndex = createParameterArray(parameters, buildMethodVisitor);
            invokeConstructorChain(buildMethodVisitor, constructorIndex, parametersIndex, parameters);
        } else {
            if (constructor.isStatic()) {
                pushConstructorArguments(buildMethodVisitor, parameterArray);
                final String methodDescriptor = getMethodDescriptor(constructor.getReturnType(), parameters);
                buildMethodVisitor.invokeStatic(getTypeReference(constructor.getDeclaringType()), new org.objectweb.asm.commons.Method(constructor.getName(), methodDescriptor));
            } else {
                if (requiresReflection) {
                    final int parameterArrayLocalVarIndex = createParameterArray(parameters, buildMethodVisitor);
                    final int parameterTypeArrayLocalVarIndex = createParameterTypeArray(parameters, buildMethodVisitor);
                    buildMethodVisitor.push(beanType);
                    buildMethodVisitor.loadLocal(parameterTypeArrayLocalVarIndex);
                    buildMethodVisitor.loadLocal(parameterArrayLocalVarIndex);
                    buildMethodVisitor.invokeStatic(Type.getType(InstantiationUtils.class), org.objectweb.asm.commons.Method.getMethod(ReflectionUtils.getRequiredInternalMethod(InstantiationUtils.class, "instantiate", Class.class, Class[].class, Object[].class)));
                    pushCastToType(buildMethodVisitor, beanType);
                } else {
                    buildMethodVisitor.newInstance(beanType);
                    buildMethodVisitor.dup();
                    pushConstructorArguments(buildMethodVisitor, parameterArray);
                    String constructorDescriptor = getConstructorDescriptor(parameters);
                    buildMethodVisitor.invokeConstructor(beanType, new org.objectweb.asm.commons.Method("<init>", constructorDescriptor));
                }
            }
        }
        this.buildInstanceLocalVarIndex = buildMethodVisitor.newLocal(beanType);
        buildMethodVisitor.storeLocal(buildInstanceLocalVarIndex);
        pushBeanDefinitionMethodInvocation(buildMethodVisitor, "injectBean");
        pushCastToType(buildMethodVisitor, beanType);
        buildMethodVisitor.storeLocal(buildInstanceLocalVarIndex);
        buildMethodVisitor.loadLocal(buildInstanceLocalVarIndex);
        initLifeCycleMethodsIfNecessary();
        pushBoxPrimitiveIfNecessary(beanType, buildMethodVisitor);
    }
}
Also used : AbstractConstructorInjectionPoint(io.micronaut.context.AbstractConstructorInjectionPoint) ConstructorInjectionPoint(io.micronaut.inject.ConstructorInjectionPoint) InstantiationUtils(io.micronaut.core.reflect.InstantiationUtils) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) ParameterElement(io.micronaut.inject.ast.ParameterElement)

Example 29 with ParameterElement

use of io.micronaut.inject.ast.ParameterElement in project micronaut-core by micronaut-projects.

the class BeanDefinitionWriter method visitBuildFactoryMethodDefinition.

private void visitBuildFactoryMethodDefinition(ClassElement factoryClass, Element factoryMethod) {
    if (buildMethodVisitor == null) {
        ParameterElement[] parameters;
        if (factoryMethod instanceof MethodElement) {
            parameters = ((MethodElement) factoryMethod).getParameters();
        } else {
            parameters = new ParameterElement[0];
        }
        List<ParameterElement> parameterList = Arrays.asList(parameters);
        boolean isParametrized = isParametrized(parameters);
        boolean isIntercepted = isConstructorIntercepted(factoryMethod);
        Type factoryType = JavaModelUtils.getTypeReference(factoryClass);
        defineBuilderMethod(isParametrized);
        // load this
        GeneratorAdapter buildMethodVisitor = this.buildMethodVisitor;
        // for Factory beans first we need to lookup the the factory bean
        // before invoking the method to instantiate
        // the below code looks up the factory bean.
        // Load the BeanContext for the method call
        buildMethodVisitor.loadArg(1);
        pushCastToType(buildMethodVisitor, DefaultBeanContext.class);
        // load the first argument of the method (the BeanResolutionContext) to be passed to the method
        buildMethodVisitor.loadArg(0);
        // second argument is the bean type
        buildMethodVisitor.push(factoryType);
        buildMethodVisitor.invokeVirtual(Type.getType(DefaultBeanContext.class), org.objectweb.asm.commons.Method.getMethod(METHOD_GET_BEAN));
        // store a reference to the bean being built at index 3
        int factoryVar = buildMethodVisitor.newLocal(JavaModelUtils.getTypeReference(factoryClass));
        buildMethodVisitor.storeLocal(factoryVar);
        buildMethodVisitor.loadLocal(factoryVar);
        pushCastToType(buildMethodVisitor, factoryClass);
        String methodDescriptor = getMethodDescriptorForReturnType(beanType, parameterList);
        boolean hasInjectScope = false;
        if (isIntercepted) {
            int constructorIndex = initInterceptedConstructorWriter(buildMethodVisitor, parameterList, new FactoryMethodDef(factoryType, factoryMethod, methodDescriptor, factoryVar));
            // populate an Object[] of all constructor arguments
            final int parametersIndex = createParameterArray(parameterList, buildMethodVisitor);
            invokeConstructorChain(buildMethodVisitor, constructorIndex, parametersIndex, parameterList);
        } else {
            if (!parameterList.isEmpty()) {
                hasInjectScope = pushConstructorArguments(buildMethodVisitor, parameters);
            }
            if (factoryMethod instanceof MethodElement) {
                buildMethodVisitor.visitMethodInsn(INVOKEVIRTUAL, factoryType.getInternalName(), factoryMethod.getName(), methodDescriptor, false);
            } else {
                buildMethodVisitor.getField(factoryType, factoryMethod.getName(), beanType);
            }
        }
        this.buildInstanceLocalVarIndex = buildMethodVisitor.newLocal(beanType);
        buildMethodVisitor.storeLocal(buildInstanceLocalVarIndex);
        if (!isPrimitiveBean) {
            pushBeanDefinitionMethodInvocation(buildMethodVisitor, "injectBean");
            pushCastToType(buildMethodVisitor, beanType);
            buildMethodVisitor.storeLocal(buildInstanceLocalVarIndex);
        }
        destroyInjectScopeBeansIfNecessary(buildMethodVisitor, hasInjectScope);
        buildMethodVisitor.loadLocal(buildInstanceLocalVarIndex);
        initLifeCycleMethodsIfNecessary();
    }
}
Also used : Type(org.objectweb.asm.Type) AdvisedBeanType(io.micronaut.inject.AdvisedBeanType) MethodElement(io.micronaut.inject.ast.MethodElement) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) DefaultBeanContext(io.micronaut.context.DefaultBeanContext) ParameterElement(io.micronaut.inject.ast.ParameterElement) AbstractConstructorInjectionPoint(io.micronaut.context.AbstractConstructorInjectionPoint) ConstructorInjectionPoint(io.micronaut.inject.ConstructorInjectionPoint)

Example 30 with ParameterElement

use of io.micronaut.inject.ast.ParameterElement in project micronaut-core by micronaut-projects.

the class BeanDefinitionWriter method pushConstructorArguments.

private boolean pushConstructorArguments(GeneratorAdapter buildMethodVisitor, ParameterElement[] parameters) {
    int size = parameters.length;
    boolean hasInjectScope = false;
    if (size > 0) {
        for (int i = 0; i < parameters.length; i++) {
            ParameterElement parameter = parameters[i];
            pushConstructorArgument(buildMethodVisitor, parameter.getName(), parameter, parameter.getAnnotationMetadata(), i);
            if (parameter.hasDeclaredAnnotation(InjectScope.class)) {
                hasInjectScope = true;
            }
        }
    }
    return hasInjectScope;
}
Also used : ParameterElement(io.micronaut.inject.ast.ParameterElement) AbstractConstructorInjectionPoint(io.micronaut.context.AbstractConstructorInjectionPoint) ConstructorInjectionPoint(io.micronaut.inject.ConstructorInjectionPoint)

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