#1140 Add warning when target has no properties

This commit is contained in:
zral 2025-05-11 19:59:59 +02:00 committed by GitHub
parent 2c84d04463
commit 602e29083f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
71 changed files with 657 additions and 85 deletions

View File

@ -235,9 +235,10 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
this.unprocessedTargetProperties = new LinkedHashMap<>( accessors ); this.unprocessedTargetProperties = new LinkedHashMap<>( accessors );
boolean constructorAccessorHadError = false;
if ( !method.isUpdateMethod() && !hasFactoryMethod ) { if ( !method.isUpdateMethod() && !hasFactoryMethod ) {
ConstructorAccessor constructorAccessor = getConstructorAccessor( resultTypeToMap ); ConstructorAccessor constructorAccessor = getConstructorAccessor( resultTypeToMap );
if ( constructorAccessor != null ) { if ( constructorAccessor != null && !constructorAccessor.hasError ) {
this.unprocessedConstructorProperties = constructorAccessor.constructorAccessors; this.unprocessedConstructorProperties = constructorAccessor.constructorAccessors;
@ -250,8 +251,10 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
else { else {
this.unprocessedConstructorProperties = new LinkedHashMap<>(); this.unprocessedConstructorProperties = new LinkedHashMap<>();
} }
constructorAccessorHadError = constructorAccessor != null && constructorAccessor.hasError;
this.targetProperties.addAll( this.unprocessedConstructorProperties.keySet() ); this.targetProperties.addAll( this.unprocessedConstructorProperties.keySet() );
this.unprocessedTargetProperties.putAll( this.unprocessedConstructorProperties ); this.unprocessedTargetProperties.putAll( this.unprocessedConstructorProperties );
} }
else { else {
@ -322,7 +325,7 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
// report errors on unmapped properties // report errors on unmapped properties
if ( shouldHandledDefinedMappings ) { if ( shouldHandledDefinedMappings ) {
reportErrorForUnmappedTargetPropertiesIfRequired(); reportErrorForUnmappedTargetPropertiesIfRequired( resultTypeToMap, constructorAccessorHadError );
reportErrorForUnmappedSourcePropertiesIfRequired(); reportErrorForUnmappedSourcePropertiesIfRequired();
} }
reportErrorForMissingIgnoredSourceProperties(); reportErrorForMissingIgnoredSourceProperties();
@ -964,7 +967,7 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
) )
.collect( Collectors.joining( ", " ) ) .collect( Collectors.joining( ", " ) )
); );
return null; return new ConstructorAccessor( true, Collections.emptyList(), Collections.emptyMap() );
} }
else { else {
return getConstructorAccessor( type, accessibleConstructors.get( 0 ) ); return getConstructorAccessor( type, accessibleConstructors.get( 0 ) );
@ -1023,7 +1026,7 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
GENERAL_CONSTRUCTOR_PROPERTIES_NOT_MATCHING_PARAMETERS, GENERAL_CONSTRUCTOR_PROPERTIES_NOT_MATCHING_PARAMETERS,
type type
); );
return null; return new ConstructorAccessor( true, Collections.emptyList(), Collections.emptyMap() );
} }
else { else {
Map<String, Accessor> constructorAccessors = new LinkedHashMap<>(); Map<String, Accessor> constructorAccessors = new LinkedHashMap<>();
@ -1731,13 +1734,14 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
return method.getOptions().getMapper().unmappedTargetPolicy(); return method.getOptions().getMapper().unmappedTargetPolicy();
} }
private void reportErrorForUnmappedTargetPropertiesIfRequired() { private void reportErrorForUnmappedTargetPropertiesIfRequired(Type resultType,
boolean constructorAccessorHadError) {
// fetch settings from element to implement // fetch settings from element to implement
ReportingPolicyGem unmappedTargetPolicy = getUnmappedTargetPolicy(); ReportingPolicyGem unmappedTargetPolicy = getUnmappedTargetPolicy();
if ( method instanceof ForgedMethod && targetProperties.isEmpty() ) { if ( targetProperties.isEmpty() ) {
//TODO until we solve 1140 we report this error when the target properties are empty if ( method instanceof ForgedMethod ) {
ForgedMethod forgedMethod = (ForgedMethod) method; ForgedMethod forgedMethod = (ForgedMethod) method;
if ( forgedMethod.getHistory() == null ) { if ( forgedMethod.getHistory() == null ) {
Type sourceType = this.method.getParameters().get( 0 ).getType(); Type sourceType = this.method.getParameters().get( 0 ).getType();
@ -1764,6 +1768,14 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
); );
} }
} }
else if ( !constructorAccessorHadError ) {
ctx.getMessager().printMessage(
method.getExecutable(),
Message.PROPERTYMAPPING_TARGET_HAS_NO_TARGET_PROPERTIES,
resultType.describe()
);
}
}
else if ( !unprocessedTargetProperties.isEmpty() && unmappedTargetPolicy.requiresReport() ) { else if ( !unprocessedTargetProperties.isEmpty() && unmappedTargetPolicy.requiresReport() ) {
Message unmappedPropertiesMsg; Message unmappedPropertiesMsg;
@ -1780,7 +1792,8 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
reportErrorForUnmappedProperties( reportErrorForUnmappedProperties(
unprocessedTargetProperties, unprocessedTargetProperties,
unmappedPropertiesMsg, unmappedPropertiesMsg,
unmappedForgedPropertiesMsg ); unmappedForgedPropertiesMsg
);
} }
} }
@ -1907,12 +1920,19 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
} }
private static class ConstructorAccessor { private static class ConstructorAccessor {
private final boolean hasError;
private final List<ParameterBinding> parameterBindings; private final List<ParameterBinding> parameterBindings;
private final Map<String, Accessor> constructorAccessors; private final Map<String, Accessor> constructorAccessors;
private ConstructorAccessor( private ConstructorAccessor(
List<ParameterBinding> parameterBindings, List<ParameterBinding> parameterBindings,
Map<String, Accessor> constructorAccessors) { Map<String, Accessor> constructorAccessors) {
this( false, parameterBindings, constructorAccessors );
}
private ConstructorAccessor(boolean hasError, List<ParameterBinding> parameterBindings,
Map<String, Accessor> constructorAccessors) {
this.hasError = hasError;
this.parameterBindings = parameterBindings; this.parameterBindings = parameterBindings;
this.constructorAccessors = constructorAccessors; this.constructorAccessors = constructorAccessors;
} }

View File

@ -92,6 +92,7 @@ public enum Message {
PROPERTYMAPPING_CANNOT_DETERMINE_SOURCE_PARAMETER_FROM_TARGET("No property named \"%s\" exists in source parameter(s). Please define the source explicitly."), PROPERTYMAPPING_CANNOT_DETERMINE_SOURCE_PARAMETER_FROM_TARGET("No property named \"%s\" exists in source parameter(s). Please define the source explicitly."),
PROPERTYMAPPING_NO_SUITABLE_COLLECTION_OR_MAP_CONSTRUCTOR( "%s does not have an accessible copy or no-args constructor." ), PROPERTYMAPPING_NO_SUITABLE_COLLECTION_OR_MAP_CONSTRUCTOR( "%s does not have an accessible copy or no-args constructor." ),
PROPERTYMAPPING_EXPRESSION_AND_CONDITION_QUALIFIED_BY_NAME_BOTH_DEFINED( "Expression and condition qualified by name are both defined in @Mapping, either define an expression or a condition qualified by name." ), PROPERTYMAPPING_EXPRESSION_AND_CONDITION_QUALIFIED_BY_NAME_BOTH_DEFINED( "Expression and condition qualified by name are both defined in @Mapping, either define an expression or a condition qualified by name." ),
PROPERTYMAPPING_TARGET_HAS_NO_TARGET_PROPERTIES( "No target property found for target \"%s\".", Diagnostic.Kind.WARNING ),
CONVERSION_LOSSY_WARNING( "%s has a possibly lossy conversion from %s to %s.", Diagnostic.Kind.WARNING ), CONVERSION_LOSSY_WARNING( "%s has a possibly lossy conversion from %s to %s.", Diagnostic.Kind.WARNING ),
CONVERSION_LOSSY_ERROR( "Can't map %s. It has a possibly lossy conversion from %s to %s." ), CONVERSION_LOSSY_ERROR( "Can't map %s. It has a possibly lossy conversion from %s to %s." ),

View File

@ -7,6 +7,7 @@ package org.mapstruct.ap.test.annotatewith;
import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.extension.RegisterExtension;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.ap.test.WithProperties;
import org.mapstruct.ap.testutil.IssueKey; import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.ProcessorTest;
import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.WithClasses;
@ -176,12 +177,12 @@ public class AnnotateWithTest {
@Diagnostic( @Diagnostic(
kind = javax.tools.Diagnostic.Kind.ERROR, kind = javax.tools.Diagnostic.Kind.ERROR,
type = ErroneousMapperWithClassOnMethod.class, type = ErroneousMapperWithClassOnMethod.class,
line = 17, line = 18,
message = "Annotation \"CustomClassOnlyAnnotation\" is not allowed on methods." message = "Annotation \"CustomClassOnlyAnnotation\" is not allowed on methods."
) )
} }
) )
@WithClasses({ ErroneousMapperWithClassOnMethod.class, CustomClassOnlyAnnotation.class }) @WithClasses({ ErroneousMapperWithClassOnMethod.class, CustomClassOnlyAnnotation.class, WithProperties.class })
public void erroneousMapperWithClassOnMethod() { public void erroneousMapperWithClassOnMethod() {
} }

