mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#160 allow selection of update methods by refactoring MethodMatcher but stopping selection of update method at new filter
This commit is contained in:
parent
0c226f8388
commit
37e5942c86
@ -50,7 +50,7 @@ public abstract class MappingMethod extends ModelElement {
|
||||
this.name = method.getName();
|
||||
this.parameters = method.getParameters();
|
||||
this.returnType = method.getReturnType();
|
||||
this.targetParameter = method.getTargetParameter();
|
||||
this.targetParameter = method.getMappingTargetParameter();
|
||||
this.accessibility = method.getAccessibility();
|
||||
this.thrownTypes = method.getThrownTypes();
|
||||
this.isStatic = method.isStatic();
|
||||
|
@ -71,19 +71,18 @@ public class ForgedMethod implements Method {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(List<Type> sourceTypes, Type targetType) {
|
||||
public boolean matches(Type sourceTypes, Type targetType) {
|
||||
|
||||
if ( !targetType.equals( returnType ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( sourceTypes.size() == parameters.size() ) {
|
||||
if ( parameters.size() != 1 ) {
|
||||
return false;
|
||||
}
|
||||
for ( int i = 0; i < sourceTypes.size(); i++ ) {
|
||||
if ( !sourceTypes.get( i ).equals( parameters.get( i ).getType() ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !sourceTypes.equals( parameters.get( 0 ).getType() ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -110,7 +109,12 @@ public class ForgedMethod implements Method {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parameter getTargetParameter() {
|
||||
public Parameter getMappingTargetParameter() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parameter getTargetTypeParameter() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -40,12 +40,12 @@ public interface Method {
|
||||
* Checks whether the provided sourceType and provided targetType match with the parameter respectively return type
|
||||
* of the method. The check also should incorporate wild card and generic type variables
|
||||
*
|
||||
* @param sourceTypes the sourceTypes to match to the parameter
|
||||
* @param sourceType the sourceType to match to the parameter
|
||||
* @param targetType the targetType to match to the returnType
|
||||
*
|
||||
* @return true when match
|
||||
*/
|
||||
boolean matches(List<Type> sourceTypes, Type targetType);
|
||||
boolean matches(Type sourceType, Type targetType );
|
||||
|
||||
/**
|
||||
* Returns the mapper type declaring this method if it is not declared by the mapper interface currently processed
|
||||
@ -71,18 +71,26 @@ public interface Method {
|
||||
|
||||
/**
|
||||
* returns the list of 'true' source parameters excluding the parameter(s) that is designated as
|
||||
* target by means of the target annotation {@link #getTargetParameter() }.
|
||||
* target by means of the target annotation {@link #getMappingTargetParameter() }.
|
||||
*
|
||||
* @return list of 'true' source parameters
|
||||
*/
|
||||
List<Parameter> getSourceParameters();
|
||||
|
||||
/**
|
||||
* Returns the parameter designated as target parameter (if present) {@link #getSourceParameters() }
|
||||
* Returns the parameter designated as mapping target (if present) {@link org.mapstruct.MappingTarget }
|
||||
*
|
||||
* @return target parameter (when present) null otherwise.
|
||||
* @return mapping target parameter (when present) null otherwise.
|
||||
*/
|
||||
Parameter getTargetParameter();
|
||||
Parameter getMappingTargetParameter();
|
||||
|
||||
/**
|
||||
* Returns the parameter designated as target type (if present) {@link org.mapstruct.TargetType }
|
||||
*
|
||||
* @return target type parameter (when present) null otherwise.
|
||||
*/
|
||||
Parameter getTargetTypeParameter();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the {@link Accessibility} of this method.
|
||||
|
@ -24,7 +24,6 @@ import java.util.Map;
|
||||
|
||||
import javax.lang.model.element.TypeElement;
|
||||
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;
|
||||
@ -34,8 +33,10 @@ 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.common.Parameter;
|
||||
|
||||
import org.mapstruct.ap.model.common.Type;
|
||||
import org.mapstruct.ap.model.common.TypeFactory;
|
||||
|
||||
import static org.mapstruct.ap.util.SpecificCompilerWorkarounds.isSubType;
|
||||
|
||||
@ -68,80 +69,65 @@ public class MethodMatcher {
|
||||
|
||||
private final SourceMethod candidateMethod;
|
||||
private final Types typeUtils;
|
||||
private final TypeFactory typeFactory;
|
||||
|
||||
MethodMatcher(Types typeUtils, SourceMethod candidateMethod) {
|
||||
MethodMatcher(Types typeUtils, TypeFactory typeFactory, SourceMethod candidateMethod) {
|
||||
this.typeUtils = typeUtils;
|
||||
this.candidateMethod = candidateMethod;
|
||||
this.typeFactory = typeFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the given source and target types are matched by this matcher's candidate method.
|
||||
*
|
||||
* @param sourceTypes the source types
|
||||
* @param targetType the target type
|
||||
* @param sourceType the source types
|
||||
* @param resultType the target type
|
||||
*
|
||||
* @return {@code true} when both, source type and target types match the signature of this matcher's method;
|
||||
* {@code false} otherwise.
|
||||
*/
|
||||
boolean matches(List<Type> sourceTypes, Type targetType) {
|
||||
// check & collect generic types.
|
||||
List<? extends VariableElement> candidateParameters = candidateMethod.getExecutable().getParameters();
|
||||
boolean matches(Type sourceType, Type resultType) {
|
||||
|
||||
if ( candidateParameters.size() != sourceTypes.size() ) {
|
||||
// check & collect generic types.
|
||||
Map<TypeVariable, TypeMirror> genericTypesMap = new HashMap<TypeVariable, TypeMirror>();
|
||||
|
||||
// only factory / mapping methods with zero or one source parameters qualify
|
||||
if ( candidateMethod.getSourceParameters().size() > 1 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Map<TypeVariable, TypeMirror> genericTypesMap = new HashMap<TypeVariable, TypeMirror>();
|
||||
|
||||
int i = 0;
|
||||
for ( VariableElement candidateParameter : candidateParameters ) {
|
||||
TypeMatcher parameterMatcher = new TypeMatcher( Assignability.VISITED_ASSIGNABLE_FROM, genericTypesMap );
|
||||
Type sourceType = sourceTypes.get( i++ );
|
||||
if ( !parameterMatcher.visit( candidateParameter.asType(), sourceType.getTypeMirror() ) ) {
|
||||
if (sourceType.isPrimitive() ) {
|
||||
// the candidate source is primitive, so promote to its boxed type and check again (autobox)
|
||||
TypeMirror boxedType = typeUtils.boxedClass( (PrimitiveType) sourceType.getTypeMirror() ).asType();
|
||||
if ( !parameterMatcher.visit( candidateParameter.asType(), boxedType ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// NOTE: unboxing is deliberately not considered here. This should be handled via type-conversion
|
||||
// (for NPE safety).
|
||||
if ( sourceType != null ) {
|
||||
// if the sourcetype is not null then only methods with one source parameter qualfiy
|
||||
if ( candidateMethod.getSourceParameters().size() == 1 ) {
|
||||
Parameter sourceParam = candidateMethod.getSourceParameters().iterator().next();
|
||||
if ( !matchSourceType( sourceType, sourceParam.getType(), genericTypesMap ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check return type
|
||||
TypeMirror candidateReturnType = candidateMethod.getExecutable().getReturnType();
|
||||
TypeMatcher returnTypeMatcher = new TypeMatcher( Assignability.VISITED_ASSIGNABLE_TO, genericTypesMap );
|
||||
|
||||
if ( !returnTypeMatcher.visit( candidateReturnType, targetType.getTypeMirror() ) ) {
|
||||
if ( targetType.isPrimitive() ) {
|
||||
TypeMirror boxedType = typeUtils.boxedClass( (PrimitiveType) targetType.getTypeMirror() ).asType();
|
||||
TypeMatcher boxedReturnTypeMatcher =
|
||||
new TypeMatcher( Assignability.VISITED_ASSIGNABLE_TO, genericTypesMap );
|
||||
|
||||
if ( !boxedReturnTypeMatcher.visit( candidateReturnType, boxedType ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ( candidateReturnType.getKind().isPrimitive() ) {
|
||||
TypeMirror boxedCandidateReturnType =
|
||||
typeUtils.boxedClass( (PrimitiveType) candidateReturnType ).asType();
|
||||
TypeMatcher boxedReturnTypeMatcher =
|
||||
new TypeMatcher( Assignability.VISITED_ASSIGNABLE_TO, genericTypesMap );
|
||||
|
||||
if ( !boxedReturnTypeMatcher.visit( boxedCandidateReturnType, targetType.getTypeMirror() ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// if the sourcetype is null then only methods with zero source parameters qualfiy
|
||||
if ( !candidateMethod.getSourceParameters().isEmpty() ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// check if the method matches the proper result type to construct
|
||||
Parameter targetTypeParameter = candidateMethod.getTargetTypeParameter();
|
||||
if ( targetTypeParameter != null ) {
|
||||
Type returnClassType = typeFactory.classTypeOf( resultType );
|
||||
if ( !matchSourceType( returnClassType, targetTypeParameter.getType(), genericTypesMap ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// check result type
|
||||
if ( !matchResultType( resultType, candidateMethod.getResultType(), genericTypesMap ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if all type parameters are indeed mapped
|
||||
if ( candidateMethod.getExecutable().getTypeParameters().size() != genericTypesMap.size() ) {
|
||||
@ -158,6 +144,63 @@ public class MethodMatcher {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean matchSourceType(Type sourceType,
|
||||
Type candidateSourceType,
|
||||
Map<TypeVariable, TypeMirror> genericTypesMap) {
|
||||
|
||||
TypeMatcher parameterMatcher = new TypeMatcher( Assignability.VISITED_ASSIGNABLE_FROM, genericTypesMap );
|
||||
if ( !parameterMatcher.visit( candidateSourceType.getTypeMirror(), sourceType.getTypeMirror() ) ) {
|
||||
if ( sourceType.isPrimitive() ) {
|
||||
// the candidate source is primitive, so promote to its boxed type and check again (autobox)
|
||||
TypeMirror boxedType = typeUtils.boxedClass( (PrimitiveType) sourceType.getTypeMirror() ).asType();
|
||||
if ( !parameterMatcher.visit( candidateSourceType.getTypeMirror(), boxedType ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// NOTE: unboxing is deliberately not considered here. This should be handled via type-conversion
|
||||
// (for NPE safety).
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean matchResultType(Type resultType,
|
||||
Type candidateResultType,
|
||||
Map<TypeVariable, TypeMirror> genericTypesMap) {
|
||||
|
||||
TypeMatcher returnTypeMatcher = new TypeMatcher( Assignability.VISITED_ASSIGNABLE_TO, genericTypesMap );
|
||||
|
||||
if ( !returnTypeMatcher.visit( candidateResultType.getTypeMirror(), resultType.getTypeMirror() ) ) {
|
||||
if ( resultType.isPrimitive() ) {
|
||||
TypeMirror boxedType = typeUtils.boxedClass( (PrimitiveType) resultType.getTypeMirror() ).asType();
|
||||
TypeMatcher boxedReturnTypeMatcher =
|
||||
new TypeMatcher( Assignability.VISITED_ASSIGNABLE_TO, genericTypesMap );
|
||||
|
||||
if ( !boxedReturnTypeMatcher.visit( candidateResultType.getTypeMirror(), boxedType ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ( candidateResultType.getTypeMirror().getKind().isPrimitive() ) {
|
||||
TypeMirror boxedCandidateReturnType =
|
||||
typeUtils.boxedClass( (PrimitiveType) candidateResultType.getTypeMirror() ).asType();
|
||||
TypeMatcher boxedReturnTypeMatcher =
|
||||
new TypeMatcher( Assignability.VISITED_ASSIGNABLE_TO, genericTypesMap );
|
||||
|
||||
if ( !boxedReturnTypeMatcher.visit( boxedCandidateReturnType, resultType.getTypeMirror() ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private enum Assignability {
|
||||
VISITED_ASSIGNABLE_FROM, VISITED_ASSIGNABLE_TO
|
||||
}
|
||||
|
@ -55,7 +55,8 @@ public class SourceMethod implements Method {
|
||||
private final Type declaringMapper;
|
||||
private final ExecutableElement executable;
|
||||
private final List<Parameter> parameters;
|
||||
private final Parameter targetParameter;
|
||||
private final Parameter mappingTargetParameter;
|
||||
private final Parameter targetTypeParameter;
|
||||
private final Type returnType;
|
||||
private final Accessibility accessibility;
|
||||
private final List<Type> exceptionTypes;
|
||||
@ -185,7 +186,8 @@ public class SourceMethod implements Method {
|
||||
this.mapMapping = mapMapping;
|
||||
this.accessibility = Accessibility.fromModifiers( executable.getModifiers() );
|
||||
|
||||
this.targetParameter = determineTargetParameter( parameters );
|
||||
this.mappingTargetParameter = determineMappingTargetParameter( parameters );
|
||||
this.targetTypeParameter = determineTargetTypeParameter( parameters );
|
||||
|
||||
this.typeUtils = typeUtils;
|
||||
this.typeFactory = typeFactory;
|
||||
@ -193,7 +195,7 @@ public class SourceMethod implements Method {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
private Parameter determineTargetParameter(Iterable<Parameter> parameters) {
|
||||
private Parameter determineMappingTargetParameter(Iterable<Parameter> parameters) {
|
||||
for ( Parameter parameter : parameters ) {
|
||||
if ( parameter.isMappingTarget() ) {
|
||||
return parameter;
|
||||
@ -203,6 +205,16 @@ public class SourceMethod implements Method {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Parameter determineTargetTypeParameter(Iterable<Parameter> parameters) {
|
||||
for ( Parameter parameter : parameters ) {
|
||||
if ( parameter.isTargetType() ) {
|
||||
return parameter;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc} {@link Method}
|
||||
*/
|
||||
@ -261,7 +273,7 @@ public class SourceMethod implements Method {
|
||||
|
||||
@Override
|
||||
public Type getResultType() {
|
||||
return targetParameter != null ? targetParameter.getType() : returnType;
|
||||
return mappingTargetParameter != null ? mappingTargetParameter.getType() : returnType;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -357,12 +369,14 @@ public class SourceMethod implements Method {
|
||||
return equals( getResultType(), method.getResultType() );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc} {@link Method}
|
||||
*/
|
||||
@Override
|
||||
public Parameter getTargetParameter() {
|
||||
return targetParameter;
|
||||
public Parameter getMappingTargetParameter() {
|
||||
return mappingTargetParameter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parameter getTargetTypeParameter() {
|
||||
return targetTypeParameter;
|
||||
}
|
||||
|
||||
public boolean isIterableMapping() {
|
||||
@ -455,9 +469,9 @@ public class SourceMethod implements Method {
|
||||
* {@inheritDoc} {@link Method}
|
||||
*/
|
||||
@Override
|
||||
public boolean matches(List<Type> sourceTypes, Type targetType) {
|
||||
MethodMatcher matcher = new MethodMatcher( typeUtils, this );
|
||||
return matcher.matches( sourceTypes, targetType );
|
||||
public boolean matches(Type sourceType, Type targetType) {
|
||||
MethodMatcher matcher = new MethodMatcher( typeUtils, typeFactory, this );
|
||||
return matcher.matches( sourceType, targetType );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,11 +71,7 @@ public abstract class BuiltInMethod implements Method {
|
||||
* excluding generic type variables. When the implementor sees a need for this, this method can be overridden.
|
||||
*/
|
||||
@Override
|
||||
public boolean matches(List<Type> sourceTypes, Type targetType) {
|
||||
if ( sourceTypes.size() > 1 ) {
|
||||
return false;
|
||||
}
|
||||
Type sourceType = sourceTypes.iterator().next();
|
||||
public boolean matches(Type sourceType, Type targetType) {
|
||||
|
||||
if ( getReturnType().isAssignableTo( targetType.erasure() )
|
||||
&& sourceType.erasure().isAssignableTo( getParameter().getType() ) ) {
|
||||
@ -118,12 +114,22 @@ public abstract class BuiltInMethod implements Method {
|
||||
}
|
||||
|
||||
/**
|
||||
* target parameter mechanism not supported for built-in methods
|
||||
* mapping target parameter mechanism not supported for built-in methods
|
||||
*
|
||||
* @return {@code null}
|
||||
*/
|
||||
@Override
|
||||
public Parameter getTargetParameter() {
|
||||
public Parameter getMappingTargetParameter() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* target type parameter mechanism not supported for built-in methods
|
||||
*
|
||||
* @return {@code null}
|
||||
*/
|
||||
@Override
|
||||
public Parameter getTargetTypeParameter() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.mapstruct.ap.model.source.selector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.mapstruct.ap.model.common.Type;
|
||||
import org.mapstruct.ap.model.source.Method;
|
||||
import org.mapstruct.ap.model.source.MethodMatcher;
|
||||
|
||||
/**
|
||||
* Selects only create method candidates (so methods not containing {@link @MappingTarget} )
|
||||
* {@link MethodMatcher}).
|
||||
*
|
||||
* @author Sjaak Derksen
|
||||
*/
|
||||
public class CreateOrUpdateSelector implements MethodSelector {
|
||||
|
||||
@Override
|
||||
public <T extends Method> List<T> getMatchingMethods(Method mappingMethod, List<T> methods,
|
||||
Type sourceType, Type targetType,
|
||||
SelectionCriteria criteria) {
|
||||
|
||||
List<T> createCandidates = new ArrayList<T>();
|
||||
for ( T method : methods ) {
|
||||
boolean isCreateCandidate = method.getMappingTargetParameter() == null;
|
||||
if ( isCreateCandidate ) {
|
||||
createCandidates.add( method );
|
||||
}
|
||||
}
|
||||
return createCandidates;
|
||||
|
||||
}
|
||||
}
|
@ -24,7 +24,6 @@ import java.util.List;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.lang.model.util.Types;
|
||||
|
||||
import org.mapstruct.ap.model.common.Parameter;
|
||||
import org.mapstruct.ap.model.common.Type;
|
||||
import org.mapstruct.ap.model.common.TypeFactory;
|
||||
import org.mapstruct.ap.model.source.Method;
|
||||
@ -41,11 +40,12 @@ public class MethodSelectors implements MethodSelector {
|
||||
public MethodSelectors(Types typeUtils, Elements elementUtils, TypeFactory typeFactory) {
|
||||
selectors =
|
||||
Arrays.<MethodSelector>asList(
|
||||
new TypeSelector( typeFactory ),
|
||||
new TypeSelector(),
|
||||
new QualifierSelector( typeUtils, elementUtils ),
|
||||
new TargetTypeSelector( typeUtils, elementUtils ),
|
||||
new XmlElementDeclSelector( typeUtils ),
|
||||
new InheritanceSelector()
|
||||
new InheritanceSelector(),
|
||||
new CreateOrUpdateSelector()
|
||||
);
|
||||
}
|
||||
|
||||
@ -67,30 +67,4 @@ public class MethodSelectors implements MethodSelector {
|
||||
}
|
||||
return candidates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param typeFactory the type factory to use
|
||||
* @param parameters the parameters to map the types for
|
||||
* @param sourceType the source type
|
||||
* @param returnType the return type
|
||||
*
|
||||
* @return the list of actual parameter types
|
||||
*/
|
||||
public static List<Type> getParameterTypes(TypeFactory typeFactory, List<Parameter> parameters, Type sourceType,
|
||||
Type returnType) {
|
||||
List<Type> result = new ArrayList<Type>();
|
||||
for ( Parameter param : parameters ) {
|
||||
if ( param.isTargetType() ) {
|
||||
result.add( typeFactory.classTypeOf( returnType ) );
|
||||
}
|
||||
else {
|
||||
if ( sourceType != null ) {
|
||||
/* for factory methods (sourceType==null), no parameter must be added */
|
||||
result.add( sourceType );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.mapstruct.ap.model.common.Type;
|
||||
import org.mapstruct.ap.model.common.TypeFactory;
|
||||
import org.mapstruct.ap.model.source.Method;
|
||||
import org.mapstruct.ap.model.source.MethodMatcher;
|
||||
|
||||
@ -34,12 +33,6 @@ import org.mapstruct.ap.model.source.MethodMatcher;
|
||||
*/
|
||||
public class TypeSelector implements MethodSelector {
|
||||
|
||||
private final TypeFactory typeFactory;
|
||||
|
||||
public TypeSelector(TypeFactory typeFactory) {
|
||||
this.typeFactory = typeFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Method> List<T> getMatchingMethods(Method mappingMethod, List<T> methods,
|
||||
Type sourceType, Type targetType,
|
||||
@ -47,13 +40,7 @@ public class TypeSelector implements MethodSelector {
|
||||
|
||||
List<T> result = new ArrayList<T>();
|
||||
for ( T method : methods ) {
|
||||
if ( method.getSourceParameters().size() > 1 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<Type> parameterTypes =
|
||||
MethodSelectors.getParameterTypes( typeFactory, method.getParameters(), sourceType, targetType );
|
||||
if ( method.matches( parameterTypes, targetType ) ) {
|
||||
if ( method.matches( sourceType, targetType ) ) {
|
||||
result.add( method );
|
||||
}
|
||||
}
|
||||
|
@ -204,6 +204,7 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
||||
.setReturnType( returnType )
|
||||
.setExceptionTypes( exceptionTypes )
|
||||
.setTypeUtils( typeUtils )
|
||||
.setTypeFactory( typeFactory )
|
||||
.createSourceMethod();
|
||||
}
|
||||
|
||||
|
@ -444,9 +444,19 @@ public class MappingResolverImpl implements MappingResolver {
|
||||
}
|
||||
|
||||
private boolean isCandidateForMapping(Method methodCandidate) {
|
||||
return isCreateMethodForMapping( methodCandidate ) || isUpdateMethodForMapping( methodCandidate );
|
||||
}
|
||||
|
||||
private boolean isCreateMethodForMapping(Method methodCandidate) {
|
||||
// a create method may not return void and has no target parameter
|
||||
return methodCandidate.getSourceParameters().size() == 1 && !methodCandidate.getReturnType().isVoid()
|
||||
&& methodCandidate.getTargetParameter() == null; // @MappingTarget is not yet supported for property
|
||||
// mappings
|
||||
&& methodCandidate.getMappingTargetParameter() == null;
|
||||
}
|
||||
|
||||
private boolean isUpdateMethodForMapping(Method methodCandidate) {
|
||||
// an update method may, or may not return void and has a target parameter
|
||||
return methodCandidate.getSourceParameters().size() == 1
|
||||
&& methodCandidate.getMappingTargetParameter() != null;
|
||||
}
|
||||
|
||||
private <T extends Method> T getBestMatch(List<T> methods, Type sourceType, Type returnType) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user