diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java index 8942c6278..c8fbe0205 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java @@ -420,7 +420,7 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { FormattingParameters.EMPTY, criteria, rightHandSide, - null, + subclassMappingOptions.getMirror(), () -> forgeSubclassMapping( rightHandSide, sourceType, diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SubclassMappingOptions.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SubclassMappingOptions.java index 6ed1117eb..11b4b283c 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SubclassMappingOptions.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SubclassMappingOptions.java @@ -7,7 +7,10 @@ package org.mapstruct.ap.internal.model.source; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; +import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.ExecutableElement; import javax.lang.model.type.TypeMirror; @@ -34,14 +37,16 @@ public class SubclassMappingOptions extends DelegatingOptions { private final TypeMirror target; private final TypeUtils typeUtils; private final SelectionParameters selectionParameters; + private final SubclassMappingGem subclassMapping; public SubclassMappingOptions(TypeMirror source, TypeMirror target, TypeUtils typeUtils, DelegatingOptions next, - SelectionParameters selectionParameters) { + SelectionParameters selectionParameters, SubclassMappingGem subclassMapping) { super( next ); this.source = source; this.target = target; this.typeUtils = typeUtils; this.selectionParameters = selectionParameters; + this.subclassMapping = subclassMapping; } @Override @@ -124,14 +129,18 @@ public class SubclassMappingOptions extends DelegatingOptions { return selectionParameters; } + public AnnotationMirror getMirror() { + return Optional.ofNullable( subclassMapping ).map( SubclassMappingGem::mirror ).orElse( null ); + } + public static void addInstances(SubclassMappingsGem gem, ExecutableElement method, BeanMappingOptions beanMappingOptions, FormattingMessager messager, TypeUtils typeUtils, Set mappings, List sourceParameters, Type resultType, SubclassValidator subclassValidator) { - for ( SubclassMappingGem subclassMappingGem : gem.value().get() ) { + for ( SubclassMappingGem subclassMapping : gem.value().get() ) { addInstance( - subclassMappingGem, + subclassMapping, method, beanMappingOptions, messager, @@ -175,25 +184,22 @@ public class SubclassMappingOptions extends DelegatingOptions { targetSubclass, typeUtils, beanMappingOptions, - selectionParameters + selectionParameters, + subclassMapping ) ); } - public static List copyForInverseInheritance(Set subclassMappings, + public static List copyForInverseInheritance(Set mappings, BeanMappingOptions beanMappingOptions) { // we are not interested in keeping it unique at this point. - List mappings = new ArrayList<>(); - for ( SubclassMappingOptions subclassMapping : subclassMappings ) { - mappings.add( - new SubclassMappingOptions( - subclassMapping.target, - subclassMapping.source, - subclassMapping.typeUtils, - beanMappingOptions, - subclassMapping.selectionParameters - ) ); - } - return mappings; + return mappings.stream().map( mapping -> new SubclassMappingOptions( + mapping.target, + mapping.source, + mapping.typeUtils, + beanMappingOptions, + mapping.selectionParameters, + mapping.subclassMapping + ) ).collect( Collectors.toCollection( ArrayList::new ) ); } @Override diff --git a/processor/src/test/java/org/mapstruct/ap/test/subclassmapping/qualifier/ErroneousSubclassQualifiedByMapper.java b/processor/src/test/java/org/mapstruct/ap/test/subclassmapping/qualifier/ErroneousSubclassQualifiedByMapper.java index 26cdd4715..fb5dcca11 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/subclassmapping/qualifier/ErroneousSubclassQualifiedByMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/subclassmapping/qualifier/ErroneousSubclassQualifiedByMapper.java @@ -11,6 +11,5 @@ import org.mapstruct.SubclassMapping; @Mapper(uses = { RossiniMapper.class, VivaldiMapper.class }) public interface ErroneousSubclassQualifiedByMapper { @SubclassMapping(source = Rossini.class, target = RossiniDto.class, qualifiedBy = NonExistent.class) - @SubclassMapping(source = Vivaldi.class, target = VivaldiDto.class) ComposerDto toDto(Composer composer); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/subclassmapping/qualifier/SubclassQualifierMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/subclassmapping/qualifier/SubclassQualifierMapperTest.java index df67c2701..2b301d898 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/subclassmapping/qualifier/SubclassQualifierMapperTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/subclassmapping/qualifier/SubclassQualifierMapperTest.java @@ -230,7 +230,7 @@ public class SubclassQualifierMapperTest { diagnostics = @Diagnostic( type = ErroneousSubclassQualifiedByMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 15, + line = 13, message = "Qualifier error. No method found annotated with: [ @NonExistent ]. " + "See https://mapstruct.org/faq/#qualifier for more info." ) @@ -245,7 +245,8 @@ public class SubclassQualifierMapperTest { diagnostics = @Diagnostic( type = ErroneousSubclassQualifiedByNameMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 15, + line = 13, + alternativeLine = 15, message = "Qualifier error. No method found annotated with @Named#value: [ non-existent ]. " + "See https://mapstruct.org/faq/#qualifier for more info." )