View File

@ -7,6 +7,7 @@ package org.mapstruct.ap.test.annotatewith;
import org.mapstruct.AnnotateWith; import org.mapstruct.AnnotateWith;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.ap.test.WithProperties;
/** /**
* @author Ben Zegveld * @author Ben Zegveld
@ -15,13 +16,6 @@ import org.mapstruct.Mapper;
public interface ErroneousMapperWithClassOnMethod { public interface ErroneousMapperWithClassOnMethod {
@AnnotateWith( value = CustomClassOnlyAnnotation.class ) @AnnotateWith( value = CustomClassOnlyAnnotation.class )
Target toString(Source value); WithProperties toString(String string);
class Source {
}
class Target {
}
} }

View File

@ -24,8 +24,29 @@ public interface Issue1111Mapper {
List<List<Target>> listList(List<List<Source>> in); List<List<Target>> listList(List<List<Source>> in);
class Source { } class Source {
private final String value;
class Target { } public Source(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
class Target {
private final String value;
public Target(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
} }

View File

@ -27,7 +27,7 @@ public class Issue1111Test {
@ProcessorTest @ProcessorTest
public void shouldCompile() { public void shouldCompile() {
List<List<Source>> source = Arrays.asList( Arrays.asList( new Source() ) ); List<List<Source>> source = Arrays.asList( Arrays.asList( new Source( "test" ) ) );
List<List<Issue1111Mapper.Target>> target = Issue1111Mapper.INSTANCE.listList( source ); List<List<Issue1111Mapper.Target>> target = Issue1111Mapper.INSTANCE.listList( source );

View File

@ -30,6 +30,16 @@ public abstract class Issue1130Mapper {
} }
static class BEntity { static class BEntity {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
} }
static class ADto { static class ADto {
@ -46,6 +56,7 @@ public abstract class Issue1130Mapper {
class BDto { class BDto {
private final String passedViaConstructor; private final String passedViaConstructor;
private String id;
BDto(String passedViaConstructor) { BDto(String passedViaConstructor) {
this.passedViaConstructor = passedViaConstructor; this.passedViaConstructor = passedViaConstructor;
@ -54,6 +65,14 @@ public abstract class Issue1130Mapper {
String getPassedViaConstructor() { String getPassedViaConstructor() {
return passedViaConstructor; return passedViaConstructor;
} }
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
} }
abstract void mergeA(AEntity source, @MappingTarget ADto target); abstract void mergeA(AEntity source, @MappingTarget ADto target);

View File

@ -7,13 +7,14 @@ package org.mapstruct.ap.test.bugs._1242;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.ObjectFactory; import org.mapstruct.ObjectFactory;
import org.mapstruct.ReportingPolicy;
/** /**
* Results in an ambiguous factory method error, as there are two methods with matching source types available. * Results in an ambiguous factory method error, as there are two methods with matching source types available.
* *
* @author Andreas Gudian * @author Andreas Gudian
*/ */
@Mapper(uses = TargetFactories.class) @Mapper(uses = TargetFactories.class, unmappedTargetPolicy = ReportingPolicy.IGNORE)
public abstract class ErroneousIssue1242MapperMultipleSources { public abstract class ErroneousIssue1242MapperMultipleSources {
abstract TargetA toTargetA(SourceA source); abstract TargetA toTargetA(SourceA source);

View File

@ -7,13 +7,14 @@ package org.mapstruct.ap.test.bugs._1242;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget; import org.mapstruct.MappingTarget;
import org.mapstruct.ReportingPolicy;
/** /**
* Test mapper for properly resolving the best fitting factory method * Test mapper for properly resolving the best fitting factory method
* *
* @author Andreas Gudian * @author Andreas Gudian
*/ */
@Mapper(uses = TargetFactories.class) @Mapper(uses = TargetFactories.class, unmappedTargetPolicy = ReportingPolicy.IGNORE)
public abstract class Issue1242Mapper { public abstract class Issue1242Mapper {
abstract TargetA toTargetA(SourceA source); abstract TargetA toTargetA(SourceA source);

View File

@ -54,7 +54,7 @@ public class Issue1242Test {
diagnostics = { diagnostics = {
@Diagnostic(type = ErroneousIssue1242MapperMultipleSources.class, @Diagnostic(type = ErroneousIssue1242MapperMultipleSources.class,
kind = javax.tools.Diagnostic.Kind.ERROR, kind = javax.tools.Diagnostic.Kind.ERROR,
line = 20, line = 21,
message = "Ambiguous factory methods found for creating TargetB: " + message = "Ambiguous factory methods found for creating TargetB: " +
"TargetB anotherTargetBCreator(SourceB source), " + "TargetB anotherTargetBCreator(SourceB source), " +
"TargetB TargetFactories.createTargetB(SourceB source, @TargetType Class<TargetB> clazz), " + "TargetB TargetFactories.createTargetB(SourceB source, @TargetType Class<TargetB> clazz), " +

View File

@ -9,6 +9,7 @@ package org.mapstruct.ap.test.bugs._1242;
* @author Andreas Gudian * @author Andreas Gudian
*/ */
class TargetB { class TargetB {
protected String value;
private final String passedViaConstructor; private final String passedViaConstructor;
TargetB(String passedViaConstructor) { TargetB(String passedViaConstructor) {
@ -18,4 +19,12 @@ class TargetB {
String getPassedViaConstructor() { String getPassedViaConstructor() {
return passedViaConstructor; return passedViaConstructor;
} }
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
} }

View File

@ -27,8 +27,17 @@ public interface Issue1345Mapper {
class A { class A {
private String value;
private String readOnlyProperty; private String readOnlyProperty;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getReadOnlyProperty() { public String getReadOnlyProperty() {
return readOnlyProperty; return readOnlyProperty;
} }
@ -36,8 +45,17 @@ public interface Issue1345Mapper {
class B { class B {
private String value;
private String property; private String property;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getProperty() { public String getProperty() {
return property; return property;
} }

View File

@ -18,13 +18,13 @@ public abstract class Issue1460Mapper {
public abstract Target map(Source source); public abstract Target map(Source source);
public abstract String forceUsageOfIssue1460Enum(Issue1460Enum source); public abstract Value<Issue1460Enum> forceUsageOfIssue1460Enum(Issue1460Enum source);
public abstract String forceUsageOfLocale(Locale source); public abstract Value<Locale> forceUsageOfLocale(Locale source);
public abstract String forceUsageOfLocalDate(LocalDate source); public abstract Value<LocalDate> forceUsageOfLocalDate(LocalDate source);
public abstract String forceUsageOfDateTime(DateTime source); public abstract Value<DateTime> forceUsageOfDateTime(DateTime source);
public static class Issue1460Enum { public static class Issue1460Enum {
} }
@ -37,4 +37,17 @@ public abstract class Issue1460Mapper {
public static class DateTime { public static class DateTime {
} }
public static class Value<T> {
private final T source;
public Value(T source) {
this.source = source;
}
public T getSource() {
return source;
}
}
} }

View File

@ -18,8 +18,17 @@ public abstract class Issue1460JavaTimeMapper {
public abstract Target map(Source source); public abstract Target map(Source source);
public abstract String forceUsageOfLocalDate(LocalDate source); public abstract LocalTarget forceUsageOfLocalDate(LocalDate source);
public static class LocalDate { public static class LocalDate {
} }
public static class LocalTarget {
private final LocalDate source;
public LocalTarget(LocalDate source) {
this.source = source;
}
}
} }

View File

@ -6,4 +6,14 @@
package org.mapstruct.ap.test.bugs._1590; package org.mapstruct.ap.test.bugs._1590;
public class Book { public class Book {
private final String name;
public Book(String name) {
this.name = name;
}
public String getName() {
return name;
}
} }

View File

@ -28,7 +28,7 @@ public class Issue1590Test {
@ProcessorTest @ProcessorTest
public void shouldTestMappingLocalDates() { public void shouldTestMappingLocalDates() {
BookShelf source = new BookShelf(); BookShelf source = new BookShelf();
source.setBooks( Arrays.asList( new Book() ) ); source.setBooks( Arrays.asList( new Book("Test") ) );
BookShelf target = BookShelfMapper.INSTANCE.map( source ); BookShelf target = BookShelfMapper.INSTANCE.map( source );

View File

@ -6,4 +6,14 @@
package org.mapstruct.ap.test.bugs._1650; package org.mapstruct.ap.test.bugs._1650;
public class C { public class C {
private final int value;
public C(int value) {
this.value = value;
}
public int getValue() {
return value;
}
} }

View File

@ -6,4 +6,14 @@
package org.mapstruct.ap.test.bugs._1650; package org.mapstruct.ap.test.bugs._1650;
public class CPrime { public class CPrime {
private int value;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
} }

View File

@ -27,7 +27,7 @@ public class Issue1650Test {
A a = new A(); A a = new A();
a.setB( new B() ); a.setB( new B() );
a.getB().setC( new C() ); a.getB().setC( new C( 10 ) );
APrime aPrime = new APrime(); APrime aPrime = new APrime();

View File

@ -22,11 +22,31 @@ public interface Issue1821Mapper {
ExtendedTarget mapExtended(Source source); ExtendedTarget mapExtended(Source source);
class Target { class Target {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
} }
class ExtendedTarget extends Target { class ExtendedTarget extends Target {
} }
class Source { class Source {
private final String value;
public Source(String value) {
this.value = value;
}
public String getValue() {
return value;
}
} }
} }

View File

@ -15,7 +15,7 @@ public class Issue1821Test {
@ProcessorTest @ProcessorTest
public void shouldNotGiveNullPtr() { public void shouldNotGiveNullPtr() {
Issue1821Mapper.INSTANCE.map( new Issue1821Mapper.Source() ); Issue1821Mapper.INSTANCE.map( new Issue1821Mapper.Source( "test" ) );
} }
} }

View File

@ -43,8 +43,8 @@ public class Issue611Test {
*/ */
@ProcessorTest @ProcessorTest
public void rightMapperIsFound() { public void rightMapperIsFound() {
SomeClass.InnerMapper.Source source1 = new SomeClass.InnerMapper.Source(); SomeClass.InnerMapper.Source source1 = new SomeClass.InnerMapper.Source( "test" );
SomeOtherClass.InnerMapper.Source source2 = new SomeOtherClass.InnerMapper.Source(); SomeOtherClass.InnerMapper.Source source2 = new SomeOtherClass.InnerMapper.Source( "test2" );
SomeClass.InnerMapper.Target target1 = SomeClass.InnerMapper.INSTANCE.toTarget( source1 ); SomeClass.InnerMapper.Target target1 = SomeClass.InnerMapper.INSTANCE.toTarget( source1 );
SomeOtherClass.InnerMapper.Target target2 = SomeOtherClass.InnerMapper.INSTANCE.toTarget( source2 ); SomeOtherClass.InnerMapper.Target target2 = SomeOtherClass.InnerMapper.INSTANCE.toTarget( source2 );

View File

@ -19,9 +19,29 @@ public class SomeClass {
Target toTarget(Source in); Target toTarget(Source in);
class Source { class Source {
private final String value;
public Source(String value) {
this.value = value;
}
public String getValue() {
return value;
}
} }
class Target { class Target {
private final String value;
public Target(String value) {
this.value = value;
}
public String getValue() {
return value;
}
} }
} }
@ -33,9 +53,29 @@ public class SomeClass {
Target toTarget(Source in); Target toTarget(Source in);
class Source { class Source {
private final String value;
public Source(String value) {
this.value = value;
}
public String getValue() {
return value;
}
} }
class Target { class Target {
private final String value;
public Target(String value) {
this.value = value;
}
public String getValue() {
return value;
}
} }
} }
} }

View File

@ -19,9 +19,29 @@ public class SomeOtherClass {
Target toTarget(Source in); Target toTarget(Source in);
class Source { class Source {
private final String value;
public Source(String value) {
this.value = value;
}
public String getValue() {
return value;
}
} }
class Target { class Target {
private final String value;
public Target(String value) {
this.value = value;
}
public String getValue() {
return value;
}
} }
} }
} }

View File

@ -9,6 +9,9 @@ import org.junit.jupiter.api.extension.RegisterExtension;
import org.mapstruct.ap.testutil.IssueKey; import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.ProcessorTest;
import org.mapstruct.ap.testutil.WithClasses; 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.GeneratedSource; import org.mapstruct.ap.testutil.runner.GeneratedSource;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -80,6 +83,17 @@ public class BuilderInfoTargetTest {
} }
@ProcessorTest @ProcessorTest
@WithClasses( {
SimpleImmutableUpdateMapper.class
} )
@ExpectedCompilationOutcome(value = CompilationResult.SUCCEEDED,
diagnostics = {
@Diagnostic(type = SimpleImmutableUpdateMapper.class,
kind = javax.tools.Diagnostic.Kind.WARNING,
line = 18,
message = "No target property found for target \"SimpleImmutableTarget\"."),
})
public void updatingTargetWithNoSettersShouldNotFail() { public void updatingTargetWithNoSettersShouldNotFail() {
SimpleMutableSource source = new SimpleMutableSource(); SimpleMutableSource source = new SimpleMutableSource();
@ -90,7 +104,7 @@ public class BuilderInfoTargetTest {
.build(); .build();
assertThat( target.getAge() ).isEqualTo( 20 ); assertThat( target.getAge() ).isEqualTo( 20 );
SimpleBuilderMapper.INSTANCE.toImmutable( source, target ); SimpleImmutableUpdateMapper.INSTANCE.toImmutable( source, target );
assertThat( target.getAge() ).isEqualTo( 20 ); assertThat( target.getAge() ).isEqualTo( 20 );
} }
} }

View File

@ -21,9 +21,6 @@ public interface SimpleBuilderMapper {
@Mapping(target = "builder.name", source = "source.fullName") @Mapping(target = "builder.name", source = "source.fullName")
void updateImmutable(SimpleMutableSource source, @MappingTarget SimpleImmutableTarget.Builder builder); void updateImmutable(SimpleMutableSource source, @MappingTarget SimpleImmutableTarget.Builder builder);
// This method is fine as if the mapping target has setters it would use them, otherwise it won't
void toImmutable(SimpleMutableSource source, @MappingTarget SimpleImmutableTarget target);
@Mapping(target = "name", source = "fullName") @Mapping(target = "name", source = "fullName")
SimpleImmutableTarget toImmutable(SimpleMutableSource source); SimpleImmutableTarget toImmutable(SimpleMutableSource source);

View File

@ -0,0 +1,19 @@
/*
* 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.builder.mappingTarget.simple;
import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;
import org.mapstruct.factory.Mappers;
@Mapper
public interface SimpleImmutableUpdateMapper {
SimpleImmutableUpdateMapper INSTANCE = Mappers.getMapper( SimpleImmutableUpdateMapper.class );
// This method is fine as if the mapping target has setters it would use them, otherwise it won't
void toImmutable(SimpleMutableSource source, @MappingTarget SimpleImmutableTarget target);
}

View File

@ -11,6 +11,9 @@ import java.util.Collections;
import org.mapstruct.ap.testutil.IssueKey; import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.ProcessorTest;
import org.mapstruct.ap.testutil.WithClasses; 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 static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -41,6 +44,13 @@ public class ImmutableProductTest {
CupboardNoSetterMapper.class, CupboardNoSetterMapper.class,
CupboardEntityOnlyGetter.class CupboardEntityOnlyGetter.class
}) })
@ExpectedCompilationOutcome(value = CompilationResult.SUCCEEDED,
diagnostics = {
@Diagnostic(type = CupboardNoSetterMapper.class,
kind = javax.tools.Diagnostic.Kind.WARNING,
line = 22,
message = "No target property found for target \"CupboardEntityOnlyGetter\"."),
})
public void shouldIgnoreImmutableTarget() { public void shouldIgnoreImmutableTarget() {
CupboardDto in = new CupboardDto(); CupboardDto in = new CupboardDto();
in.setContent( Arrays.asList( "flour", "peas" ) ); in.setContent( Arrays.asList( "flour", "peas" ) );

View File

@ -11,4 +11,13 @@ package org.mapstruct.ap.test.collection.wildcard;
*/ */
public class Idea { public class Idea {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
} }

View File

@ -11,4 +11,13 @@ package org.mapstruct.ap.test.collection.wildcard;
*/ */
public class Plan { public class Plan {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
} }

View File

@ -10,6 +10,9 @@ import org.mapstruct.ap.test.constructor.PersonDto;
import org.mapstruct.ap.testutil.IssueKey; import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.ProcessorTest;
import org.mapstruct.ap.testutil.WithClasses; 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 static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -44,6 +47,15 @@ public class ConstructorVisibilityTest {
@WithClasses({ @WithClasses({
SimpleWithPublicParameterlessConstructorMapper.class SimpleWithPublicParameterlessConstructorMapper.class
}) })
@ExpectedCompilationOutcome(value = CompilationResult.SUCCEEDED,
diagnostics = {
@Diagnostic(type = SimpleWithPublicParameterlessConstructorMapper.class,
kind = javax.tools.Diagnostic.Kind.WARNING,
line = 21,
message = "No target property found for target " +
"\"SimpleWithPublicParameterlessConstructorMapper.Person\"."),
})
public void shouldUsePublicParameterConstructorIfPresent() { public void shouldUsePublicParameterConstructorIfPresent() {
PersonDto source = new PersonDto(); PersonDto source = new PersonDto();
source.setName( "Bob" ); source.setName( "Bob" );

View File

@ -16,5 +16,5 @@ public abstract class AbstractDestinationClassNameMapper {
public static final AbstractDestinationClassNameMapper INSTANCE = public static final AbstractDestinationClassNameMapper INSTANCE =
Mappers.getMapper( AbstractDestinationClassNameMapper.class ); Mappers.getMapper( AbstractDestinationClassNameMapper.class );
public abstract String intToString(Integer source); public abstract Target map(Integer source);
} }

View File

@ -16,5 +16,5 @@ public abstract class AbstractDestinationPackageNameMapper {
public static final AbstractDestinationPackageNameMapper INSTANCE = public static final AbstractDestinationPackageNameMapper INSTANCE =
Mappers.getMapper( AbstractDestinationPackageNameMapper.class ); Mappers.getMapper( AbstractDestinationPackageNameMapper.class );
public abstract String intToString(Integer source); public abstract Target map(Integer source);
} }

View File

@ -15,5 +15,5 @@ import org.mapstruct.factory.Mappers;
public interface DestinationClassNameMapper { public interface DestinationClassNameMapper {
DestinationClassNameMapper INSTANCE = Mappers.getMapper( DestinationClassNameMapper.class ); DestinationClassNameMapper INSTANCE = Mappers.getMapper( DestinationClassNameMapper.class );
String intToString(Integer source); Target map(Integer source);
} }

View File

@ -17,5 +17,5 @@ import org.mapstruct.factory.Mappers;
public interface DestinationClassNameMapperDecorated { public interface DestinationClassNameMapperDecorated {
DestinationClassNameMapperDecorated INSTANCE = Mappers.getMapper( DestinationClassNameMapperDecorated.class ); DestinationClassNameMapperDecorated INSTANCE = Mappers.getMapper( DestinationClassNameMapperDecorated.class );
String intToString(Integer source); Target map(Integer source);
} }

View File

@ -16,7 +16,7 @@ public abstract class DestinationClassNameMapperDecorator implements Destination
} }
@Override @Override
public String intToString(Integer source) { public Target map(Integer source) {
return delegate.intToString( source ); return delegate.map( source );
} }
} }

View File

@ -15,5 +15,5 @@ import org.mapstruct.factory.Mappers;
public interface DestinationClassNameMapperWithConfig { public interface DestinationClassNameMapperWithConfig {
DestinationClassNameMapperWithConfig INSTANCE = Mappers.getMapper( DestinationClassNameMapperWithConfig.class ); DestinationClassNameMapperWithConfig INSTANCE = Mappers.getMapper( DestinationClassNameMapperWithConfig.class );
String intToString(Integer source); Target map(Integer source);
} }

View File

@ -16,5 +16,5 @@ public interface DestinationClassNameMapperWithConfigOverride {
DestinationClassNameMapperWithConfigOverride INSTANCE = DestinationClassNameMapperWithConfigOverride INSTANCE =
Mappers.getMapper( DestinationClassNameMapperWithConfigOverride.class ); Mappers.getMapper( DestinationClassNameMapperWithConfigOverride.class );
String intToString(Integer source); Target map(Integer source);
} }

View File

@ -16,6 +16,7 @@ import static org.assertj.core.api.Assertions.fail;
/** /**
* @author Christophe Labouisse on 27/05/2015. * @author Christophe Labouisse on 27/05/2015.
*/ */
@WithClasses( Target.class )
public class DestinationClassNameTest { public class DestinationClassNameTest {
@ProcessorTest @ProcessorTest
@WithClasses({ DestinationClassNameMapper.class }) @WithClasses({ DestinationClassNameMapper.class })

View File

@ -13,5 +13,5 @@ import org.mapstruct.MappingConstants;
*/ */
@Mapper(implementationName = "<CLASS_NAME>Jsr330Impl", componentModel = MappingConstants.ComponentModel.JSR330) @Mapper(implementationName = "<CLASS_NAME>Jsr330Impl", componentModel = MappingConstants.ComponentModel.JSR330)
public interface DestinationClassNameWithJsr330Mapper { public interface DestinationClassNameWithJsr330Mapper {
String intToString(Integer source); Target map(Integer source);
} }

View File

@ -15,5 +15,5 @@ import org.mapstruct.factory.Mappers;
public interface DestinationPackageNameMapper { public interface DestinationPackageNameMapper {
DestinationPackageNameMapper INSTANCE = Mappers.getMapper( DestinationPackageNameMapper.class ); DestinationPackageNameMapper INSTANCE = Mappers.getMapper( DestinationPackageNameMapper.class );
String intToString(Integer source); Target map(Integer source);
} }

View File

@ -17,5 +17,5 @@ import org.mapstruct.factory.Mappers;
public interface DestinationPackageNameMapperDecorated { public interface DestinationPackageNameMapperDecorated {
DestinationPackageNameMapperDecorated INSTANCE = Mappers.getMapper( DestinationPackageNameMapperDecorated.class ); DestinationPackageNameMapperDecorated INSTANCE = Mappers.getMapper( DestinationPackageNameMapperDecorated.class );
String intToString(Integer source); Target map(Integer source);
} }

View File

@ -16,7 +16,7 @@ public abstract class DestinationPackageNameMapperDecorator implements Destinati
} }
@Override @Override
public String intToString(Integer source) { public Target map(Integer source) {
return delegate.intToString( source ); return delegate.map( source );
} }
} }

View File

@ -15,5 +15,5 @@ import org.mapstruct.factory.Mappers;
public interface DestinationPackageNameMapperWithConfig { public interface DestinationPackageNameMapperWithConfig {
DestinationPackageNameMapperWithConfig INSTANCE = Mappers.getMapper( DestinationPackageNameMapperWithConfig.class ); DestinationPackageNameMapperWithConfig INSTANCE = Mappers.getMapper( DestinationPackageNameMapperWithConfig.class );
String intToString(Integer source); Target map(Integer source);
} }

View File

@ -16,5 +16,5 @@ public interface DestinationPackageNameMapperWithConfigOverride {
DestinationPackageNameMapperWithConfigOverride INSTANCE = DestinationPackageNameMapperWithConfigOverride INSTANCE =
Mappers.getMapper( DestinationPackageNameMapperWithConfigOverride.class ); Mappers.getMapper( DestinationPackageNameMapperWithConfigOverride.class );
String intToString(Integer source); Target map(Integer source);
} }

View File

@ -15,5 +15,5 @@ import org.mapstruct.factory.Mappers;
public interface DestinationPackageNameMapperWithSuffix { public interface DestinationPackageNameMapperWithSuffix {
DestinationPackageNameMapperWithSuffix INSTANCE = Mappers.getMapper( DestinationPackageNameMapperWithSuffix.class ); DestinationPackageNameMapperWithSuffix INSTANCE = Mappers.getMapper( DestinationPackageNameMapperWithSuffix.class );
String intToString(Integer source); Target map(Integer source);
} }

View File

@ -15,6 +15,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Christophe Labouisse on 27/05/2015. * @author Christophe Labouisse on 27/05/2015.
*/ */
@IssueKey( "556" ) @IssueKey( "556" )
@WithClasses( Target.class )
public class DestinationPackageNameTest { public class DestinationPackageNameTest {
@ProcessorTest @ProcessorTest
@WithClasses({ DestinationPackageNameMapper.class }) @WithClasses({ DestinationPackageNameMapper.class })

View File

@ -0,0 +1,19 @@
/*
* 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.destination;
public class Target {
private final Integer source;
public Target(Integer source) {
this.source = source;
}
public Integer getSource() {
return source;
}
}

View File

@ -0,0 +1,9 @@
/*
* 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.emptytarget;
public class EmptyTarget {
}

View File

@ -0,0 +1,18 @@
/*
* 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.emptytarget;
import org.mapstruct.Mapper;
@Mapper
public interface EmptyTargetMapper {
TargetWithNoSetters mapToTargetWithSetters(Source source);
EmptyTarget mapToEmptyTarget(Source source);
Target mapToTarget(Source source);
}

View File

@ -0,0 +1,39 @@
/*
* 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.emptytarget;
import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.ProcessorTest;
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;
@IssueKey("1140")
@WithClasses({
EmptyTarget.class,
EmptyTargetMapper.class,
Source.class,
Target.class,
TargetWithNoSetters.class,
})
class EmptyTargetTest {
@ProcessorTest
@ExpectedCompilationOutcome(value = CompilationResult.SUCCEEDED,
diagnostics = {
@Diagnostic(type = EmptyTargetMapper.class,
kind = javax.tools.Diagnostic.Kind.WARNING,
line = 13,
message = "No target property found for target \"TargetWithNoSetters\"."),
@Diagnostic(type = EmptyTargetMapper.class,
kind = javax.tools.Diagnostic.Kind.WARNING,
line = 15,
message = "No target property found for target \"EmptyTarget\".")
})
void shouldProvideWarnings() {
}
}

View File

@ -0,0 +1,36 @@
/*
* 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.emptytarget;
public class Source {
private String label;
private double weight;
private Object content;
public Object getContent() {
return content;
}
public void setContent(Object content) {
this.content = content;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
}

View File

@ -0,0 +1,34 @@
/*
* 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.emptytarget;
/**
* @author Filip Hrisafov
*/
public class Target {
private final String label;
private final double weight;
private final Object content;
public Target(String label, double weight, Object content) {
this.label = label;
this.weight = weight;
this.content = content;
}
public String getLabel() {
return label;
}
public double getWeight() {
return weight;
}
public Object getContent() {
return content;
}
}

View File

@ -0,0 +1,15 @@
/*
* 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.emptytarget;
public class TargetWithNoSetters {
private int flightNumber;
private String airplaneName;
public String getAirplaneName() {
return airplaneName;
}
}

View File

@ -25,7 +25,7 @@ public interface SourceTargetMapper {
ParseException sourceToTarget(Named source); ParseException sourceToTarget(Named source);
//custom types //custom types
Map listToMap(List list); Value<Map> listToMap(List list);
java.util.List<ParseException> namedsToExceptions(java.util.List<Named> source); java.util.List<ParseException> namedsToExceptions(java.util.List<Named> source);
@ -36,4 +36,12 @@ public interface SourceTargetMapper {
java.util.Map<Date, Date> stringsToDates(java.util.Map<String, String> stringDates); java.util.Map<Date, Date> stringsToDates(java.util.Map<String, String> stringDates);
Target sourceToTarget(Source target); Target sourceToTarget(Source target);
class Value<T> {
private T value;
public Value(List list) {
}
}
} }

View File

@ -11,4 +11,13 @@ package org.mapstruct.ap.test.java8stream.wildcard;
*/ */
public class Idea { public class Idea {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
} }

View File

@ -11,4 +11,13 @@ package org.mapstruct.ap.test.java8stream.wildcard;
*/ */
public class Plan { public class Plan {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
} }

View File

@ -8,14 +8,24 @@ package org.mapstruct.ap.test.missingignoredsource;
import org.mapstruct.BeanMapping; import org.mapstruct.BeanMapping;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy; import org.mapstruct.ReportingPolicy;
import org.mapstruct.factory.Mappers;
@Mapper( @Mapper(
unmappedTargetPolicy = ReportingPolicy.IGNORE, unmappedTargetPolicy = ReportingPolicy.IGNORE,
unmappedSourcePolicy = ReportingPolicy.IGNORE) unmappedSourcePolicy = ReportingPolicy.IGNORE)
public interface ErroneousSourceTargetMapper { public interface ErroneousSourceTargetMapper {
ErroneousSourceTargetMapper INSTANCE = Mappers.getMapper( ErroneousSourceTargetMapper.class );
@BeanMapping(ignoreUnmappedSourceProperties = "bar") @BeanMapping(ignoreUnmappedSourceProperties = "bar")
Object sourceToTarget(Object source); Target map(Target source);
class Target {
private final String value;
public Target(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
} }

View File

@ -22,7 +22,7 @@ public class MissingIgnoredSourceTest {
diagnostics = { diagnostics = {
@Diagnostic(type = ErroneousSourceTargetMapper.class, @Diagnostic(type = ErroneousSourceTargetMapper.class,
kind = Kind.ERROR, kind = Kind.ERROR,
line = 20, line = 18,
message = "Ignored unknown source property: \"bar\".") message = "Ignored unknown source property: \"bar\".")
} }
) )

View File

@ -7,10 +7,11 @@ package org.mapstruct.ap.test.selection.methodgenerics.objectfactory;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.ObjectFactory; import org.mapstruct.ObjectFactory;
import org.mapstruct.ReportingPolicy;
import org.mapstruct.TargetType; import org.mapstruct.TargetType;
import org.mapstruct.factory.Mappers; import org.mapstruct.factory.Mappers;
@Mapper @Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface ObjectFactoryMapper { public interface ObjectFactoryMapper {
ObjectFactoryMapper INSTANCE = Mappers.getMapper( ObjectFactoryMapper.class ); ObjectFactoryMapper INSTANCE = Mappers.getMapper( ObjectFactoryMapper.class );
@ -44,6 +45,16 @@ public interface ObjectFactoryMapper {
} }
abstract class Target { abstract class Target {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
} }
class TargetA extends Target { class TargetA extends Target {

View File

@ -7,4 +7,13 @@ package org.mapstruct.ap.test.subclassmapping.fixture;
public abstract class AbstractParentSource { public abstract class AbstractParentSource {
private String parentValue;
public String getParentValue() {
return parentValue;
}
public void setParentValue(String parentValue) {
this.parentValue = parentValue;
}
} }

View File

@ -7,4 +7,13 @@ package org.mapstruct.ap.test.subclassmapping.fixture;
public abstract class AbstractParentTarget { public abstract class AbstractParentTarget {
private String parentValue;
public String getParentValue() {
return parentValue;
}
public void setParentValue(String parentValue) {
this.parentValue = parentValue;
}
} }

View File

@ -7,4 +7,13 @@ package org.mapstruct.ap.test.subclassmapping.fixture;
public class ImplementedParentSource extends AbstractParentSource { public class ImplementedParentSource extends AbstractParentSource {
private String implementedParentValue;
public String getImplementedParentValue() {
return implementedParentValue;
}
public void setImplementedParentValue(String implementedParentValue) {
this.implementedParentValue = implementedParentValue;
}
} }

View File

@ -7,4 +7,13 @@ package org.mapstruct.ap.test.subclassmapping.fixture;
public class ImplementedParentTarget extends AbstractParentTarget { public class ImplementedParentTarget extends AbstractParentTarget {
private String implementedParentValue;
public String getImplementedParentValue() {
return implementedParentValue;
}
public void setImplementedParentValue(String implementedParentValue) {
this.implementedParentValue = implementedParentValue;
}
} }

View File

@ -6,6 +6,7 @@
package org.mapstruct.ap.test.versioninfo; package org.mapstruct.ap.test.versioninfo;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.ap.test.WithProperties;
/** /**
* @author Andreas Gudian * @author Andreas Gudian
@ -13,5 +14,5 @@ import org.mapstruct.Mapper;
*/ */
@Mapper @Mapper
public interface SimpleMapper { public interface SimpleMapper {
Object toObject(Object object); WithProperties toObject(WithProperties object);
} }

View File

@ -6,11 +6,12 @@
package org.mapstruct.ap.test.versioninfo; package org.mapstruct.ap.test.versioninfo;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.ap.test.WithProperties;
/** /**
* @author Filip Hrisafov * @author Filip Hrisafov
*/ */
@Mapper(suppressTimestampInGenerated = true) @Mapper(suppressTimestampInGenerated = true)
public interface SuppressTimestampViaMapper { public interface SuppressTimestampViaMapper {
Object toObject(Object object); WithProperties toObject(WithProperties object);
} }

View File

@ -7,13 +7,14 @@ package org.mapstruct.ap.test.versioninfo;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.MapperConfig; import org.mapstruct.MapperConfig;
import org.mapstruct.ap.test.WithProperties;
/** /**
* @author Filip Hrisafov * @author Filip Hrisafov
*/ */
@Mapper(config = SuppressTimestampViaMapperConfig.Config.class) @Mapper(config = SuppressTimestampViaMapperConfig.Config.class)
public interface SuppressTimestampViaMapperConfig { public interface SuppressTimestampViaMapperConfig {
Object toObject(Object object); WithProperties toObject(WithProperties object);
@MapperConfig(suppressTimestampInGenerated = true) @MapperConfig(suppressTimestampInGenerated = true)
interface Config { interface Config {

View File

@ -6,6 +6,7 @@
package org.mapstruct.ap.test.versioninfo; package org.mapstruct.ap.test.versioninfo;
import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.extension.RegisterExtension;
import org.mapstruct.ap.test.WithProperties;
import org.mapstruct.ap.testutil.IssueKey; import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.ProcessorTest;
import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.WithClasses;
@ -18,7 +19,7 @@ import org.mapstruct.ap.testutil.runner.GeneratedSource;
* *
*/ */
@IssueKey( "424" ) @IssueKey( "424" )
@WithClasses( SimpleMapper.class ) @WithClasses( { SimpleMapper.class, WithProperties.class } )
public class VersionInfoTest { public class VersionInfoTest {
@RegisterExtension @RegisterExtension
final GeneratedSource generatedSource = new GeneratedSource(); final GeneratedSource generatedSource = new GeneratedSource();

View File

@ -58,6 +58,8 @@ public class SubclassAbstractMapperImpl implements SubclassAbstractMapper {
SubTarget subTarget = new SubTarget(); SubTarget subTarget = new SubTarget();
subTarget.setParentValue( subSource.getParentValue() );
subTarget.setImplementedParentValue( subSource.getImplementedParentValue() );
subTarget.setValue( subSource.getValue() ); subTarget.setValue( subSource.getValue() );
return subTarget; return subTarget;
@ -74,6 +76,9 @@ public class SubclassAbstractMapperImpl implements SubclassAbstractMapper {
SubTargetOther subTargetOther = new SubTargetOther( finalValue ); SubTargetOther subTargetOther = new SubTargetOther( finalValue );
subTargetOther.setParentValue( subSourceOther.getParentValue() );
subTargetOther.setImplementedParentValue( subSourceOther.getImplementedParentValue() );
return subTargetOther; return subTargetOther;
} }
@ -88,6 +93,9 @@ public class SubclassAbstractMapperImpl implements SubclassAbstractMapper {
SubSourceSeparate subSourceSeparate = new SubSourceSeparate( separateValue ); SubSourceSeparate subSourceSeparate = new SubSourceSeparate( separateValue );
subSourceSeparate.setParentValue( subTargetSeparate.getParentValue() );
subSourceSeparate.setImplementedParentValue( subTargetSeparate.getImplementedParentValue() );
return subSourceSeparate; return subSourceSeparate;
} }
@ -102,6 +110,9 @@ public class SubclassAbstractMapperImpl implements SubclassAbstractMapper {
SubSourceOverride subSourceOverride = new SubSourceOverride( finalValue ); SubSourceOverride subSourceOverride = new SubSourceOverride( finalValue );
subSourceOverride.setParentValue( subTargetOther.getParentValue() );
subSourceOverride.setImplementedParentValue( subTargetOther.getImplementedParentValue() );
return subSourceOverride; return subSourceOverride;
} }
@ -112,6 +123,8 @@ public class SubclassAbstractMapperImpl implements SubclassAbstractMapper {
SubSource subSource = new SubSource(); SubSource subSource = new SubSource();
subSource.setParentValue( subTarget.getParentValue() );
subSource.setImplementedParentValue( subTarget.getImplementedParentValue() );
subSource.setValue( subTarget.getValue() ); subSource.setValue( subTarget.getValue() );
return subSource; return subSource;

View File

@ -29,6 +29,9 @@ public class SubclassImplementedMapperImpl implements SubclassImplementedMapper
else { else {
ImplementedParentTarget implementedParentTarget = new ImplementedParentTarget(); ImplementedParentTarget implementedParentTarget = new ImplementedParentTarget();
implementedParentTarget.setParentValue( item.getParentValue() );
implementedParentTarget.setImplementedParentValue( item.getImplementedParentValue() );
return implementedParentTarget; return implementedParentTarget;
} }
} }
@ -40,6 +43,8 @@ public class SubclassImplementedMapperImpl implements SubclassImplementedMapper
SubTarget subTarget = new SubTarget(); SubTarget subTarget = new SubTarget();
subTarget.setParentValue( subSource.getParentValue() );
subTarget.setImplementedParentValue( subSource.getImplementedParentValue() );
subTarget.setValue( subSource.getValue() ); subTarget.setValue( subSource.getValue() );
return subTarget; return subTarget;
@ -56,6 +61,9 @@ public class SubclassImplementedMapperImpl implements SubclassImplementedMapper
SubTargetOther subTargetOther = new SubTargetOther( finalValue ); SubTargetOther subTargetOther = new SubTargetOther( finalValue );
subTargetOther.setParentValue( subSourceOther.getParentValue() );
subTargetOther.setImplementedParentValue( subSourceOther.getImplementedParentValue() );
return subTargetOther; return subTargetOther;
} }
} }

View File

@ -38,6 +38,8 @@ public class SubclassInterfaceMapperImpl implements SubclassInterfaceMapper {
SubTarget subTarget = new SubTarget(); SubTarget subTarget = new SubTarget();
subTarget.setParentValue( subSource.getParentValue() );
subTarget.setImplementedParentValue( subSource.getImplementedParentValue() );
subTarget.setValue( subSource.getValue() ); subTarget.setValue( subSource.getValue() );
return subTarget; return subTarget;
@ -54,6 +56,9 @@ public class SubclassInterfaceMapperImpl implements SubclassInterfaceMapper {
SubTargetOther subTargetOther = new SubTargetOther( finalValue ); SubTargetOther subTargetOther = new SubTargetOther( finalValue );
subTargetOther.setParentValue( subSourceOther.getParentValue() );
subTargetOther.setImplementedParentValue( subSourceOther.getImplementedParentValue() );
return subTargetOther; return subTargetOther;
} }
} }