Skip to content

Commit

Permalink
Fix handling of raw generic argument types
Browse files Browse the repository at this point in the history
  • Loading branch information
graemerocher committed May 2, 2019
1 parent d29ebc5 commit 9c9b273
Show file tree
Hide file tree
Showing 12 changed files with 195 additions and 63 deletions.
20 changes: 17 additions & 3 deletions aop/src/main/java/io/micronaut/aop/writer/AopProxyWriter.java
Expand Up @@ -375,13 +375,13 @@ public void visitBeanDefinitionConstructor(

/**
* Visit a method that is to be proxied.
*
* @param declaringType The declaring type of the method. Either a Class or a string representing the name of the type
* @param declaringType The declaring type of the method. Either a Class or a string representing the name of the type
* @param returnType The return type of the method. Either a Class or a string representing the name of the type
* @param genericReturnType The generic return type
* @param returnTypeGenericTypes Map containing the return generic types
* @param methodName The method name
* @param argumentTypes The argument types. Note: an ordered map should be used such as LinkedHashMap. Can be null or empty.
* @param genericParameters The generic argument types
* @param argumentAnnotationMetadata The argument annotation metadata
* @param genericTypes The generic types of each argument. Can be null.
* @param annotationMetadata metadata
Expand All @@ -392,6 +392,7 @@ public void visitAroundMethod(Object declaringType,
Map<String, Object> returnTypeGenericTypes,
String methodName,
Map<String, Object> argumentTypes,
Map<String, Object> genericParameters,
Map<String, AnnotationMetadata> argumentAnnotationMetadata,
Map<String, Map<String, Object>> genericTypes,
AnnotationMetadata annotationMetadata) {
Expand All @@ -404,6 +405,7 @@ public void visitAroundMethod(Object declaringType,
returnTypeGenericTypes,
methodName,
argumentTypes,
genericParameters,
argumentAnnotationMetadata,
genericTypes,
annotationMetadata);
Expand Down Expand Up @@ -466,7 +468,17 @@ protected void buildInvokeMethod(Type declaringTypeObject, String methodName, Ob

};
executableMethodWriter.makeInner(proxyInternalName, classWriter);
executableMethodWriter.visitMethod(declaringType, returnType, genericReturnType, returnTypeGenericTypes, methodName, argumentTypes, argumentAnnotationMetadata, genericTypes);
executableMethodWriter.visitMethod(
declaringType,
returnType,
genericReturnType,
returnTypeGenericTypes,
methodName,
argumentTypes,
genericParameters,
argumentAnnotationMetadata,
genericTypes
);

proxiedMethods.add(executableMethodWriter);
proxiedMethodsRefSet.add(methodKey);
Expand Down Expand Up @@ -1021,6 +1033,7 @@ public ExecutableMethodWriter visitExecutableMethod(
Map<String, Object> returnTypeGenericTypes,
String methodName,
Map<String, Object> argumentTypes,
Map<String, Object> genericArgumentTypes,
Map<String, AnnotationMetadata> argumentAnnotationMetadata,
Map<String, Map<String, Object>> genericTypes,
AnnotationMetadata annotationMetadata) {
Expand All @@ -1032,6 +1045,7 @@ public ExecutableMethodWriter visitExecutableMethod(
returnTypeGenericTypes,
methodName,
argumentTypes,
genericArgumentTypes,
argumentAnnotationMetadata,
genericTypes,
annotationMetadata
Expand Down
Expand Up @@ -33,8 +33,6 @@ import io.micronaut.inject.writer.DirectoryClassWriterOutputVisitor
import io.micronaut.inject.writer.GeneratedFile

import javax.inject.Named
import javax.lang.model.element.ExecutableElement
import javax.lang.model.element.VariableElement
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicInteger
import java.util.function.Function
Expand Down Expand Up @@ -433,6 +431,7 @@ class InjectTransform implements ASTTransformation, CompilationUnitAware {
@Override
void accept(ClassNode classNode, MethodNode methodNode) {
Map<String, Object> targetMethodParamsToType = [:]
Map<String, Object> targetGenericParams = [:]
Map<String, AnnotationMetadata> targetAnnotationMetadata = [:]
Map<String, Map<String, Object>> targetMethodGenericTypeMap = [:]

Expand All @@ -449,8 +448,11 @@ class InjectTransform implements ASTTransformation, CompilationUnitAware {
populateParameterData(
methodNode,
targetMethodParamsToType,
targetGenericParams,
targetAnnotationMetadata,
targetMethodGenericTypeMap)
targetMethodGenericTypeMap,
boundTypes
)


AnnotationMetadata annotationMetadata
Expand All @@ -469,6 +471,7 @@ class InjectTransform implements ASTTransformation, CompilationUnitAware {
resolvedGenericTypes,
methodNode.name,
targetMethodParamsToType,
targetGenericParams,
targetAnnotationMetadata,
targetMethodGenericTypeMap,
annotationMetadata
Expand Down Expand Up @@ -541,9 +544,17 @@ class InjectTransform implements ASTTransformation, CompilationUnitAware {
}

Map<String, Object> paramsToType = [:]
Map<String, Object> paramsGenerics = [:]
Map<String, AnnotationMetadata> argumentAnnotationMetadata = [:]
Map<String, Map<String, Object>> genericTypeMap = [:]
populateParameterData(methodNode, paramsToType, argumentAnnotationMetadata, genericTypeMap)
populateParameterData(
methodNode,
paramsToType,
paramsGenerics,
argumentAnnotationMetadata,
genericTypeMap,
genericsSpec
)

beanMethodWriter.visitBeanFactoryMethod(
AstGenericUtils.resolveTypeReference(concreteClass),
Expand Down Expand Up @@ -590,6 +601,7 @@ class InjectTransform implements ASTTransformation, CompilationUnitAware {
@Override
void accept(ClassNode classNode, MethodNode targetBeanMethodNode) {
Map<String, Object> targetMethodParamsToType = [:]
Map<String, Object> targetGenericParams = [:]
Map<String, AnnotationMetadata> targetAnnotationMetadata = [:]
Map<String, Map<String, Object>> targetMethodGenericTypeMap = [:]
Map<String, ClassNode> boundTypes = AstGenericUtils.createGenericsSpec(classNode)
Expand All @@ -603,8 +615,10 @@ class InjectTransform implements ASTTransformation, CompilationUnitAware {
populateParameterData(
targetBeanMethodNode,
targetMethodParamsToType,
targetGenericParams,
targetAnnotationMetadata,
targetMethodGenericTypeMap)
targetMethodGenericTypeMap,
boundTypes)
AnnotationMetadata annotationMetadata
if (AstAnnotationUtils.isAnnotated(methodNode)) {
annotationMetadata = AstAnnotationUtils.getAnnotationMetadata(source, methodNode, targetBeanMethodNode)
Expand All @@ -622,6 +636,7 @@ class InjectTransform implements ASTTransformation, CompilationUnitAware {
resolvedGenericTypes,
targetBeanMethodNode.name,
targetMethodParamsToType,
targetGenericParams,
targetAnnotationMetadata,
targetMethodGenericTypeMap,
annotationMetadata
Expand All @@ -634,6 +649,7 @@ class InjectTransform implements ASTTransformation, CompilationUnitAware {
resolvedGenericTypes,
targetBeanMethodNode.name,
targetMethodParamsToType,
targetGenericParams,
targetAnnotationMetadata,
targetMethodGenericTypeMap,
new AnnotationMetadataReference(writer.getClassName(), annotationMetadata)
Expand Down Expand Up @@ -698,7 +714,14 @@ class InjectTransform implements ASTTransformation, CompilationUnitAware {
Map<String, Object> paramsToType = [:]
Map<String, AnnotationMetadata> argumentAnnotationMetadata = [:]
Map<String, Map<String, Object>> genericTypeMap = [:]
populateParameterData(methodNode, paramsToType, argumentAnnotationMetadata, genericTypeMap)
populateParameterData(
methodNode,
paramsToType,
paramsToType,
argumentAnnotationMetadata,
genericTypeMap,
Collections.emptyMap()
)

if (methodAnnotationMetadata.hasStereotype(ProcessedTypes.POST_CONSTRUCT)) {
def beanWriter = getBeanWriter()
Expand Down Expand Up @@ -812,16 +835,29 @@ class InjectTransform implements ASTTransformation, CompilationUnitAware {
}
}

private void visitExecutableMethod(ClassNode declaringClass, MethodNode methodNode, AnnotationMetadata methodAnnotationMetadata, String methodName, boolean isPublic) {
private void visitExecutableMethod(
ClassNode declaringClass,
MethodNode methodNode,
AnnotationMetadata methodAnnotationMetadata,
String methodName, boolean isPublic) {
if (declaringClass != ClassHelper.OBJECT_TYPE) {

defineBeanDefinition(concreteClass)
Map<String, Object> returnTypeGenerics = AstGenericUtils.buildGenericTypeInfo(methodNode.returnType, GenericsUtils.createGenericsSpec(concreteClass))
Map<String, ClassNode> genericsSpec = AstGenericUtils.createGenericsSpec(methodNode, GenericsUtils.createGenericsSpec(concreteClass))

Map<String, Object> paramsToType = [:]
Map<String, Object> genericParams = [:]
Map<String, AnnotationMetadata> qualifierTypes = [:]
Map<String, Map<String, Object>> genericTypeMap = [:]
populateParameterData(methodNode, paramsToType, qualifierTypes, genericTypeMap)
populateParameterData(
methodNode,
paramsToType,
genericParams,
qualifierTypes,
genericTypeMap,
genericsSpec
)

boolean preprocess = methodAnnotationMetadata.getValue(Executable.class, "processOnStartup", Boolean.class).orElse(false)
if (preprocess) {
Expand All @@ -834,8 +870,11 @@ class InjectTransform implements ASTTransformation, CompilationUnitAware {
returnTypeGenerics,
methodName,
paramsToType,
genericParams,
qualifierTypes,
genericTypeMap, methodAnnotationMetadata)
genericTypeMap,
methodAnnotationMetadata
)

if (methodAnnotationMetadata.hasStereotype(Adapter.class)) {
visitAdaptedMethod(methodNode, methodAnnotationMetadata)
Expand Down Expand Up @@ -870,6 +909,7 @@ class InjectTransform implements ASTTransformation, CompilationUnitAware {
returnTypeGenerics,
methodName,
paramsToType,
genericParams,
qualifierTypes,
genericTypeMap,
new AnnotationMetadataReference(executableMethodWriter.getClassName(), methodAnnotationMetadata)
Expand Down Expand Up @@ -925,8 +965,10 @@ class InjectTransform implements ASTTransformation, CompilationUnitAware {
Map<String, Map<String, Object>> constructorGenericTypeMap = [:]
populateParameterData(constructorNode,
constructorParamsToType,
constructorParamsToType,
constructorArgumentMetadata,
constructorGenericTypeMap)
constructorGenericTypeMap,
Collections.emptyMap())
proxyWriter.visitBeanDefinitionConstructor(
AstAnnotationUtils.getAnnotationMetadata(sourceUnit, constructorNode),
constructorNode.isPrivate(),
Expand Down Expand Up @@ -1189,6 +1231,7 @@ class InjectTransform implements ASTTransformation, CompilationUnitAware {
emptyMap,
getSetterName(propertyName),
resolvedArguments,
resolvedArguments,
resolvedAnnotationMetadata,
resolvedGenericTypes,
fieldAnnotationMetadata
Expand All @@ -1201,6 +1244,7 @@ class InjectTransform implements ASTTransformation, CompilationUnitAware {
emptyMap,
getSetterName(propertyName),
resolvedArguments,
resolvedArguments,
resolvedAnnotationMetadata,
resolvedGenericTypes,
fieldAnnotationMetadata
Expand All @@ -1217,6 +1261,7 @@ class InjectTransform implements ASTTransformation, CompilationUnitAware {
emptyMap,
emptyMap,
emptyMap,
emptyMap,
fieldAnnotationMetadata
)

Expand All @@ -1229,6 +1274,7 @@ class InjectTransform implements ASTTransformation, CompilationUnitAware {
emptyMap,
emptyMap,
emptyMap,
emptyMap,
fieldAnnotationMetadata
)
}
Expand Down Expand Up @@ -1313,7 +1359,14 @@ class InjectTransform implements ASTTransformation, CompilationUnitAware {
Map<String, Object> paramsToType = [:]
Map<String, AnnotationMetadata> qualifierTypes = [:]
Map<String, Map<String, Object>> genericTypeMap = [:]
populateParameterData(constructorNode, paramsToType, qualifierTypes, genericTypeMap)
populateParameterData(
constructorNode,
paramsToType,
paramsToType,
qualifierTypes,
genericTypeMap,
Collections.emptyMap()
)
beanWriter.visitBeanDefinitionConstructor(
AstAnnotationUtils.getAnnotationMetadata(sourceUnit, constructorNode),
constructorNode.isPrivate(),
Expand Down Expand Up @@ -1438,6 +1491,7 @@ class InjectTransform implements ASTTransformation, CompilationUnitAware {
}

Map<String, Object> targetMethodParamsToType = [:]
Map<String, Object> targetMethodGenericParams = [:]
Map<String, AnnotationMetadata> targetAnnotationMetadata = [:]
Map<String, Map<String, Object>> targetMethodGenericTypeMap = [:]

Expand All @@ -1452,8 +1506,11 @@ class InjectTransform implements ASTTransformation, CompilationUnitAware {
populateParameterData(
targetMethod,
targetMethodParamsToType,
targetMethodGenericParams,
targetAnnotationMetadata,
targetMethodGenericTypeMap)
targetMethodGenericTypeMap,
boundTypes
)

AnnotationClassValue[] adaptedArgumentTypes = new AnnotationClassValue[sourceParameters.length]
int j = 0
Expand Down Expand Up @@ -1491,6 +1548,7 @@ class InjectTransform implements ASTTransformation, CompilationUnitAware {
resolvedGenericTypes,
targetMethod.name,
targetMethodParamsToType,
targetMethodGenericParams,
targetAnnotationMetadata,
targetMethodGenericTypeMap,
annotationMetadata
Expand Down Expand Up @@ -1536,11 +1594,18 @@ class InjectTransform implements ASTTransformation, CompilationUnitAware {
constructorNode
}

private void populateParameterData(MethodNode methodNode, Map<String, Object> paramsToType, Map<String, AnnotationMetadata> anntationMetadata, Map<String, Map<String, Object>> genericTypeMap) {
private void populateParameterData(
MethodNode methodNode,
Map<String, Object> paramsToType,
Map<String, Object> genericParams,
Map<String, AnnotationMetadata> anntationMetadata,
Map<String, Map<String, Object>> genericTypeMap,
Map<String, ClassNode> boundTypes) {
for (Parameter param in methodNode.parameters) {
String parameterName = param.name

paramsToType.put(parameterName, resolveParameterType(param))
genericParams.put(parameterName, AstGenericUtils.resolveTypeReference(param.type, boundTypes))

anntationMetadata.put(parameterName, AstAnnotationUtils.getAnnotationMetadata(sourceUnit, new ExtendedParameter(methodNode, param)))

Expand Down
Expand Up @@ -165,7 +165,12 @@ class AstGenericUtils {

String typeVar = classNode.genericsTypes[0].name
if (boundTypes.containsKey(typeVar)) {
return boundTypes.get(typeVar).name
def resolved = boundTypes.get(typeVar)
if (resolved.isGenericsPlaceHolder()) {
return resolveTypeReference(resolved, boundTypes)
} else {
return resolved.name
}
}
} else {
if (classNode.isResolved() || ClassHelper.isPrimitiveType(classNode)) {
Expand Down

0 comments on commit 9c9b273

Please sign in to comment.