From 01182491eac508b4f187c36e468bc7c428657b4a Mon Sep 17 00:00:00 2001 From: Dirk Mahler Date: Fri, 4 Jun 2021 22:26:28 +0200 Subject: [PATCH] #32 added ITs for generic methods --- .../impl/scanner/visitor/ClassVisitor.java | 8 +- .../generics/AbstractBoundVisitor.java | 3 - .../AbstractGenericDeclarationVisitor.java | 2 + .../test/scanner/generics/JavaGenericsIT.java | 102 ++++++++++++++---- .../set/scanner/generics/GenericFields.java | 2 + .../set/scanner/generics/GenericMethods.java | 7 +- 6 files changed, 91 insertions(+), 33 deletions(-) diff --git a/src/main/java/com/buschmais/jqassistant/plugin/java/impl/scanner/visitor/ClassVisitor.java b/src/main/java/com/buschmais/jqassistant/plugin/java/impl/scanner/visitor/ClassVisitor.java index e4e9078..13cc893 100644 --- a/src/main/java/com/buschmais/jqassistant/plugin/java/impl/scanner/visitor/ClassVisitor.java +++ b/src/main/java/com/buschmais/jqassistant/plugin/java/impl/scanner/visitor/ClassVisitor.java @@ -122,13 +122,13 @@ public MethodVisitor visitMethod(final int access, final String name, final Stri ParameterDescriptor parameterDescriptor = visitorHelper.addParameterDescriptor(methodDescriptor, i); parameterDescriptor.setType(typeDescriptor); } + for (int i = 0; exceptions != null && i < exceptions.length; i++) { + TypeDescriptor exceptionType = visitorHelper.resolveType(SignatureHelper.getObjectType(exceptions[i]), cachedType).getTypeDescriptor(); + methodDescriptor.getThrows().add(exceptionType); + } } else { new SignatureReader(signature).accept(new MethodSignatureVisitor(cachedType, methodDescriptor, visitorHelper)); } - for (int i = 0; exceptions != null && i < exceptions.length; i++) { - TypeDescriptor exceptionType = visitorHelper.resolveType(SignatureHelper.getObjectType(exceptions[i]), cachedType).getTypeDescriptor(); - methodDescriptor.getThrows().add(exceptionType); - } return new MethodVisitor(cachedType, methodDescriptor, visitorHelper); } diff --git a/src/main/java/com/buschmais/jqassistant/plugin/java/impl/scanner/visitor/generics/AbstractBoundVisitor.java b/src/main/java/com/buschmais/jqassistant/plugin/java/impl/scanner/visitor/generics/AbstractBoundVisitor.java index 4d7a8e8..1af0307 100644 --- a/src/main/java/com/buschmais/jqassistant/plugin/java/impl/scanner/visitor/generics/AbstractBoundVisitor.java +++ b/src/main/java/com/buschmais/jqassistant/plugin/java/impl/scanner/visitor/generics/AbstractBoundVisitor.java @@ -33,9 +33,6 @@ public AbstractBoundVisitor(VisitorHelper visitorHelper, TypeCache.CachedType typeArguments = getActualTypeArguments(parameterizedType, 2); assertThat(typeArguments.get(0).getRawType()).is(matching(typeDescriptor(String.class))); - verifyTypeVariable(typeArguments.get(1), "X", typeDescriptor(GenericFields.class)); + verifyTypeVariable(typeArguments.get(1), "X", typeDescriptor(GenericFields.class), Object.class); store.commitTransaction(); } @@ -151,7 +160,7 @@ void fieldOfParameterizedType() { void fieldOfNestedParameterizedType() { scanClasses(GenericFields.class); store.beginTransaction(); - FieldDescriptor field = getField("nestedParameterizedType"); + FieldDescriptor field = getMember("GenericFields", "nestedParameterizedType"); assertThat(field.getType()).is(matching(typeDescriptor(List.class))); BoundDescriptor genericType = field.getGenericType(); assertThat(genericType).isNotNull().isInstanceOf(ParameterizedTypeDescriptor.class); @@ -172,7 +181,7 @@ void fieldOfNestedParameterizedType() { void fieldOfUpperBoundWildcard() { scanClasses(GenericFields.class); store.beginTransaction(); - FieldDescriptor field = getField("upperBoundWildcard"); + FieldDescriptor field = getMember("GenericFields", "upperBoundWildcard"); assertThat(field.getType()).is(matching(typeDescriptor(List.class))); BoundDescriptor genericType = field.getGenericType(); WildcardTypeDescriptor wildcardType = getListOfWildcard(genericType); @@ -185,7 +194,7 @@ void fieldOfUpperBoundWildcard() { void fieldOfLowerBoundWildcard() { scanClasses(GenericFields.class); store.beginTransaction(); - FieldDescriptor field = getField("lowerBoundWildcard"); + FieldDescriptor field = getMember("GenericFields", "lowerBoundWildcard"); assertThat(field.getType()).is(matching(typeDescriptor(List.class))); BoundDescriptor genericType = field.getGenericType(); WildcardTypeDescriptor wildcardType = getListOfWildcard(genericType); @@ -198,7 +207,7 @@ void fieldOfLowerBoundWildcard() { void fieldOfUnboundWildcard() { scanClasses(GenericFields.class); store.beginTransaction(); - FieldDescriptor field = getField("unboundWildcard"); + FieldDescriptor field = getMember("GenericFields", "unboundWildcard"); assertThat(field.getType()).is(matching(typeDescriptor(List.class))); BoundDescriptor genericType = field.getGenericType(); WildcardTypeDescriptor wildcardType = getListOfWildcard(genericType); @@ -207,12 +216,60 @@ void fieldOfUnboundWildcard() { store.commitTransaction(); } - private FieldDescriptor getField(String fieldName) { - Map parameters = MapBuilder. builder().entry("fieldName", fieldName).build(); - List fields = query("MATCH (:Type{name:'GenericFields'})-[:DECLARES]->(field:Java:ByteCode:Field{name:$fieldName}) RETURN field", - parameters).getColumn("field"); - assertThat(fields).hasSize(1); - return fields.get(0); + @Test + void genericParameter() { + scanClasses(GenericMethods.class); + store.beginTransaction(); + MethodDescriptor genericParameter = getMember("GenericMethods", "genericParameter"); + List parameters = genericParameter.getParameters(); + assertThat(parameters).hasSize(1); + ParameterDescriptor parameter = parameters.get(0); + assertThat(parameter.getIndex()).isEqualTo(0); + assertThat(parameter.getType()).is(matching(typeDescriptor(Object.class))); + verifyTypeVariable(parameter.getGenericType(), "X", typeDescriptor(GenericMethods.class), Object.class); + store.commitTransaction(); + } + + @Test + void genericReturnType() { + scanClasses(GenericMethods.class); + store.beginTransaction(); + MethodDescriptor genericReturnType = getMember("GenericMethods", "genericReturnType"); + assertThat(genericReturnType.getReturns()).is(matching(typeDescriptor(Object.class))); + verifyTypeVariable(genericReturnType.getReturnsGeneric(), "X", typeDescriptor(GenericMethods.class), Object.class); + store.commitTransaction(); + } + + @Test + void genericException() throws NoSuchMethodException { + scanClasses(GenericMethods.class); + store.beginTransaction(); + MethodDescriptor genericException = getMember("GenericMethods", "genericException"); + List throwsExceptions = genericException.getThrows(); + assertThat(throwsExceptions).hasSize(1); + assertThat(throwsExceptions.get(0)).is(matching(typeDescriptor(IOException.class))); + List throwsGenericExceptions = genericException.getThrowsGeneric(); + assertThat(throwsGenericExceptions).hasSize(1); + verifyTypeVariable(throwsGenericExceptions.get(0), "E", methodDescriptor(GenericMethods.class, "genericException"), IOException.class); + store.commitTransaction(); + } + + @Test + void overwriteTypeParameter() throws NoSuchMethodException { + scanClasses(GenericMethods.class); + store.beginTransaction(); + MethodDescriptor overwriteTypeParameter = getMember("GenericMethods", "overwriteTypeParameter"); + assertThat(overwriteTypeParameter.getReturns()).is(matching(typeDescriptor(Object.class))); + verifyTypeVariable(overwriteTypeParameter.getReturnsGeneric(), "X", methodDescriptor(GenericMethods.class, "overwriteTypeParameter"), Object.class); + store.commitTransaction(); + } + + private T getMember(String typeName, String memberName) { + Map parameters = MapBuilder. builder().entry("typeName", typeName).entry("memberName", memberName).build(); + List members = query("MATCH (:Type{name:$typeName})-[:DECLARES]->(member:Java:ByteCode:Member{name:$memberName}) RETURN member", parameters) + .getColumn("member"); + assertThat(members).hasSize(1); + return members.get(0); } private WildcardTypeDescriptor getListOfWildcard(BoundDescriptor genericType) { @@ -233,11 +290,12 @@ private void verifyWildcardBounds(List bounds) { assertThat(typeVariable.getName()).isEqualTo("X"); } - private void verifyTypeVariable(BoundDescriptor bound, String expectedName, Matcher declaredBy) { + private void verifyTypeVariable(BoundDescriptor bound, String expectedName, Matcher declaredBy, Class expectedRawType) { assertThat(bound).isNotNull().isInstanceOf(TypeVariableDescriptor.class); TypeVariableDescriptor typeVariable = (TypeVariableDescriptor) bound; assertThat(typeVariable.getName()).isEqualTo(expectedName); assertThat(typeVariable.getDeclaredBy().getGenericDeclaration()).is(matching(declaredBy)); + assertThat(typeVariable.getRawType()).is(matching(typeDescriptor(expectedRawType))); } private Map getActualTypeArguments(ParameterizedTypeDescriptor parameterizedType, int expectedTypeArgumentCount) { diff --git a/src/test/java/com/buschmais/jqassistant/plugin/java/test/set/scanner/generics/GenericFields.java b/src/test/java/com/buschmais/jqassistant/plugin/java/test/set/scanner/generics/GenericFields.java index 9f5b002..cfe5cfe 100644 --- a/src/test/java/com/buschmais/jqassistant/plugin/java/test/set/scanner/generics/GenericFields.java +++ b/src/test/java/com/buschmais/jqassistant/plugin/java/test/set/scanner/generics/GenericFields.java @@ -7,6 +7,8 @@ public class GenericFields { private X typeVariable; + private X[] arrayOfTypeVariable; + private Map parameterizedType; private List> nestedParameterizedType; diff --git a/src/test/java/com/buschmais/jqassistant/plugin/java/test/set/scanner/generics/GenericMethods.java b/src/test/java/com/buschmais/jqassistant/plugin/java/test/set/scanner/generics/GenericMethods.java index eb6c625..7266e3a 100644 --- a/src/test/java/com/buschmais/jqassistant/plugin/java/test/set/scanner/generics/GenericMethods.java +++ b/src/test/java/com/buschmais/jqassistant/plugin/java/test/set/scanner/generics/GenericMethods.java @@ -1,11 +1,10 @@ package com.buschmais.jqassistant.plugin.java.test.set.scanner.generics; import java.io.IOException; -import java.util.List; public class GenericMethods { - void genericParameter(X x, List listOfString) { + void genericParameter(X x) { } X genericReturnType() { @@ -13,10 +12,10 @@ X genericReturnType() { } void genericException() throws E { - } - void overwriteGenericDeclaration(X x) { + X overwriteTypeParameter() { + return null; } }