mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
This commit is contained in:
parent
cb432fa61b
commit
36349c49e9
@ -27,6 +27,8 @@ public abstract class AbstractMappingMethodBuilder<B extends AbstractMappingMeth
|
||||
|
||||
public abstract M build();
|
||||
|
||||
private ForgedMethodHistory description;
|
||||
|
||||
/**
|
||||
* @return {@code true} if property names should be used for the creation of the {@link ForgedMethodHistory}.
|
||||
*/
|
||||
@ -44,7 +46,7 @@ public abstract class AbstractMappingMethodBuilder<B extends AbstractMappingMeth
|
||||
history = ( (ForgedMethod) method ).getHistory();
|
||||
}
|
||||
|
||||
ForgedMethodHistory forgedHistory = new ForgedMethodHistory(
|
||||
description = new ForgedMethodHistory(
|
||||
history,
|
||||
Strings.stubPropertyName( sourceRHS.getSourceType().getName() ),
|
||||
Strings.stubPropertyName( targetType.getName() ),
|
||||
@ -53,7 +55,7 @@ public abstract class AbstractMappingMethodBuilder<B extends AbstractMappingMeth
|
||||
shouldUsePropertyNamesInHistory(),
|
||||
sourceRHS.getSourceErrorMessagePart() );
|
||||
|
||||
ForgedMethod forgedMethod = forElementMapping( name, sourceType, targetType, method, forgedHistory, true );
|
||||
ForgedMethod forgedMethod = forElementMapping( name, sourceType, targetType, method, description, true );
|
||||
BuilderGem builder = method.getOptions().getBeanMapping().getBuilder();
|
||||
|
||||
return createForgedAssignment(
|
||||
@ -77,4 +79,9 @@ public abstract class AbstractMappingMethodBuilder<B extends AbstractMappingMeth
|
||||
builder.append( type.getIdentification() );
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public ForgedMethodHistory getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ import static org.mapstruct.ap.internal.util.Collections.first;
|
||||
import static org.mapstruct.ap.internal.util.Message.BEANMAPPING_ABSTRACT;
|
||||
import static org.mapstruct.ap.internal.util.Message.BEANMAPPING_NOT_ASSIGNABLE;
|
||||
import static org.mapstruct.ap.internal.util.Message.GENERAL_ABSTRACT_RETURN_TYPE;
|
||||
import static org.mapstruct.ap.internal.util.Message.GENERAL_AMBIGIOUS_CONSTRUCTORS;
|
||||
import static org.mapstruct.ap.internal.util.Message.GENERAL_AMBIGUOUS_CONSTRUCTORS;
|
||||
import static org.mapstruct.ap.internal.util.Message.GENERAL_CONSTRUCTOR_PROPERTIES_NOT_MATCHING_PARAMETERS;
|
||||
|
||||
/**
|
||||
@ -569,7 +569,7 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
|
||||
else {
|
||||
ctx.getMessager().printMessage(
|
||||
method.getExecutable(),
|
||||
Message.GENERAL_AMBIGIOUS_FACTORY_METHOD,
|
||||
Message.GENERAL_AMBIGUOUS_FACTORY_METHOD,
|
||||
returnTypeImpl,
|
||||
Strings.join( matchingFactoryMethods, ", " )
|
||||
);
|
||||
@ -665,7 +665,7 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
|
||||
|
||||
ctx.getMessager().printMessage(
|
||||
method.getExecutable(),
|
||||
GENERAL_AMBIGIOUS_CONSTRUCTORS,
|
||||
GENERAL_AMBIGUOUS_CONSTRUCTORS,
|
||||
type,
|
||||
Strings.join( constructors, ", " )
|
||||
);
|
||||
|
@ -83,6 +83,7 @@ public abstract class ContainerMappingMethodBuilder<B extends ContainerMappingMe
|
||||
);
|
||||
|
||||
Assignment assignment = ctx.getMappingResolver().getTargetAssignment( method,
|
||||
getDescription(),
|
||||
targetElementType,
|
||||
formattingParameters,
|
||||
criteria,
|
||||
|
@ -96,6 +96,7 @@ public class MapMappingMethod extends NormalTypeMappingMethod {
|
||||
|
||||
Assignment keyAssignment = ctx.getMappingResolver().getTargetAssignment(
|
||||
method,
|
||||
getDescription(),
|
||||
keyTargetType,
|
||||
keyFormattingParameters,
|
||||
keyCriteria,
|
||||
@ -142,6 +143,7 @@ public class MapMappingMethod extends NormalTypeMappingMethod {
|
||||
|
||||
Assignment valueAssignment = ctx.getMappingResolver().getTargetAssignment(
|
||||
method,
|
||||
getDescription(),
|
||||
valueTargetType,
|
||||
valueFormattingParameters,
|
||||
valueCriteria,
|
||||
|
@ -78,6 +78,7 @@ public class MappingBuilderContext {
|
||||
* returns a parameter assignment
|
||||
*
|
||||
* @param mappingMethod target mapping method
|
||||
* @param description
|
||||
* @param targetType return type to match
|
||||
* @param formattingParameters used for formatting dates and numbers
|
||||
* @param criteria parameters criteria in the selection process
|
||||
@ -92,7 +93,7 @@ public class MappingBuilderContext {
|
||||
* <li>null, no assignment found</li>
|
||||
* </ol>
|
||||
*/
|
||||
Assignment getTargetAssignment(Method mappingMethod, Type targetType,
|
||||
Assignment getTargetAssignment(Method mappingMethod, ForgedMethodHistory description, Type targetType,
|
||||
FormattingParameters formattingParameters,
|
||||
SelectionCriteria criteria, SourceRHS sourceRHS,
|
||||
AnnotationMirror positionHint,
|
||||
|
@ -81,7 +81,7 @@ public class ObjectFactoryMethodResolver {
|
||||
if ( matchingFactoryMethods.size() > 1 ) {
|
||||
ctx.getMessager().printMessage(
|
||||
method.getExecutable(),
|
||||
Message.GENERAL_AMBIGIOUS_FACTORY_METHOD,
|
||||
Message.GENERAL_AMBIGUOUS_FACTORY_METHOD,
|
||||
alternativeTarget,
|
||||
Strings.join( matchingFactoryMethods, ", " ) );
|
||||
|
||||
|
@ -242,6 +242,7 @@ public class PropertyMapping extends ModelElement {
|
||||
if ( forgeMethodWithMappingReferences == null ) {
|
||||
assignment = ctx.getMappingResolver().getTargetAssignment(
|
||||
method,
|
||||
getForgedMethodHistory( rightHandSide ),
|
||||
targetType,
|
||||
formattingParameters,
|
||||
criteria,
|
||||
@ -791,6 +792,7 @@ public class PropertyMapping extends ModelElement {
|
||||
if ( !targetType.isEnumType() ) {
|
||||
assignment = ctx.getMappingResolver().getTargetAssignment(
|
||||
method,
|
||||
null, // TODO description for constant
|
||||
targetType,
|
||||
formattingParameters,
|
||||
criteria,
|
||||
|
@ -39,6 +39,7 @@ import org.mapstruct.ap.internal.conversion.ConversionProvider;
|
||||
import org.mapstruct.ap.internal.conversion.Conversions;
|
||||
import org.mapstruct.ap.internal.gem.ReportingPolicyGem;
|
||||
import org.mapstruct.ap.internal.model.Field;
|
||||
import org.mapstruct.ap.internal.model.ForgedMethodHistory;
|
||||
import org.mapstruct.ap.internal.model.HelperMethod;
|
||||
import org.mapstruct.ap.internal.model.MapperReference;
|
||||
import org.mapstruct.ap.internal.model.MappingBuilderContext.MappingResolver;
|
||||
@ -74,6 +75,8 @@ import org.mapstruct.ap.internal.util.Strings;
|
||||
*/
|
||||
public class MappingResolverImpl implements MappingResolver {
|
||||
|
||||
private static final int MAX_REPORTING_AMBIGUOUS = 5;
|
||||
|
||||
private final FormattingMessager messager;
|
||||
private final Types typeUtils;
|
||||
private final TypeFactory typeFactory;
|
||||
@ -109,7 +112,7 @@ public class MappingResolverImpl implements MappingResolver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Assignment getTargetAssignment(Method mappingMethod, Type targetType,
|
||||
public Assignment getTargetAssignment(Method mappingMethod, ForgedMethodHistory description, Type targetType,
|
||||
FormattingParameters formattingParameters,
|
||||
SelectionCriteria criteria, SourceRHS sourceRHS,
|
||||
AnnotationMirror positionHint,
|
||||
@ -118,6 +121,7 @@ public class MappingResolverImpl implements MappingResolver {
|
||||
ResolvingAttempt attempt = new ResolvingAttempt(
|
||||
sourceModel,
|
||||
mappingMethod,
|
||||
description,
|
||||
formattingParameters,
|
||||
sourceRHS,
|
||||
criteria,
|
||||
@ -149,6 +153,7 @@ public class MappingResolverImpl implements MappingResolver {
|
||||
private class ResolvingAttempt {
|
||||
|
||||
private final Method mappingMethod;
|
||||
private final ForgedMethodHistory description;
|
||||
private final List<Method> methods;
|
||||
private final SelectionCriteria selectionCriteria;
|
||||
private final SourceRHS sourceRHS;
|
||||
@ -163,7 +168,7 @@ public class MappingResolverImpl implements MappingResolver {
|
||||
// so this set must be cleared.
|
||||
private final Set<SupportingMappingMethod> supportingMethodCandidates;
|
||||
|
||||
private ResolvingAttempt(List<Method> sourceModel, Method mappingMethod,
|
||||
private ResolvingAttempt(List<Method> sourceModel, Method mappingMethod, ForgedMethodHistory description,
|
||||
FormattingParameters formattingParameters, SourceRHS sourceRHS,
|
||||
SelectionCriteria criteria,
|
||||
AnnotationMirror positionHint,
|
||||
@ -172,6 +177,7 @@ public class MappingResolverImpl implements MappingResolver {
|
||||
FormattingMessager messager) {
|
||||
|
||||
this.mappingMethod = mappingMethod;
|
||||
this.description = description;
|
||||
this.methods = filterPossibleCandidateMethods( sourceModel );
|
||||
this.formattingParameters =
|
||||
formattingParameters == null ? FormattingParameters.EMPTY : formattingParameters;
|
||||
@ -202,7 +208,7 @@ public class MappingResolverImpl implements MappingResolver {
|
||||
// first simple mapping method
|
||||
if ( allowMappingMethod() ) {
|
||||
List<SelectedMethod<Method>> matches = getBestMatch( methods, sourceType, targetType );
|
||||
reportErrorWhenAmbigious( matches, targetType );
|
||||
reportErrorWhenAmbiguous( matches, targetType );
|
||||
if ( !matches.isEmpty() ) {
|
||||
assignment = toMethodRef( first( matches ) );
|
||||
assignment.setAssignment( sourceRHS );
|
||||
@ -246,7 +252,7 @@ public class MappingResolverImpl implements MappingResolver {
|
||||
// check for a built-in method
|
||||
if ( !hasQualfiers() ) {
|
||||
List<SelectedMethod<BuiltInMethod>> matches = getBestMatch( builtIns, sourceType, targetType );
|
||||
reportErrorWhenAmbigious( matches, targetType );
|
||||
reportErrorWhenAmbiguous( matches, targetType );
|
||||
if ( !matches.isEmpty() ) {
|
||||
assignment = toBuildInRef( first( matches ) );
|
||||
assignment.setAssignment( sourceRHS );
|
||||
@ -443,29 +449,37 @@ public class MappingResolverImpl implements MappingResolver {
|
||||
);
|
||||
}
|
||||
|
||||
private <T extends Method> void reportErrorWhenAmbigious(List<SelectedMethod<T>> candidates, Type target) {
|
||||
private <T extends Method> void reportErrorWhenAmbiguous(List<SelectedMethod<T>> candidates, Type target) {
|
||||
|
||||
// raise an error if more than one mapping method is suitable to map the given source type
|
||||
// into the target type
|
||||
if ( candidates.size() > 1 ) {
|
||||
|
||||
String descriptionStr = "";
|
||||
if ( description != null ) {
|
||||
descriptionStr = description.createSourcePropertyErrorMessage();
|
||||
}
|
||||
else {
|
||||
descriptionStr = sourceRHS.getSourceErrorMessagePart();
|
||||
}
|
||||
|
||||
if ( sourceRHS.getSourceErrorMessagePart() != null ) {
|
||||
messager.printMessage(
|
||||
mappingMethod.getExecutable(),
|
||||
positionHint,
|
||||
Message.GENERAL_AMBIGIOUS_MAPPING_METHOD,
|
||||
sourceRHS.getSourceErrorMessagePart(),
|
||||
Message.GENERAL_AMBIGUOUS_MAPPING_METHOD,
|
||||
descriptionStr,
|
||||
target,
|
||||
Strings.join( candidates, ", " )
|
||||
join( candidates )
|
||||
);
|
||||
}
|
||||
else {
|
||||
messager.printMessage(
|
||||
mappingMethod.getExecutable(),
|
||||
positionHint,
|
||||
Message.GENERAL_AMBIGIOUS_FACTORY_METHOD,
|
||||
Message.GENERAL_AMBIGUOUS_FACTORY_METHOD,
|
||||
target,
|
||||
Strings.join( candidates, ", " )
|
||||
join( candidates )
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -578,6 +592,18 @@ public class MappingResolverImpl implements MappingResolver {
|
||||
return false;
|
||||
}
|
||||
|
||||
private <T extends Method> String join( List<SelectedMethod<T>> candidates ) {
|
||||
|
||||
String candidateStr = candidates.stream()
|
||||
.limit( MAX_REPORTING_AMBIGUOUS )
|
||||
.map( m -> m.getMethod().shortName() )
|
||||
.collect( Collectors.joining( ", " ) );
|
||||
|
||||
if ( candidates.size() > MAX_REPORTING_AMBIGUOUS ) {
|
||||
candidateStr += String.format( "... and %s more", candidates.size() - MAX_REPORTING_AMBIGUOUS );
|
||||
}
|
||||
return candidateStr;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ConversionAssignment {
|
||||
@ -762,28 +788,26 @@ public class MappingResolverImpl implements MappingResolver {
|
||||
result = methodRefY;
|
||||
}
|
||||
else {
|
||||
reportAmbigiousError( xCandidates, targetType );
|
||||
reportAmbiguousError( xCandidates, targetType );
|
||||
}
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
void reportAmbigiousError(Map<SelectedMethod<T1>, List<SelectedMethod<T2>>> xCandidates, Type target) {
|
||||
void reportAmbiguousError(Map<SelectedMethod<T1>, List<SelectedMethod<T2>>> xCandidates, Type target) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
xCandidates.entrySet()
|
||||
.stream()
|
||||
.limit( MAX_REPORTING_AMBIGUOUS )
|
||||
.forEach( e -> result.append( "method(s)Y: " )
|
||||
.append( e.getValue()
|
||||
.stream()
|
||||
.map( v -> v.getMethod().shortName() )
|
||||
.collect( Collectors.joining( ", " ) ) )
|
||||
.append( attempt.join( e.getValue() ) )
|
||||
.append( ", methodX: " )
|
||||
.append( e.getKey().getMethod().shortName() )
|
||||
.append( "; " ) );
|
||||
attempt.messager.printMessage(
|
||||
attempt.mappingMethod.getExecutable(),
|
||||
attempt.positionHint,
|
||||
Message.GENERAL_AMBIGIOUS_MAPPING_METHODY_METHODX,
|
||||
Message.GENERAL_AMBIGUOUS_MAPPING_METHODY_METHODX,
|
||||
attempt.sourceRHS.getSourceType().getName() + " " + attempt.sourceRHS.getSourceParameterName(),
|
||||
target.getName(),
|
||||
result.toString() );
|
||||
@ -878,28 +902,26 @@ public class MappingResolverImpl implements MappingResolver {
|
||||
result = methodRefY;
|
||||
}
|
||||
else {
|
||||
reportAmbigiousError( xRefCandidates, targetType );
|
||||
reportAmbiguousError( xRefCandidates, targetType );
|
||||
}
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
void reportAmbigiousError(Map<ConversionAssignment, List<SelectedMethod<T>>> xRefCandidates, Type target) {
|
||||
void reportAmbiguousError(Map<ConversionAssignment, List<SelectedMethod<T>>> xRefCandidates, Type target) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
xRefCandidates.entrySet()
|
||||
.stream()
|
||||
.limit( MAX_REPORTING_AMBIGUOUS )
|
||||
.forEach( e -> result.append( "method(s)Y: " )
|
||||
.append( e.getValue()
|
||||
.stream()
|
||||
.map( v -> v.getMethod().shortName() )
|
||||
.collect( Collectors.joining( ", " ) ) )
|
||||
.append( attempt.join( e.getValue() ) )
|
||||
.append( ", conversionX: " )
|
||||
.append( e.getKey().shortName() )
|
||||
.append( "; " ) );
|
||||
attempt.messager.printMessage(
|
||||
attempt.mappingMethod.getExecutable(),
|
||||
attempt.positionHint,
|
||||
Message.GENERAL_AMBIGIOUS_MAPPING_METHODY_CONVERSIONX,
|
||||
Message.GENERAL_AMBIGUOUS_MAPPING_METHODY_CONVERSIONX,
|
||||
attempt.sourceRHS.getSourceType().getName() + " " + attempt.sourceRHS.getSourceParameterName(),
|
||||
target.getName(),
|
||||
result.toString() );
|
||||
@ -997,28 +1019,26 @@ public class MappingResolverImpl implements MappingResolver {
|
||||
result = conversionRefY.assignment;
|
||||
}
|
||||
else {
|
||||
reportAmbigiousError( yRefCandidates, targetType );
|
||||
reportAmbiguousError( yRefCandidates, targetType );
|
||||
}
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
void reportAmbigiousError(Map<ConversionAssignment, List<SelectedMethod<T>>> yRefCandidates, Type target) {
|
||||
void reportAmbiguousError(Map<ConversionAssignment, List<SelectedMethod<T>>> yRefCandidates, Type target) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
yRefCandidates.entrySet()
|
||||
.stream()
|
||||
.limit( MAX_REPORTING_AMBIGUOUS )
|
||||
.forEach( e -> result.append( "conversionY: " )
|
||||
.append( e.getKey().shortName() )
|
||||
.append( ", method(s)X: " )
|
||||
.append( e.getValue()
|
||||
.stream()
|
||||
.map( v -> v.getMethod().shortName() )
|
||||
.collect( Collectors.joining( ", " ) ) )
|
||||
.append( attempt.join( e.getValue() ) )
|
||||
.append( "; " ) );
|
||||
attempt.messager.printMessage(
|
||||
attempt.mappingMethod.getExecutable(),
|
||||
attempt.positionHint,
|
||||
Message.GENERAL_AMBIGIOUS_MAPPING_CONVERSIONY_METHODX,
|
||||
Message.GENERAL_AMBIGUOUS_MAPPING_CONVERSIONY_METHODX,
|
||||
attempt.sourceRHS.getSourceType().getName() + " " + attempt.sourceRHS.getSourceParameterName(),
|
||||
target.getName(),
|
||||
result.toString() );
|
||||
|
@ -7,6 +7,7 @@ package org.mapstruct.ap.internal.util;
|
||||
|
||||
import javax.tools.Diagnostic;
|
||||
|
||||
import static org.mapstruct.ap.internal.util.MessageConstants.FAQ_AMBIGUOUS_URL;
|
||||
import static org.mapstruct.ap.internal.util.MessageConstants.FAQ_QUALIFIER_URL;
|
||||
|
||||
/**
|
||||
@ -111,9 +112,9 @@ public enum Message {
|
||||
|
||||
GENERAL_NO_IMPLEMENTATION( "No implementation type is registered for return type %s." ),
|
||||
GENERAL_ABSTRACT_RETURN_TYPE( "The return type %s is an abstract class or interface. Provide a non abstract / non interface result type or a factory method." ),
|
||||
GENERAL_AMBIGIOUS_MAPPING_METHOD( "Ambiguous mapping methods found for mapping %s to %s: %s." ),
|
||||
GENERAL_AMBIGIOUS_FACTORY_METHOD( "Ambiguous factory methods found for creating %s: %s." ),
|
||||
GENERAL_AMBIGIOUS_CONSTRUCTORS( "Ambiguous constructors found for creating %s. Either declare parameterless constructor or annotate the default constructor with an annotation named @Default." ),
|
||||
GENERAL_AMBIGUOUS_MAPPING_METHOD( "Ambiguous mapping methods found for mapping %s to %s: %s. See " + FAQ_AMBIGUOUS_URL + " for more info." ),
|
||||
GENERAL_AMBIGUOUS_FACTORY_METHOD( "Ambiguous factory methods found for creating %s: %s. See " + FAQ_AMBIGUOUS_URL + " for more info." ),
|
||||
GENERAL_AMBIGUOUS_CONSTRUCTORS( "Ambiguous constructors found for creating %s. Either declare parameterless constructor or annotate the default constructor with an annotation named @Default." ),
|
||||
GENERAL_CONSTRUCTOR_PROPERTIES_NOT_MATCHING_PARAMETERS( "Incorrect @ConstructorProperties for %s. The size of the @ConstructorProperties does not match the number of constructor parameters" ),
|
||||
GENERAL_UNSUPPORTED_DATE_FORMAT_CHECK( "No dateFormat check is supported for types %s, %s" ),
|
||||
GENERAL_VALID_DATE( "Given date format \"%s\" is valid.", Diagnostic.Kind.NOTE ),
|
||||
@ -125,9 +126,9 @@ public enum Message {
|
||||
GENERAL_NO_QUALIFYING_METHOD_NAMED( "Qualifier error. No method found annotated with @Named#value: [ %s ]. See " + FAQ_QUALIFIER_URL + " for more info." ),
|
||||
GENERAL_NO_QUALIFYING_METHOD_COMBINED( "Qualifier error. No method found annotated with @Named#value: [ %s ], annotated with [ %s ]. See " + FAQ_QUALIFIER_URL + " for more info." ),
|
||||
|
||||
GENERAL_AMBIGIOUS_MAPPING_METHODY_METHODX( "Ambiguous 2step methods found, mapping %s to %s. Found methodY( methodX ( parameter ) ): %s." ),
|
||||
GENERAL_AMBIGIOUS_MAPPING_CONVERSIONY_METHODX( "Ambiguous 2step methods found, mapping %s to %s. Found conversionY( methodX ( parameter ) ): %s." ),
|
||||
GENERAL_AMBIGIOUS_MAPPING_METHODY_CONVERSIONX( "Ambiguous 2step methods found, mapping %s to %s. Found methodY( conversionX ( parameter ) ): %s." ),
|
||||
GENERAL_AMBIGUOUS_MAPPING_METHODY_METHODX( "Ambiguous 2step methods found, mapping %s to %s. Found methodY( methodX ( parameter ) ): %s." ),
|
||||
GENERAL_AMBIGUOUS_MAPPING_CONVERSIONY_METHODX( "Ambiguous 2step methods found, mapping %s to %s. Found conversionY( methodX ( parameter ) ): %s." ),
|
||||
GENERAL_AMBIGUOUS_MAPPING_METHODY_CONVERSIONX( "Ambiguous 2step methods found, mapping %s to %s. Found methodY( conversionX ( parameter ) ): %s." ),
|
||||
|
||||
BUILDER_MORE_THAN_ONE_BUILDER_CREATION_METHOD( "More than one builder creation method for \"%s\". Found methods: \"%s\". Builder will not be used. Consider implementing a custom BuilderProvider SPI.", Diagnostic.Kind.WARNING ),
|
||||
BUILDER_NO_BUILD_METHOD_FOUND("No build method \"%s\" found in \"%s\" for \"%s\". Found methods: \"%s\".", Diagnostic.Kind.ERROR ),
|
||||
|
@ -9,6 +9,7 @@ public final class MessageConstants {
|
||||
|
||||
public static final String AND = " and ";
|
||||
public static final String FAQ_QUALIFIER_URL = "https://mapstruct.org/faq/#qualifier";
|
||||
public static final String FAQ_AMBIGUOUS_URL = "https://mapstruct.org/faq/#ambiguous";
|
||||
|
||||
private MessageConstants() {
|
||||
}
|
||||
|
@ -65,7 +65,8 @@ public class Issue1242Test {
|
||||
".lang.Class<org.mapstruct.ap.test.bugs._1242.TargetB> clazz), org.mapstruct.ap.test.bugs._1242" +
|
||||
".TargetB org.mapstruct.ap.test.bugs._1242.TargetFactories.createTargetB(@TargetType java.lang" +
|
||||
".Class<org.mapstruct.ap.test.bugs._1242.TargetB> clazz), org.mapstruct.ap.test.bugs._1242" +
|
||||
".TargetB org.mapstruct.ap.test.bugs._1242.TargetFactories.createTargetB().")
|
||||
".TargetB org.mapstruct.ap.test.bugs._1242.TargetFactories.createTargetB()." +
|
||||
" See https://mapstruct.org/faq/#ambiguous for more info." )
|
||||
})
|
||||
public void ambiguousMethodErrorForTwoFactoryMethodsWithSourceParam() {
|
||||
}
|
||||
|
@ -36,7 +36,8 @@ public class AmbiguousAnnotatedFactoryTest {
|
||||
".ambiguousannotatedfactorymethod.Foo foo), org.mapstruct.ap.test.erroneous" +
|
||||
".ambiguousannotatedfactorymethod.Bar org.mapstruct.ap.test.erroneous" +
|
||||
".ambiguousannotatedfactorymethod.AmbiguousBarFactory.createBar(org.mapstruct.ap.test.erroneous" +
|
||||
".ambiguousannotatedfactorymethod.Foo foo).")
|
||||
".ambiguousannotatedfactorymethod.Foo foo)." +
|
||||
" See https://mapstruct.org/faq/#ambiguous for more info.")
|
||||
|
||||
}
|
||||
)
|
||||
|
@ -37,8 +37,8 @@ public class FactoryTest {
|
||||
message = "Ambiguous factory methods found for creating org.mapstruct.ap.test.erroneous" +
|
||||
".ambiguousfactorymethod.Bar: org.mapstruct.ap.test.erroneous.ambiguousfactorymethod.Bar " +
|
||||
"createBar(), org.mapstruct.ap.test.erroneous.ambiguousfactorymethod.Bar org.mapstruct.ap.test" +
|
||||
".erroneous.ambiguousfactorymethod.a.BarFactory.createBar().")
|
||||
|
||||
".erroneous.ambiguousfactorymethod.a.BarFactory.createBar()." +
|
||||
" See https://mapstruct.org/faq/#ambiguous for more info.")
|
||||
}
|
||||
)
|
||||
public void shouldUseTwoFactoryMethods() {
|
||||
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright MapStruct Authors.
|
||||
*
|
||||
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
package org.mapstruct.ap.test.erroneous.ambiguousmapping;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mapstruct.ap.testutil.IssueKey;
|
||||
import org.mapstruct.ap.testutil.WithClasses;
|
||||
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.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
||||
|
||||
@IssueKey("2156")
|
||||
@RunWith(AnnotationProcessorTestRunner.class)
|
||||
public class AmbigiousMapperTest {
|
||||
|
||||
@Test
|
||||
@WithClasses( ErroneousWithAmbiguousMethodsMapper.class)
|
||||
@ExpectedCompilationOutcome(
|
||||
value = CompilationResult.FAILED,
|
||||
diagnostics = {
|
||||
@Diagnostic(type = ErroneousWithAmbiguousMethodsMapper.class,
|
||||
kind = javax.tools.Diagnostic.Kind.ERROR,
|
||||
line = 16,
|
||||
message = "Ambiguous mapping methods found for mapping property "
|
||||
+ "\"org.mapstruct.ap.test.erroneous.ambiguousmapping."
|
||||
+ "ErroneousWithAmbiguousMethodsMapper.LeafDTO branch.leaf\" to "
|
||||
+ "org.mapstruct.ap.test.erroneous.ambiguousmapping."
|
||||
+ "ErroneousWithAmbiguousMethodsMapper.LeafEntity: "
|
||||
+ "LeafEntity:map1(LeafDTO), LeafEntity:map2(LeafDTO). "
|
||||
+ "See https://mapstruct.org/faq/#ambiguous for more info.")
|
||||
}
|
||||
)
|
||||
|
||||
public void testErrorMessageForAmbiguous() {
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithClasses( ErroneousWithMoreThanFiveAmbiguousMethodsMapper.class)
|
||||
@ExpectedCompilationOutcome(
|
||||
value = CompilationResult.FAILED,
|
||||
diagnostics = {
|
||||
@Diagnostic(type = ErroneousWithMoreThanFiveAmbiguousMethodsMapper.class,
|
||||
kind = javax.tools.Diagnostic.Kind.ERROR,
|
||||
line = 17,
|
||||
message = "Ambiguous mapping methods found for mapping property "
|
||||
+ "\"org.mapstruct.ap.test.erroneous.ambiguousmapping."
|
||||
+ "ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafDTO branch.leaf\" to "
|
||||
+ "org.mapstruct.ap.test.erroneous.ambiguousmapping."
|
||||
+ "ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafEntity: "
|
||||
+ "LeafEntity:map1(LeafDTO), "
|
||||
+ "LeafEntity:map2(LeafDTO), "
|
||||
+ "LeafEntity:map3(LeafDTO), "
|
||||
+ "LeafEntity:map4(LeafDTO), "
|
||||
+ "LeafEntity:map5(LeafDTO)"
|
||||
+ "... and 1 more. "
|
||||
+ "See https://mapstruct.org/faq/#ambiguous for more info.")
|
||||
}
|
||||
)
|
||||
public void testErrorMessageForManyAmbiguous() {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright MapStruct Authors.
|
||||
*
|
||||
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
package org.mapstruct.ap.test.erroneous.ambiguousmapping;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public interface ErroneousWithAmbiguousMethodsMapper {
|
||||
|
||||
ErroneousWithAmbiguousMethodsMapper INSTANCE = Mappers.getMapper( ErroneousWithAmbiguousMethodsMapper.class );
|
||||
|
||||
TrunkEntity map(TrunkDTO dto);
|
||||
|
||||
default LeafEntity map1(LeafDTO dto) {
|
||||
return new LeafEntity();
|
||||
}
|
||||
|
||||
// duplicated method, triggering ambigious mapping method
|
||||
default LeafEntity map2(LeafDTO dto) {
|
||||
return new LeafEntity();
|
||||
}
|
||||
|
||||
// CHECKSTYLE:OFF
|
||||
class TrunkDTO {
|
||||
public BranchDTO branch;
|
||||
}
|
||||
|
||||
class BranchDTO {
|
||||
public LeafDTO leaf;
|
||||
}
|
||||
|
||||
class LeafDTO {
|
||||
public int numberOfVeigns;
|
||||
}
|
||||
|
||||
class TrunkEntity {
|
||||
public BranchEntity branch;
|
||||
}
|
||||
|
||||
class BranchEntity {
|
||||
public LeafEntity leaf;
|
||||
}
|
||||
|
||||
class LeafEntity {
|
||||
public int numberOfVeigns;
|
||||
}
|
||||
// CHECKSTYLE ON
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright MapStruct Authors.
|
||||
*
|
||||
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
package org.mapstruct.ap.test.erroneous.ambiguousmapping;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public interface ErroneousWithMoreThanFiveAmbiguousMethodsMapper {
|
||||
|
||||
ErroneousWithMoreThanFiveAmbiguousMethodsMapper
|
||||
INSTANCE = Mappers.getMapper( ErroneousWithMoreThanFiveAmbiguousMethodsMapper.class );
|
||||
|
||||
TrunkEntity map(TrunkDTO dto);
|
||||
|
||||
default LeafEntity map1(LeafDTO dto) {
|
||||
return new LeafEntity();
|
||||
}
|
||||
|
||||
// duplicated method, triggering ambigious mapping method
|
||||
default LeafEntity map2(LeafDTO dto) {
|
||||
return new LeafEntity();
|
||||
}
|
||||
|
||||
// duplicated method, triggering ambigious mapping method
|
||||
default LeafEntity map3(LeafDTO dto) {
|
||||
return new LeafEntity();
|
||||
}
|
||||
|
||||
// duplicated method, triggering ambigious mapping method
|
||||
default LeafEntity map4(LeafDTO dto) {
|
||||
return new LeafEntity();
|
||||
}
|
||||
|
||||
// duplicated method, triggering ambigious mapping method
|
||||
|
||||
default LeafEntity map5(LeafDTO dto) {
|
||||
return new LeafEntity();
|
||||
}
|
||||
|
||||
// duplicated method, triggering ambigious mapping method
|
||||
default LeafEntity map6(LeafDTO dto) {
|
||||
return new LeafEntity();
|
||||
}
|
||||
|
||||
// CHECKSTYLE:OFF
|
||||
class TrunkDTO {
|
||||
public BranchDTO branch;
|
||||
}
|
||||
|
||||
class BranchDTO {
|
||||
public LeafDTO leaf;
|
||||
}
|
||||
|
||||
class LeafDTO {
|
||||
public int numberOfVeigns;
|
||||
}
|
||||
|
||||
class TrunkEntity {
|
||||
public BranchEntity branch;
|
||||
}
|
||||
|
||||
class BranchEntity {
|
||||
public LeafEntity leaf;
|
||||
}
|
||||
|
||||
class LeafEntity {
|
||||
public int numberOfVeigns;
|
||||
}
|
||||
// CHECKSTYLE ON
|
||||
}
|
@ -69,13 +69,12 @@ public class ComplexInheritanceTest {
|
||||
kind = Kind.ERROR,
|
||||
type = ErroneousSourceCompositeTargetCompositeMapper.class,
|
||||
line = 19,
|
||||
message = "Ambiguous mapping methods found for mapping property \"org.mapstruct.ap.test.inheritance" +
|
||||
".complex.SourceExt prop1\" to org.mapstruct.ap.test.inheritance.complex.Reference: org.mapstruct.ap" +
|
||||
".test.inheritance.complex.Reference org.mapstruct.ap.test.inheritance.complex" +
|
||||
".AdditionalMappingHelper.asReference(org.mapstruct.ap.test.inheritance.complex.SourceBase source), " +
|
||||
"org.mapstruct.ap.test.inheritance.complex.Reference org.mapstruct.ap.test.inheritance.complex" +
|
||||
".AdditionalMappingHelper.asReference(org.mapstruct.ap.test.inheritance.complex.AdditionalFooSource " +
|
||||
"source)."))
|
||||
message = "Ambiguous mapping methods found for mapping property "
|
||||
+ "\"org.mapstruct.ap.test.inheritance.complex.SourceExt prop1\" "
|
||||
+ "to org.mapstruct.ap.test.inheritance.complex.Reference: "
|
||||
+ "Reference:asReference(SourceBase), Reference:asReference(AdditionalFooSource). "
|
||||
+ "See https://mapstruct.org/faq/#ambiguous for more info.")
|
||||
)
|
||||
public void ambiguousMappingMethodsReportError() {
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,9 @@ public class InheritanceSelectionTest {
|
||||
message = "Ambiguous factory methods found for creating org.mapstruct.ap.test.selection.resulttype" +
|
||||
".Fruit: org.mapstruct.ap.test.selection.resulttype.Apple org.mapstruct.ap.test.selection" +
|
||||
".resulttype.ConflictingFruitFactory.createApple(), org.mapstruct.ap.test.selection.resulttype" +
|
||||
".Banana org.mapstruct.ap.test.selection.resulttype.ConflictingFruitFactory.createBanana().")
|
||||
".Banana org.mapstruct.ap.test.selection.resulttype.ConflictingFruitFactory.createBanana()." +
|
||||
" See https://mapstruct.org/faq/#ambiguous for more info."
|
||||
)
|
||||
}
|
||||
)
|
||||
public void testForkedInheritanceHierarchyShouldResultInAmbigousMappingMethod() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user