mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#79 Some typo fixes, simplifications and comment improvements
This commit is contained in:
parent
3bdc67f9ba
commit
623acb6f10
@ -21,18 +21,19 @@ package org.mapstruct.ap.util;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.lang.model.element.TypeParameterElement;
|
import javax.lang.model.element.TypeParameterElement;
|
||||||
import javax.lang.model.element.VariableElement;
|
import javax.lang.model.element.VariableElement;
|
||||||
import javax.lang.model.type.ArrayType;
|
import javax.lang.model.type.ArrayType;
|
||||||
import javax.lang.model.type.DeclaredType;
|
import javax.lang.model.type.DeclaredType;
|
||||||
import javax.lang.model.type.PrimitiveType;
|
import javax.lang.model.type.PrimitiveType;
|
||||||
import javax.lang.model.type.TypeKind;
|
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.TypeMirror;
|
||||||
import javax.lang.model.type.TypeVariable;
|
import javax.lang.model.type.TypeVariable;
|
||||||
import javax.lang.model.type.WildcardType;
|
import javax.lang.model.type.WildcardType;
|
||||||
import javax.lang.model.util.SimpleTypeVisitor6;
|
import javax.lang.model.util.SimpleTypeVisitor6;
|
||||||
import javax.lang.model.util.Types;
|
import javax.lang.model.util.Types;
|
||||||
|
|
||||||
import org.mapstruct.ap.model.Type;
|
import org.mapstruct.ap.model.Type;
|
||||||
import org.mapstruct.ap.model.source.Method;
|
import org.mapstruct.ap.model.source.Method;
|
||||||
|
|
||||||
@ -68,36 +69,33 @@ import org.mapstruct.ap.model.source.Method;
|
|||||||
*/
|
*/
|
||||||
public class MethodMatcher {
|
public class MethodMatcher {
|
||||||
|
|
||||||
private final Type[] parameters;
|
private final Type parameter;
|
||||||
private final Type returnType;
|
private final Type returnType;
|
||||||
private final Method candidateMethod;
|
private final Method candidateMethod;
|
||||||
private final Types typeUtils;
|
private final Types typeUtils;
|
||||||
private boolean typesMatch = true;
|
private boolean typesMatch = true;
|
||||||
private Map<TypeVariable, TypeMirror> genericTypesMap = new HashMap<TypeVariable, TypeMirror>();
|
private final Map<TypeVariable, TypeMirror> genericTypesMap = new HashMap<TypeVariable, TypeMirror>();
|
||||||
|
|
||||||
public MethodMatcher(Types typeUtils, Method candidateMethod, Type returnType, Type... arguments) {
|
public MethodMatcher(Types typeUtils, Method candidateMethod, Type returnType, Type parameter) {
|
||||||
this.typeUtils = typeUtils;
|
this.typeUtils = typeUtils;
|
||||||
this.candidateMethod = candidateMethod;
|
this.candidateMethod = candidateMethod;
|
||||||
this.parameters = arguments;
|
this.parameter = parameter;
|
||||||
this.returnType = returnType;
|
this.returnType = returnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean matches() {
|
public boolean matches() {
|
||||||
|
|
||||||
// check & collect generic types.
|
// check & collect generic types.
|
||||||
List<? extends VariableElement> candidateParameters = candidateMethod.getExecutable().getParameters();
|
List<? extends VariableElement> candidateParameters = candidateMethod.getExecutable().getParameters();
|
||||||
if ( candidateParameters.size() == parameters.length ) {
|
|
||||||
for ( int i = 0; i < parameters.length; i++ ) {
|
if ( candidateParameters.size() != 1 ) {
|
||||||
TypeMatcher parameterMatcher = new TypeMatcher();
|
typesMatch = false;
|
||||||
typesMatch = parameterMatcher.visit( candidateParameters.get( i ).asType(),
|
|
||||||
parameters[i].getTypeMirror() );
|
|
||||||
if ( !typesMatch ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
typesMatch = false;
|
TypeMatcher parameterMatcher = new TypeMatcher();
|
||||||
|
typesMatch = parameterMatcher.visit(
|
||||||
|
candidateParameters.iterator().next().asType(),
|
||||||
|
parameter.getTypeMirror()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check return type
|
// check return type
|
||||||
@ -114,7 +112,7 @@ public class MethodMatcher {
|
|||||||
else {
|
else {
|
||||||
// check if all entries are in the bounds
|
// check if all entries are in the bounds
|
||||||
for (Map.Entry<TypeVariable, TypeMirror> entry : genericTypesMap.entrySet()) {
|
for (Map.Entry<TypeVariable, TypeMirror> 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.
|
// checks if the found Type is in bounds of the TypeParameters bounds.
|
||||||
typesMatch = false;
|
typesMatch = false;
|
||||||
}
|
}
|
||||||
@ -202,10 +200,10 @@ public class MethodMatcher {
|
|||||||
return typeUtils.isSubtype( p, extendsBound );
|
return typeUtils.isSubtype( p, extendsBound );
|
||||||
|
|
||||||
case TYPEVAR:
|
case TYPEVAR:
|
||||||
// for exampe method: <T extends String & Serializable> T method(? extends T)
|
// for example method: <T extends String & Serializable> T method(? extends T)
|
||||||
// this can be done the directly by checking: ? extends String & Serializable
|
// this can be done the directly by checking: ? extends String & Serializable
|
||||||
// this checks the part? <T extends String & Serializable>
|
// this checks the part? <T extends String & Serializable>
|
||||||
return isWithinBounds( p, getTypeParamFromCandite( extendsBound ) );
|
return isWithinBounds( p, getTypeParamFromCandidate( extendsBound ) );
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// does this situation occur?
|
// does this situation occur?
|
||||||
@ -225,13 +223,13 @@ public class MethodMatcher {
|
|||||||
|
|
||||||
case TYPEVAR:
|
case TYPEVAR:
|
||||||
|
|
||||||
TypeParameterElement typeParameter = getTypeParamFromCandite( superBound );
|
TypeParameterElement typeParameter = getTypeParamFromCandidate( superBound );
|
||||||
// for exampe method: <T extends String & Serializable> T method(? super T)
|
// for example method: <T extends String & Serializable> T method(? super T)
|
||||||
if ( !isWithinBounds( p, typeParameter ) ) {
|
if ( !isWithinBounds( p, typeParameter ) ) {
|
||||||
// this checks the part? <T extends String & Serializable>
|
// this checks the part? <T extends String & Serializable>
|
||||||
return Boolean.FALSE;
|
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,
|
// 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
|
// 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
|
// 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
|
* @param t type parameter to match
|
||||||
* @return matching type parameter
|
* @return matching type parameter
|
||||||
*/
|
*/
|
||||||
private TypeParameterElement getTypeParamFromCandite(TypeMirror t) {
|
private TypeParameterElement getTypeParamFromCandidate(TypeMirror t) {
|
||||||
for ( TypeParameterElement candidateTypeParam : candidateMethod.getExecutable().getTypeParameters() ) {
|
for ( TypeParameterElement candidateTypeParam : candidateMethod.getExecutable().getTypeParameters() ) {
|
||||||
if ( candidateTypeParam.asType().equals( t ) ) {
|
if ( candidateTypeParam.asType().equals( t ) ) {
|
||||||
return candidateTypeParam;
|
return candidateTypeParam;
|
||||||
@ -279,7 +277,7 @@ public class MethodMatcher {
|
|||||||
if ( t != null && bounds != null ) {
|
if ( t != null && bounds != null ) {
|
||||||
for ( TypeMirror bound : bounds ) {
|
for ( TypeMirror bound : bounds ) {
|
||||||
if ( !( bound.getKind().equals( TypeKind.DECLARED ) &&
|
if ( !( bound.getKind().equals( TypeKind.DECLARED ) &&
|
||||||
typeUtils.isSubtype( t, (DeclaredType) bound ) ) ) {
|
typeUtils.isSubtype( t, bound ) ) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,19 +18,27 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.test.conversion.generics;
|
package org.mapstruct.ap.test.conversion.generics;
|
||||||
|
|
||||||
|
import static org.fest.assertions.Assertions.assertThat;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import org.mapstruct.ap.testutil.IssueKey;
|
||||||
import org.mapstruct.ap.testutil.MapperTestBase;
|
import org.mapstruct.ap.testutil.MapperTestBase;
|
||||||
import org.mapstruct.ap.testutil.WithClasses;
|
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.CompilationResult;
|
||||||
import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic;
|
import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic;
|
||||||
import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome;
|
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,
|
@WithClasses( { GenericTypeMapper.class, Wrapper.class, ArrayWrapper.class, TwoArgHolder.class, TwoArgWrapper.class,
|
||||||
UpperBoundWrapper.class, WildCardExtendsWrapper.class, WildCardSuperWrapper.class, WildCardExtendsMBWrapper.class,
|
UpperBoundWrapper.class, WildCardExtendsWrapper.class, WildCardSuperWrapper.class, WildCardExtendsMBWrapper.class,
|
||||||
TypeA.class, TypeB.class, TypeC.class } )
|
TypeA.class, TypeB.class, TypeC.class } )
|
||||||
|
@IssueKey( value = "79" )
|
||||||
public class ConversionTest extends MapperTestBase {
|
public class ConversionTest extends MapperTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -24,14 +24,19 @@ import java.lang.annotation.RetentionPolicy;
|
|||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies the classes to compile during an annotation processor test. If
|
* Specifies the classes to compile during an annotation processor test. If given both on the class-level and the
|
||||||
* given both on the class-level and the method-level for a given test, the
|
* method-level for a given test, all the given classes will be compiled.
|
||||||
* settings on the method take precedence.
|
|
||||||
*
|
*
|
||||||
* @author Gunnar Morling
|
* @author Gunnar Morling
|
||||||
*/
|
*/
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||||
public @interface WithClasses {
|
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();
|
Class<?>[] value();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user