diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/MethodRetrievalProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/MethodRetrievalProcessor.java index 4ad531d33..6f1febae9 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/MethodRetrievalProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/MethodRetrievalProcessor.java @@ -28,6 +28,7 @@ import org.mapstruct.ap.internal.gem.MappingsGem; import org.mapstruct.ap.internal.gem.ObjectFactoryGem; import org.mapstruct.ap.internal.gem.SubclassMappingGem; import org.mapstruct.ap.internal.gem.SubclassMappingsGem; +import org.mapstruct.ap.internal.gem.TargetPropertyNameGem; import org.mapstruct.ap.internal.gem.ValueMappingGem; import org.mapstruct.ap.internal.gem.ValueMappingsGem; import org.mapstruct.ap.internal.model.common.Parameter; @@ -230,7 +231,7 @@ public class MethodRetrievalProcessor implements ModelElementProcessor parameters, Type returnType) { + for ( Parameter param : parameters ) { + if ( param.isTargetPropertyName() && !param.getType().isString() ) { + messager.printMessage( + param.getElement(), + TargetPropertyNameGem.instanceOn( param.getElement() ).mirror(), + Message.RETRIEVAL_TARGET_PROPERTY_NAME_WRONG_TYPE + ); + return false; + } + } return isBoolean( returnType ) && hasConditionAnnotation( method ); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/Message.java b/processor/src/main/java/org/mapstruct/ap/internal/util/Message.java index 249825ec5..a24a43036 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/Message.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/Message.java @@ -176,6 +176,7 @@ public enum Message { RETRIEVAL_MAPPER_USES_CYCLE( "The mapper %s is referenced itself in Mapper#uses.", Diagnostic.Kind.WARNING ), RETRIEVAL_AFTER_METHOD_NOT_IMPLEMENTED( "@AfterMapping can only be applied to an implemented method." ), RETRIEVAL_BEFORE_METHOD_NOT_IMPLEMENTED( "@BeforeMapping can only be applied to an implemented method." ), + RETRIEVAL_TARGET_PROPERTY_NAME_WRONG_TYPE( "@TargetPropertyName can only by applied to a String parameter." ), INHERITINVERSECONFIGURATION_DUPLICATES( "Several matching inverse methods exist: %s(). Specify a name explicitly." ), INHERITINVERSECONFIGURATION_INVALID_NAME( "None of the candidates %s() matches given name: \"%s\"." ), diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/targetpropertyname/ErroneousNonStringTargetPropertyNameParameter.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/targetpropertyname/ErroneousNonStringTargetPropertyNameParameter.java new file mode 100644 index 000000000..ec545a058 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/targetpropertyname/ErroneousNonStringTargetPropertyNameParameter.java @@ -0,0 +1,21 @@ +/* + * 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.conditional.targetpropertyname; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.TargetPropertyName; + +@Mapper +public interface ErroneousNonStringTargetPropertyNameParameter { + + Employee map(EmployeeDto employee); + + @Condition + default boolean isNotBlank(String value, @TargetPropertyName int propName) { + return value != null && !value.trim().isEmpty(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/targetpropertyname/TargetPropertyNameTest.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/targetpropertyname/TargetPropertyNameTest.java index 3d96e6666..91e4b77de 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conditional/targetpropertyname/TargetPropertyNameTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/targetpropertyname/TargetPropertyNameTest.java @@ -9,6 +9,9 @@ import org.junit.jupiter.api.extension.RegisterExtension; 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; import org.mapstruct.ap.testutil.runner.GeneratedSource; import java.util.Collections; @@ -278,4 +281,24 @@ public class TargetPropertyNameTest { "addresses.street" ); } + + @IssueKey("2863") + @ProcessorTest + @WithClasses({ + ErroneousNonStringTargetPropertyNameParameter.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousNonStringTargetPropertyNameParameter.class, + line = 18, + message = "@TargetPropertyName can only by applied to a String parameter." + ) + } + ) + public void nonStringTargetPropertyNameParameter() { + + } }