From 2bb2aefed8957861bf297b8f953b40e8753a8c75 Mon Sep 17 00:00:00 2001 From: Muhammad Usama Date: Fri, 24 Nov 2023 10:34:15 +0500 Subject: [PATCH] #3413 Using Mapping#expression and Mapping#conditionaQualifiedBy(Name) should lead to compile error --- copyright.txt | 1 + .../internal/model/source/MappingOptions.java | 5 ++- .../mapstruct/ap/internal/util/Message.java | 1 + .../test/bugs/_3413/Erroneous3413Mapper.java | 45 +++++++++++++++++++ .../ap/test/bugs/_3413/Issue3413Test.java | 35 +++++++++++++++ 5 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_3413/Erroneous3413Mapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/bugs/_3413/Issue3413Test.java diff --git a/copyright.txt b/copyright.txt index d6dc8d1b8..71d47a796 100644 --- a/copyright.txt +++ b/copyright.txt @@ -42,6 +42,7 @@ Kevin Grüneberg - https://github.com/kevcodez Lukas Lazar - https://github.com/LukeLaz Nikolas Charalambidis - https://github.com/Nikolas-Charalambidis Michael Pardo - https://github.com/pardom +Muhammad Usama - https://github.com/the-mgi Mustafa Caylak - https://github.com/luxmeter Oliver Ehrenmüller - https://github.com/greuelpirat Oliver Erhart - https://github.com/thunderhook diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/MappingOptions.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MappingOptions.java index 2af1c95f7..dd5b2f17b 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/MappingOptions.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MappingOptions.java @@ -207,10 +207,13 @@ public class MappingOptions extends DelegatingOptions { if ( gem.source().hasValue() && gem.constant().hasValue() ) { message = Message.PROPERTYMAPPING_SOURCE_AND_CONSTANT_BOTH_DEFINED; } + else if ( gem.expression().hasValue() && gem.conditionQualifiedByName().hasValue() ) { + message = Message.PROPERTYMAPPING_EXPRESSION_AND_CONDITION_QUALIFIED_BY_NAME_BOTH_DEFINED; + } else if ( gem.source().hasValue() && gem.expression().hasValue() ) { message = Message.PROPERTYMAPPING_SOURCE_AND_EXPRESSION_BOTH_DEFINED; } - else if (gem.expression().hasValue() && gem.constant().hasValue() ) { + else if ( gem.expression().hasValue() && gem.constant().hasValue() ) { message = Message.PROPERTYMAPPING_EXPRESSION_AND_CONSTANT_BOTH_DEFINED; } else if ( gem.expression().hasValue() && gem.defaultValue().hasValue() ) { 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 a24a43036..4b4331539 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 @@ -84,6 +84,7 @@ public enum Message { PROPERTYMAPPING_CANNOT_DETERMINE_SOURCE_PROPERTY_FROM_TARGET("The type of parameter \"%s\" has no property named \"%s\". Please define the source property 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_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." ), 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." ), diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3413/Erroneous3413Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3413/Erroneous3413Mapper.java new file mode 100644 index 000000000..784e47b8e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3413/Erroneous3413Mapper.java @@ -0,0 +1,45 @@ +/* + * 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.bugs._3413; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Muhammad Usama + */ +@Mapper +public interface Erroneous3413Mapper { + Erroneous3413Mapper INSTANCE = Mappers.getMapper( Erroneous3413Mapper.class ); + + @Mapping(target = "", expression = "", conditionQualifiedByName = "") + ToPOJO map(FromPOJO fromPOJO); + + class FromPOJO { + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + class ToPOJO { + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3413/Issue3413Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3413/Issue3413Test.java new file mode 100644 index 000000000..f98ed9cdb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3413/Issue3413Test.java @@ -0,0 +1,35 @@ +/* + * 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.bugs._3413; + +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; + +/** + * @author Muhammad Usama + */ +@IssueKey("3413") +public class Issue3413Test { + @ProcessorTest + @WithClasses(Erroneous3413Mapper.class) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 19, + message = "Expression and condition qualified by name are both defined in @Mapping, " + + "either define an expression or a condition qualified by name." + ) + } + ) + void errorExpectedBecauseExpressionAndConditionQualifiedByNameCannotCoExists() { + } +}