From 623acb6f10c5fec3cdba1c09a3422ecfac170454 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Sun, 5 Jan 2014 19:45:49 +0100 Subject: [PATCH] #79 Some typo fixes, simplifications and comment improvements --- .../org/mapstruct/ap/util/MethodMatcher.java | 46 +++++++++---------- .../conversion/generics/ConversionTest.java | 14 ++++-- .../mapstruct/ap/testutil/WithClasses.java | 11 +++-- 3 files changed, 41 insertions(+), 30 deletions(-) diff --git a/processor/src/main/java/org/mapstruct/ap/util/MethodMatcher.java b/processor/src/main/java/org/mapstruct/ap/util/MethodMatcher.java index b4652e856..1f8fcf291 100644 --- a/processor/src/main/java/org/mapstruct/ap/util/MethodMatcher.java +++ b/processor/src/main/java/org/mapstruct/ap/util/MethodMatcher.java @@ -21,18 +21,19 @@ package org.mapstruct.ap.util; import java.util.HashMap; import java.util.List; import java.util.Map; + import javax.lang.model.element.TypeParameterElement; import javax.lang.model.element.VariableElement; import javax.lang.model.type.ArrayType; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.PrimitiveType; import javax.lang.model.type.TypeKind; -import static javax.lang.model.type.TypeKind.DECLARED; import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeVariable; import javax.lang.model.type.WildcardType; import javax.lang.model.util.SimpleTypeVisitor6; import javax.lang.model.util.Types; + import org.mapstruct.ap.model.Type; import org.mapstruct.ap.model.source.Method; @@ -68,36 +69,33 @@ import org.mapstruct.ap.model.source.Method; */ public class MethodMatcher { - private final Type[] parameters; + private final Type parameter; private final Type returnType; private final Method candidateMethod; private final Types typeUtils; private boolean typesMatch = true; - private Map genericTypesMap = new HashMap(); + private final Map genericTypesMap = new HashMap(); - public MethodMatcher(Types typeUtils, Method candidateMethod, Type returnType, Type... arguments) { + public MethodMatcher(Types typeUtils, Method candidateMethod, Type returnType, Type parameter) { this.typeUtils = typeUtils; this.candidateMethod = candidateMethod; - this.parameters = arguments; + this.parameter = parameter; this.returnType = returnType; } public boolean matches() { - // check & collect generic types. List candidateParameters = candidateMethod.getExecutable().getParameters(); - if ( candidateParameters.size() == parameters.length ) { - for ( int i = 0; i < parameters.length; i++ ) { - TypeMatcher parameterMatcher = new TypeMatcher(); - typesMatch = parameterMatcher.visit( candidateParameters.get( i ).asType(), - parameters[i].getTypeMirror() ); - if ( !typesMatch ) { - break; - } - } + + if ( candidateParameters.size() != 1 ) { + typesMatch = false; } else { - typesMatch = false; + TypeMatcher parameterMatcher = new TypeMatcher(); + typesMatch = parameterMatcher.visit( + candidateParameters.iterator().next().asType(), + parameter.getTypeMirror() + ); } // check return type @@ -114,7 +112,7 @@ public class MethodMatcher { else { // check if all entries are in the bounds for (Map.Entry entry : genericTypesMap.entrySet()) { - if (!isWithinBounds( entry.getValue(), getTypeParamFromCandite( entry.getKey() ) ) ) { + if (!isWithinBounds( entry.getValue(), getTypeParamFromCandidate( entry.getKey() ) ) ) { // checks if the found Type is in bounds of the TypeParameters bounds. typesMatch = false; } @@ -202,10 +200,10 @@ public class MethodMatcher { return typeUtils.isSubtype( p, extendsBound ); case TYPEVAR: - // for exampe method: T method(? extends T) + // for example method: T method(? extends T) // this can be done the directly by checking: ? extends String & Serializable // this checks the part? - return isWithinBounds( p, getTypeParamFromCandite( extendsBound ) ); + return isWithinBounds( p, getTypeParamFromCandidate( extendsBound ) ); default: // does this situation occur? @@ -225,13 +223,13 @@ public class MethodMatcher { case TYPEVAR: - TypeParameterElement typeParameter = getTypeParamFromCandite( superBound ); - // for exampe method: T method(? super T) + TypeParameterElement typeParameter = getTypeParamFromCandidate( superBound ); + // for example method: T method(? super T) if ( !isWithinBounds( p, typeParameter ) ) { // this checks the part? return Boolean.FALSE; } - // now, it becoms a bit more hairy. We have the relation (? super T). From T we know that + // now, it becomes a bit more hairy. We have the relation (? super T). From T we know that // it is a subclass of String & Serializable. However, The Java Language Secification, // Chapter 4.4, states that a bound is either: 'A type variable-', 'A class-' or 'An // interface-' type followed by further interface types. So we must compare with the first @@ -258,7 +256,7 @@ public class MethodMatcher { * @param t type parameter to match * @return matching type parameter */ - private TypeParameterElement getTypeParamFromCandite(TypeMirror t) { + private TypeParameterElement getTypeParamFromCandidate(TypeMirror t) { for ( TypeParameterElement candidateTypeParam : candidateMethod.getExecutable().getTypeParameters() ) { if ( candidateTypeParam.asType().equals( t ) ) { return candidateTypeParam; @@ -279,7 +277,7 @@ public class MethodMatcher { if ( t != null && bounds != null ) { for ( TypeMirror bound : bounds ) { if ( !( bound.getKind().equals( TypeKind.DECLARED ) && - typeUtils.isSubtype( t, (DeclaredType) bound ) ) ) { + typeUtils.isSubtype( t, bound ) ) ) { return false; } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/generics/ConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/generics/ConversionTest.java index 28b98a957..7a0404788 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/generics/ConversionTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/generics/ConversionTest.java @@ -18,19 +18,27 @@ */ package org.mapstruct.ap.test.conversion.generics; +import static org.fest.assertions.Assertions.assertThat; + import java.math.BigDecimal; + +import org.mapstruct.ap.testutil.IssueKey; import org.mapstruct.ap.testutil.MapperTestBase; import org.mapstruct.ap.testutil.WithClasses; -import org.testng.annotations.Test; - -import static org.fest.assertions.Assertions.assertThat; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; +import org.testng.annotations.Test; +/** + * Tests for the invocation of generic methods for mapping bean properties. + * + * @author Sjaak Derksen + */ @WithClasses( { GenericTypeMapper.class, Wrapper.class, ArrayWrapper.class, TwoArgHolder.class, TwoArgWrapper.class, UpperBoundWrapper.class, WildCardExtendsWrapper.class, WildCardSuperWrapper.class, WildCardExtendsMBWrapper.class, TypeA.class, TypeB.class, TypeC.class } ) +@IssueKey( value = "79" ) public class ConversionTest extends MapperTestBase { @Test diff --git a/processor/src/test/java/org/mapstruct/ap/testutil/WithClasses.java b/processor/src/test/java/org/mapstruct/ap/testutil/WithClasses.java index 8520fa278..cc517b557 100644 --- a/processor/src/test/java/org/mapstruct/ap/testutil/WithClasses.java +++ b/processor/src/test/java/org/mapstruct/ap/testutil/WithClasses.java @@ -24,14 +24,19 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * Specifies the classes to compile during an annotation processor test. If - * given both on the class-level and the method-level for a given test, the - * settings on the method take precedence. + * Specifies the classes to compile during an annotation processor test. If given both on the class-level and the + * method-level for a given test, all the given classes will be compiled. * * @author Gunnar Morling */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.METHOD }) public @interface WithClasses { + + /** + * The classes to be compiled for the annotated test class or method. + * + * @return the classes to be compiled for the annotated test class or method + */ Class[] value(); }