Skip to content
This repository has been archived by the owner on Jul 10, 2024. It is now read-only.

Commit

Permalink
#32 added ITs for generic methods
Browse files Browse the repository at this point in the history
  • Loading branch information
DirkMahler committed Jun 4, 2021
1 parent 309aa55 commit 0118249
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ public AbstractBoundVisitor(VisitorHelper visitorHelper, TypeCache.CachedType<?
this.containingType = containingType;
}

// visitBaseType | visitTypeVariable | visitArrayType | ( visitClassType
// visitTypeArgument* ( visitInnerClassType visitTypeArgument* )* visitEnd )

@Override
public final void visitBaseType(char descriptor) {
// TODO check if this is the right way to determine the primitive type
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public final SignatureVisitor visitClassBound() {
return new AbstractBoundVisitor(visitorHelper, containingType) {
@Override
protected void apply(TypeDescriptor rawTypeBound, BoundDescriptor bound) {
currentTypeParameter.setRawType(rawTypeBound);
currentTypeParameter.getBounds().add(bound);
}
};
Expand All @@ -58,6 +59,7 @@ public final SignatureVisitor visitInterfaceBound() {
return new AbstractBoundVisitor(visitorHelper, containingType) {
@Override
protected void apply(TypeDescriptor rawTypeBound, BoundDescriptor bound) {
currentTypeParameter.setRawType(rawTypeBound);
currentTypeParameter.getBounds().add(bound);
}
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
package com.buschmais.jqassistant.plugin.java.test.scanner.generics;

import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.*;
import java.util.AbstractList;
import java.util.List;
import java.util.Map;

import com.buschmais.jqassistant.core.shared.map.MapBuilder;
import com.buschmais.jqassistant.plugin.java.api.model.FieldDescriptor;
import com.buschmais.jqassistant.plugin.java.api.model.TypeDescriptor;
import com.buschmais.jqassistant.plugin.java.api.model.*;
import com.buschmais.jqassistant.plugin.java.api.model.generics.*;
import com.buschmais.jqassistant.plugin.java.test.AbstractJavaPluginIT;
import com.buschmais.jqassistant.plugin.java.test.set.scanner.generics.ExtendsGeneric;
import com.buschmais.jqassistant.plugin.java.test.set.scanner.generics.GenericFields;
import com.buschmais.jqassistant.plugin.java.test.set.scanner.generics.GenericTypeDeclarations;
import com.buschmais.jqassistant.plugin.java.test.set.scanner.generics.ImplementsGeneric;
import com.buschmais.jqassistant.plugin.java.test.set.scanner.generics.*;

import lombok.extern.slf4j.Slf4j;
import org.hamcrest.Matcher;
import org.junit.jupiter.api.Test;

import static com.buschmais.jqassistant.plugin.java.test.matcher.MethodDescriptorMatcher.methodDescriptor;
import static com.buschmais.jqassistant.plugin.java.test.matcher.TypeDescriptorMatcher.typeDescriptor;
import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;
Expand Down Expand Up @@ -124,34 +122,45 @@ void extendsGeneric() {
void fieldOfTypeVariable() {
scanClasses(GenericFields.class);
store.beginTransaction();
FieldDescriptor field = getField("typeVariable");
FieldDescriptor field = getMember("GenericFields", "typeVariable");
assertThat(field.getType()).is(matching(typeDescriptor(Object.class)));
BoundDescriptor genericType = field.getGenericType();
verifyTypeVariable(genericType, "X", typeDescriptor(GenericFields.class));
verifyTypeVariable(field.getGenericType(), "X", typeDescriptor(GenericFields.class), Object.class);
store.commitTransaction();
}

@Test
void fieldOfArrayOfTypeVariable() {
scanClasses(GenericFields.class);
store.beginTransaction();
FieldDescriptor field = getMember("GenericFields", "arrayOfTypeVariable");
assertThat(field.getType()).is(matching(typeDescriptor(Object.class)));
BoundDescriptor bound = field.getGenericType();
assertThat(bound).isInstanceOf(GenericArrayTypeDescriptor.class);
verifyTypeVariable(((GenericArrayTypeDescriptor) bound).getComponentType(), "X", typeDescriptor(GenericFields.class), Object.class);
store.commitTransaction();
}

@Test
void fieldOfParameterizedType() {
scanClasses(GenericFields.class);
store.beginTransaction();
FieldDescriptor field = getField("parameterizedType");
FieldDescriptor field = getMember("GenericFields", "parameterizedType");
assertThat(field.getType()).is(matching(typeDescriptor(Map.class)));
BoundDescriptor genericType = field.getGenericType();
assertThat(genericType).isNotNull().isInstanceOf(ParameterizedTypeDescriptor.class);
ParameterizedTypeDescriptor parameterizedType = (ParameterizedTypeDescriptor) genericType;
assertThat(parameterizedType.getRawType()).is(matching(typeDescriptor(Map.class)));
Map<Integer, BoundDescriptor> 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();
}

@Test
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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -207,12 +216,60 @@ void fieldOfUnboundWildcard() {
store.commitTransaction();
}

private FieldDescriptor getField(String fieldName) {
Map<String, Object> parameters = MapBuilder.<String, Object> builder().entry("fieldName", fieldName).build();
List<FieldDescriptor> 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<ParameterDescriptor> 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<TypeDescriptor> throwsExceptions = genericException.getThrows();
assertThat(throwsExceptions).hasSize(1);
assertThat(throwsExceptions.get(0)).is(matching(typeDescriptor(IOException.class)));
List<BoundDescriptor> 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 extends MemberDescriptor> T getMember(String typeName, String memberName) {
Map<String, Object> parameters = MapBuilder.<String, Object> builder().entry("typeName", typeName).entry("memberName", memberName).build();
List<T> 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) {
Expand All @@ -233,11 +290,12 @@ private void verifyWildcardBounds(List<BoundDescriptor> 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<Integer, BoundDescriptor> getActualTypeArguments(ParameterizedTypeDescriptor parameterizedType, int expectedTypeArgumentCount) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ public class GenericFields<X> {

private X typeVariable;

private X[] arrayOfTypeVariable;

private Map<String, X> parameterizedType;

private List<List<String>> nestedParameterizedType;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
package com.buschmais.jqassistant.plugin.java.test.set.scanner.generics;

import java.io.IOException;
import java.util.List;

public class GenericMethods<X> {

void genericParameter(X x, List<String> listOfString) {
void genericParameter(X x) {
}

X genericReturnType() {
return null;
}

<E extends IOException> void genericException() throws E {

}

<X> void overwriteGenericDeclaration(X x) {
<X> X overwriteTypeParameter() {
return null;
}

}

0 comments on commit 0118249

Please sign in to comment.