diff --git a/build.gradle b/build.gradle index caca27a3..14094ceb 100644 --- a/build.gradle +++ b/build.gradle @@ -100,6 +100,7 @@ dependencies { testRuntimeOnly('org.junit.vintage:junit-vintage-engine') testImplementation('org.assertj:assertj-core:3.11.1') testImplementation('org.apache.commons:commons-text:1.10.0') + testRuntimeOnly('org.immutables:value:2.5.6') } task libs(type: Sync) { @@ -111,6 +112,12 @@ task libs(type: Sync) { rename 'mapstruct-1.5.3.Final.jar', 'mapstruct.jar' } +task testLibs(type: Sync) { + from configurations.testRuntimeClasspath + into "$buildDir/test-libs" + rename 'value-2.5.6.jar', 'immutables.jar' +} + def mockJdkLocation = "https://github.com/JetBrains/intellij-community/raw/master/java/mock" def mockJdkDest = "$buildDir/mock" def downloadMockJdk(mockJdkLocation, mockJdkDest, mockJdkVersion) { @@ -150,8 +157,8 @@ task downloadMockJdk11() { downloadMockJdk(mockJdkLocation, mockJdkDest, "JDK-11") } -test.dependsOn( libs, downloadMockJdk7, downloadMockJdk8, downloadMockJdk11 ) -prepareTestingSandbox.dependsOn( libs ) +test.dependsOn( libs, testLibs, downloadMockJdk7, downloadMockJdk8, downloadMockJdk11 ) +prepareTestingSandbox.dependsOn( libs, testLibs ) prepareSandbox.dependsOn( libs ) test { diff --git a/src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructBaseReference.java b/src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructBaseReference.java index b2e93288..70c541e9 100644 --- a/src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructBaseReference.java +++ b/src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructBaseReference.java @@ -34,6 +34,7 @@ abstract class MapstructBaseReference extends BaseReference { private final MapstructBaseReference previous; private final String value; + protected final MapstructUtil mapstructUtil; /** * Create a reference. @@ -47,6 +48,7 @@ abstract class MapstructBaseReference extends BaseReference { super( element, rangeInElement ); this.previous = previous; this.value = value; + this.mapstructUtil = MapstructUtil.getInstance(element.getContainingFile()); } @Override diff --git a/src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructTargetReference.java b/src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructTargetReference.java index c78fffe8..307cbbf3 100644 --- a/src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructTargetReference.java +++ b/src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructTargetReference.java @@ -100,7 +100,7 @@ builderSupportPresent && isBuilderEnabled( getMappingMethod() ) if ( builderSupportPresent ) { for ( PsiMethod method : psiClass.findMethodsByName( value, true ) ) { if ( method.getParameterList().getParametersCount() == 1 && - MapstructUtil.isFluentSetter( method, typeToUse ) ) { + mapstructUtil.isFluentSetter( method, typeToUse ) ) { return method; } } @@ -140,7 +140,7 @@ PsiElement resolveInternal(@NotNull String value, @NotNull PsiMethod mappingMeth @Override Object[] getVariantsInternal(@NotNull PsiType psiType) { return asLookup( - publicWriteAccessors( psiType, mapStructVersion, getMappingMethod() ), + publicWriteAccessors( psiType, mapStructVersion, mapstructUtil, getMappingMethod() ), MapstructTargetReference::memberPsiType ); } diff --git a/src/main/java/org/mapstruct/intellij/inspection/UnmappedTargetPropertiesInspection.java b/src/main/java/org/mapstruct/intellij/inspection/UnmappedTargetPropertiesInspection.java index a85796a6..7dce5fb7 100644 --- a/src/main/java/org/mapstruct/intellij/inspection/UnmappedTargetPropertiesInspection.java +++ b/src/main/java/org/mapstruct/intellij/inspection/UnmappedTargetPropertiesInspection.java @@ -62,17 +62,19 @@ public class UnmappedTargetPropertiesInspection extends InspectionBase { @NotNull @Override PsiElementVisitor buildVisitorInternal(@NotNull ProblemsHolder holder, boolean isOnTheFly) { - return new MyJavaElementVisitor( holder, MapstructUtil.resolveMapStructProjectVersion( holder.getFile() ) ); + return new MyJavaElementVisitor( holder, MapstructUtil.resolveMapStructProjectVersion( holder.getFile() ), MapstructUtil.getInstance( holder.getFile() ) ); } private static class MyJavaElementVisitor extends JavaElementVisitor { private final ProblemsHolder holder; private final MapStructVersion mapStructVersion; + private final MapstructUtil mapstructUtil; - private MyJavaElementVisitor(ProblemsHolder holder, MapStructVersion mapStructVersion) { + private MyJavaElementVisitor(ProblemsHolder holder, MapStructVersion mapStructVersion, MapstructUtil mapstructUtil) { this.holder = holder; this.mapStructVersion = mapStructVersion; - } + this.mapstructUtil = mapstructUtil; + } @Override public void visitMethod(PsiMethod method) { @@ -92,7 +94,7 @@ public void visitMethod(PsiMethod method) { } - Set allTargetProperties = findAllTargetProperties( targetType, mapStructVersion, method ); + Set allTargetProperties = findAllTargetProperties( targetType, mapStructVersion, mapstructUtil, method ); // find and remove all defined mapping targets Set definedTargets = findAllDefinedMappingTargets( method, mapStructVersion ) diff --git a/src/main/java/org/mapstruct/intellij/util/DefaultMapstructUtil.java b/src/main/java/org/mapstruct/intellij/util/DefaultMapstructUtil.java new file mode 100644 index 00000000..b7766536 --- /dev/null +++ b/src/main/java/org/mapstruct/intellij/util/DefaultMapstructUtil.java @@ -0,0 +1,14 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.intellij.util; + +public class DefaultMapstructUtil extends MapstructUtil { + /** + * Hide constructor. + */ + protected DefaultMapstructUtil() { + } +} diff --git a/src/main/java/org/mapstruct/intellij/util/FreeBuildersMapstructUtil.java b/src/main/java/org/mapstruct/intellij/util/FreeBuildersMapstructUtil.java new file mode 100644 index 00000000..a21883d4 --- /dev/null +++ b/src/main/java/org/mapstruct/intellij/util/FreeBuildersMapstructUtil.java @@ -0,0 +1,40 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.intellij.util; + +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiType; +import org.jetbrains.annotations.NotNull; + +/** + * Mapstruct util for FreeBuilder. + * FreeBuilder adds a lot of other methods that can be considered as fluent setters. Such as: + *
    + *
  • {@code from(Target)}
  • + *
  • {@code mapXXX(UnaryOperator)}
  • + *
  • {@code mutateXXX(Consumer)}
  • + *
  • {@code mergeFrom(Target)}
  • + *
  • {@code mergeFrom(Target.Builder)}
  • + *
+ *

+ * When the JavaBean convention is not used with FreeBuilder then the getters are non-standard and MapStruct + * won't recognize them. Therefore, one needs to use the JavaBean convention in which the fluent setters + * start with {@code set}. + */ +public class FreeBuildersMapstructUtil extends MapstructUtil { + /** + * Hide constructor. + */ + protected FreeBuildersMapstructUtil() { + } + + @Override + public boolean isFluentSetter(@NotNull PsiMethod method, PsiType psiType) { + // When using FreeBuilder one needs to use the JavaBean convention, which means that all setters will start + // with set + return false; + } +} diff --git a/src/main/java/org/mapstruct/intellij/util/ImmutablesMapstructUtil.java b/src/main/java/org/mapstruct/intellij/util/ImmutablesMapstructUtil.java new file mode 100644 index 00000000..d253a05b --- /dev/null +++ b/src/main/java/org/mapstruct/intellij/util/ImmutablesMapstructUtil.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.intellij.util; + +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiType; +import org.jetbrains.annotations.NotNull; + +/** + * Mapstruct util for Immutables. + * The generated Immutables also have a from that works as a copy. Our default strategy considers this method + * as a setter with a name {@code from}. Therefore, we are ignoring it. + */ +public class ImmutablesMapstructUtil extends MapstructUtil { + /** + * Hide constructor. + */ + protected ImmutablesMapstructUtil() { + } + + @Override + public boolean isFluentSetter(@NotNull PsiMethod method, PsiType psiType) { + return super.isFluentSetter( method, psiType ) && !method.getName().equals( "from" ); + } +} diff --git a/src/main/java/org/mapstruct/intellij/util/MapstructUtil.java b/src/main/java/org/mapstruct/intellij/util/MapstructUtil.java index ad11535c..2c373fdd 100644 --- a/src/main/java/org/mapstruct/intellij/util/MapstructUtil.java +++ b/src/main/java/org/mapstruct/intellij/util/MapstructUtil.java @@ -70,7 +70,7 @@ /** * @author Filip Hrisafov */ -public final class MapstructUtil { +public class MapstructUtil { /** * The FQN of the {@link Mapper} annotation. @@ -100,11 +100,26 @@ public final class MapstructUtil { private static final String INHERIT_INVERSE_CONFIGURATION_FQN = InheritInverseConfiguration.class.getName(); private static final String BUILDER_ANNOTATION_FQN = Builder.class.getName(); private static final String ENUM_MAPPING_ANNOTATION_FQN = EnumMapping.class.getName(); + private static final String IMMUTABLE_FQN = "org.immutables.value.Value.Immutable"; + private static final String FREE_BUILDER_FQN = "org.inferred.freebuilder.FreeBuilder"; /** * Hide constructor. */ - private MapstructUtil() { + MapstructUtil() { + } + + public static MapstructUtil getInstance(@Nullable PsiFile psiFile) { + MapstructUtil mapstructUtil = new DefaultMapstructUtil(); + if (psiFile == null) { + return mapstructUtil; + } + if (MapstructUtil.immutablesOnClassPath(psiFile)) { + mapstructUtil = new ImmutablesMapstructUtil(); + } else if (MapstructUtil.freeBuilderOnClassPath(psiFile)) { + mapstructUtil = new FreeBuildersMapstructUtil(); + } + return mapstructUtil; } public static LookupElement[] asLookup(Map> accessors, @@ -140,7 +155,7 @@ public static LookupElement asLookup(PsiEnumConstant enumConstant) { } public static LookupElement asLookupWithRepresentableText(PsiMethod method, String lookupString, - String representableText, String tailText) { + String representableText, String tailText) { LookupElementBuilder builder = LookupElementBuilder.create( method, lookupString ) .withIcon( PlatformIcons.METHOD_ICON ) .withPresentableText( representableText ) @@ -203,7 +218,7 @@ public static boolean isPublicModifiable(@NotNull PsiField field) { !field.hasModifierProperty( PsiModifier.FINAL ); } - public static boolean isFluentSetter(@NotNull PsiMethod method, PsiType psiType) { + public boolean isFluentSetter(@NotNull PsiMethod method, PsiType psiType) { return !psiType.getCanonicalText().startsWith( "java.lang" ) && method.getReturnType() != null && !isAdderWithUpperCase4thCharacter( method ) && @@ -541,6 +556,36 @@ else if ( JavaPsiFacade.getInstance( module.getProject() ) } ); } + public static boolean immutablesOnClassPath(@NotNull PsiFile psiFile) { + Module module = ModuleUtilCore.findModuleForFile(psiFile.getVirtualFile(), psiFile.getProject()); + if (module == null) { + return false; + } + return CachedValuesManager.getManager(module.getProject()).getCachedValue(module, () -> { + boolean immutablesOnClassPath = JavaPsiFacade.getInstance(module.getProject()) + .findClass(IMMUTABLE_FQN, module.getModuleRuntimeScope(false)) != null; + return CachedValueProvider.Result.createSingleDependency( + immutablesOnClassPath, + ProjectRootManager.getInstance(module.getProject()) + ); + }); + } + + public static boolean freeBuilderOnClassPath(@NotNull PsiFile psiFile) { + Module module = ModuleUtilCore.findModuleForFile(psiFile.getVirtualFile(), psiFile.getProject()); + if (module == null) { + return false; + } + return CachedValuesManager.getManager(module.getProject()).getCachedValue(module, () -> { + boolean freeBuilderOnClassPath = JavaPsiFacade.getInstance(module.getProject()) + .findClass(FREE_BUILDER_FQN, module.getModuleRuntimeScope(false)) != null; + return CachedValueProvider.Result.createSingleDependency( + freeBuilderOnClassPath, + ProjectRootManager.getInstance(module.getProject()) + ); + }); + } + /** * Checks if MapStruct jdk8 is within the provided module. The MapStruct JDK 8 module is present when the * {@link Mapping} annotation is annotated with {@link java.lang.annotation.Repeatable} diff --git a/src/main/java/org/mapstruct/intellij/util/TargetUtils.java b/src/main/java/org/mapstruct/intellij/util/TargetUtils.java index 2a6d2fbb..cc7612ce 100644 --- a/src/main/java/org/mapstruct/intellij/util/TargetUtils.java +++ b/src/main/java/org/mapstruct/intellij/util/TargetUtils.java @@ -47,7 +47,6 @@ import static org.mapstruct.intellij.util.MapstructUtil.INHERIT_CONFIGURATION_FQN; import static org.mapstruct.intellij.util.MapstructUtil.MAPPER_ANNOTATION_FQN; import static org.mapstruct.intellij.util.MapstructUtil.canDescendIntoType; -import static org.mapstruct.intellij.util.MapstructUtil.isFluentSetter; import static org.mapstruct.intellij.util.MapstructUtil.publicFields; /** @@ -98,7 +97,7 @@ public static PsiType getRelevantType(@NotNull PsiMethod mappingMethod) { * @return a stream that holds all public write accessors for the given {@code psiType} */ public static Map> publicWriteAccessors(@NotNull PsiType psiType, - MapStructVersion mapStructVersion, PsiMethod mappingMethod) { + MapStructVersion mapStructVersion, MapstructUtil mapstructUtil, PsiMethod mappingMethod) { boolean builderSupportPresent = mapStructVersion.isBuilderSupported(); Pair classAndType = resolveBuilderOrSelfClass( psiType, @@ -114,7 +113,7 @@ builderSupportPresent && isBuilderEnabled( mappingMethod ) TargetType targetType = classAndType.getSecond(); PsiType typeToUse = targetType.type(); - publicWriteAccessors.putAll( publicSetters( psiClass, typeToUse, builderSupportPresent ) ); + publicWriteAccessors.putAll( publicSetters( psiClass, typeToUse, mapstructUtil, builderSupportPresent && isBuilderEnabled( mappingMethod ) ) ); publicWriteAccessors.putAll( publicFields( psiClass ) ); if ( mapStructVersion.isConstructorSupported() && !targetType.builder() ) { @@ -266,7 +265,7 @@ public static PsiMethod resolveMappingConstructor(@NotNull PsiClass psiClass) { * @return a stream that holds all public setters for the given {@code psiType} */ private static Map> publicSetters(@NotNull PsiClass psiClass, - @NotNull PsiType typeToUse, + @NotNull PsiType typeToUse, MapstructUtil mapstructUtil, boolean builderSupportPresent) { Set overriddenMethods = new HashSet<>(); Map> publicSetters = new LinkedHashMap<>(); @@ -275,7 +274,7 @@ private static Map> publicSett if ( method.isConstructor() ) { continue; } - String propertyName = extractPublicSetterPropertyName( method, typeToUse, builderSupportPresent ); + String propertyName = extractPublicSetterPropertyName( method, typeToUse, mapstructUtil, builderSupportPresent ); if ( propertyName != null && !overriddenMethods.contains( method ) ) { @@ -289,7 +288,7 @@ private static Map> publicSett } @Nullable - private static String extractPublicSetterPropertyName(PsiMethod method, @NotNull PsiType typeToUse, + private static String extractPublicSetterPropertyName(PsiMethod method, @NotNull PsiType typeToUse, MapstructUtil mapstructUtil, boolean builderSupportPresent) { if ( method.getParameterList().getParametersCount() != 1 || !MapstructUtil.isPublicNonStatic( method ) ) { // If the method does not have 1 parameter or is not public then there is no property @@ -299,7 +298,7 @@ private static String extractPublicSetterPropertyName(PsiMethod method, @NotNull // This logic is aligned with the DefaultAccessorNamingStrategy String methodName = method.getName(); if ( builderSupportPresent ) { - if ( isFluentSetter( method, typeToUse ) ) { + if ( mapstructUtil.isFluentSetter( method, typeToUse ) ) { if ( methodName.startsWith( "set" ) && methodName.length() > 3 && Character.isUpperCase( methodName.charAt( 3 ) ) ) { @@ -432,9 +431,9 @@ public static Stream findAllSourcePropertiesForCurrentTarget(@NotNull Ps * * @return all target properties for the given {@code targetClass} */ - public static Set findAllTargetProperties(@NotNull PsiType targetType, MapStructVersion mapStructVersion, + public static Set findAllTargetProperties(@NotNull PsiType targetType, MapStructVersion mapStructVersion, MapstructUtil mapstructUtil, PsiMethod mappingMethod) { - return publicWriteAccessors( targetType, mapStructVersion, mappingMethod ).keySet(); + return publicWriteAccessors( targetType, mapStructVersion, mapstructUtil, mappingMethod ).keySet(); } /** diff --git a/src/test/java/org/mapstruct/intellij/MapstructBaseCompletionTestCase.java b/src/test/java/org/mapstruct/intellij/MapstructBaseCompletionTestCase.java index 98e69929..525a3160 100644 --- a/src/test/java/org/mapstruct/intellij/MapstructBaseCompletionTestCase.java +++ b/src/test/java/org/mapstruct/intellij/MapstructBaseCompletionTestCase.java @@ -31,7 +31,8 @@ */ public abstract class MapstructBaseCompletionTestCase extends LightFixtureCompletionTestCase { - private static final String BUILD_LIBS_DIRECTORY = "build/libs"; + protected static final String BUILD_LIBS_DIRECTORY = "build/libs"; + protected static final String BUILD_TEST_LIBS_DIRECTORY = "build/test-libs"; private static final String BUILD_MOCK_JDK_DIRECTORY = "build/mockJDK-"; @Override diff --git a/src/test/java/org/mapstruct/intellij/inspection/UnmappedImmutablesFromTargetPropertiesInspectionTest.java b/src/test/java/org/mapstruct/intellij/inspection/UnmappedImmutablesFromTargetPropertiesInspectionTest.java new file mode 100644 index 00000000..7704022c --- /dev/null +++ b/src/test/java/org/mapstruct/intellij/inspection/UnmappedImmutablesFromTargetPropertiesInspectionTest.java @@ -0,0 +1,75 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.intellij.inspection; + +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.testFramework.PsiTestUtil; +import com.intellij.util.PathUtil; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Stephan Leicht Vogt + */ +public class UnmappedImmutablesFromTargetPropertiesInspectionTest extends BaseInspectionTest { + + @NotNull + @Override + protected Class getInspection() { + return UnmappedTargetPropertiesInspection.class; + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + final String immutablesLibPath = PathUtil.toSystemIndependentName( new File( BUILD_TEST_LIBS_DIRECTORY ) + .getAbsolutePath() ); + PsiTestUtil.addLibrary( + myFixture.getProjectDisposable(), + myFixture.getModule(), + "Immutables", + immutablesLibPath, + "immutables.jar" + ); + myFixture.copyFileToProject( + "UnmappedImmutablesFromTargetPropertiesData.java", + "org/example/data/UnmappedImmutablesFromTargetPropertiesData.java" + ); + } + + public void testUnmappedImmutablesFromTargetProperties() { + doTest(); + String testName = getTestName( false ); + List allQuickFixes = myFixture.getAllQuickFixes(); + + assertThat( allQuickFixes ) + .extracting( IntentionAction::getText ) + .as( "Intent Text" ) + .containsExactly( + "Ignore unmapped target property: 'builderTestName'", + "Add unmapped target property: 'builderTestName'", + + "Ignore unmapped target property: 'targetTestName'", + "Add unmapped target property: 'targetTestName'", + + "Ignore unmapped target property: 'targetTestName'", + "Add unmapped target property: 'targetTestName'", + + "Ignore unmapped target property: 'builderTestName'", + "Add unmapped target property: 'builderTestName'", + + "Ignore unmapped target property: 'targetTestName'", + "Add unmapped target property: 'targetTestName'" + ); + + allQuickFixes.forEach( myFixture::launchAction ); + myFixture.checkResultByFile( testName + "_after.java" ); + } +} diff --git a/testData/inspection/UnmappedImmutablesFromTargetProperties.java b/testData/inspection/UnmappedImmutablesFromTargetProperties.java new file mode 100644 index 00000000..2f1c7adb --- /dev/null +++ b/testData/inspection/UnmappedImmutablesFromTargetProperties.java @@ -0,0 +1,49 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +import org.mapstruct.BeanMapping; +import org.mapstruct.Builder; +import org.mapstruct.Mapper; +import org.mapstruct.MapperConfig; +import org.mapstruct.Mapping; +import org.example.data.UnmappedImmutablesFromTargetPropertiesData.Target; + +@Mapper +interface DefaultMapper { + + Target map(String source); +} + +@Mapper(builder = @Builder(disableBuilder = true)) +interface MapperDisabledBuilder { + + Target map(String source); +} + +@Mapper +interface BeanMappingDisabledBuilder { + + @BeanMapping(builder = @Builder(disableBuilder = true)) + Target map(String source); +} + +@Mapper(builder = @Builder(disableBuilder = true)) +interface MapperDisabledBuilderBeanMappingEnabledBuilder { + + @BeanMapping(builder = @Builder(disableBuilder = false)) + Target map(String source); +} + +@MapperConfig(builder = @Builder(disableBuilder = true)) +class DoNotUseBuilderMapperConfig { + +} + +@Mapper(config = DoNotUseBuilderMapperConfig.class) +interface MapperConfigDisabledBuilder { + + Target map(String source); +} diff --git a/testData/inspection/UnmappedImmutablesFromTargetPropertiesData.java b/testData/inspection/UnmappedImmutablesFromTargetPropertiesData.java new file mode 100644 index 00000000..17402b82 --- /dev/null +++ b/testData/inspection/UnmappedImmutablesFromTargetPropertiesData.java @@ -0,0 +1,43 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.example.data; + +public class UnmappedImmutablesFromTargetPropertiesData { + public static class Target { + + private String targetTestName; + + public String getTargetTestName() { + return targetTestName; + } + + public void setTargetTestName(String targetTestName) { + this.targetTestName = targetTestName; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + public final Builder from(Target instance) { + Objects.requireNonNull(instance, "instance"); + builderTestName(instance.getTargetTestName()); + return this; + } + + public Builder builderTestName(String testName) { + + } + + public Target build() { + return null; + } + } + } + +} diff --git a/testData/inspection/UnmappedImmutablesFromTargetProperties_after.java b/testData/inspection/UnmappedImmutablesFromTargetProperties_after.java new file mode 100644 index 00000000..abf17aa4 --- /dev/null +++ b/testData/inspection/UnmappedImmutablesFromTargetProperties_after.java @@ -0,0 +1,59 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +import org.mapstruct.BeanMapping; +import org.mapstruct.Builder; +import org.mapstruct.Mapper; +import org.mapstruct.MapperConfig; +import org.mapstruct.Mapping; +import org.example.data.UnmappedImmutablesFromTargetPropertiesData.Target; + +@Mapper +interface DefaultMapper { + + @Mapping(target = "builderTestName", source = "") + @Mapping(target = "builderTestName", ignore = true) + Target map(String source); +} + +@Mapper(builder = @Builder(disableBuilder = true)) +interface MapperDisabledBuilder { + + @Mapping(target = "targetTestName", source = "") + @Mapping(target = "targetTestName", ignore = true) + Target map(String source); +} + +@Mapper +interface BeanMappingDisabledBuilder { + + @Mapping(target = "targetTestName", source = "") + @Mapping(target = "targetTestName", ignore = true) + @BeanMapping(builder = @Builder(disableBuilder = true)) + Target map(String source); +} + +@Mapper(builder = @Builder(disableBuilder = true)) +interface MapperDisabledBuilderBeanMappingEnabledBuilder { + + @Mapping(target = "builderTestName", source = "") + @Mapping(target = "builderTestName", ignore = true) + @BeanMapping(builder = @Builder(disableBuilder = false)) + Target map(String source); +} + +@MapperConfig(builder = @Builder(disableBuilder = true)) +class DoNotUseBuilderMapperConfig { + +} + +@Mapper(config = DoNotUseBuilderMapperConfig.class) +interface MapperConfigDisabledBuilder { + + @Mapping(target = "targetTestName", source = "") + @Mapping(target = "targetTestName", ignore = true) + Target map(String source); +}