From 6badd0af93476b48dd98627ca2bcf74b1519a2b7 Mon Sep 17 00:00:00 2001 From: Hyeonmin Park Date: Mon, 14 Feb 2022 21:43:12 +0900 Subject: [PATCH 1/4] Support Lombok --- build.gradle | 2 +- .../codeinsight/references/MapstructTargetReference.java | 7 +++++++ .../java/org/mapstruct/intellij/util/TargetUtils.java | 4 ++-- ...hKotlin.xml => org.mapstruct.intellij-withKotlin.xml} | 0 .../META-INF/org.mapstruct.intellij-withLombok.xml | 9 +++++++++ src/main/resources/META-INF/plugin.xml | 3 ++- 6 files changed, 21 insertions(+), 4 deletions(-) rename src/main/resources/META-INF/{withKotlin.xml => org.mapstruct.intellij-withKotlin.xml} (100%) create mode 100644 src/main/resources/META-INF/org.mapstruct.intellij-withLombok.xml diff --git a/build.gradle b/build.gradle index 381dc108..b414b059 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ intellij { pluginName = 'MapStruct-Intellij-Plugin' // The properties plugin is needed because Kotlin uses it // and for some reason plugins does not transitively pull itx - plugins = ['java', 'Kotlin', 'properties'] + plugins = ['java', 'Kotlin', 'properties', 'lombok'] } // Simple function to load change-notes.html and description.html into valid text for plugin.xml 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 ab2eb495..a4c8e3cd 100644 --- a/src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructTargetReference.java +++ b/src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructTargetReference.java @@ -21,6 +21,7 @@ import com.intellij.psi.PsiType; import com.intellij.psi.PsiVariable; import com.intellij.psi.util.PsiUtil; +import de.plushnikov.intellij.plugin.psi.LombokLightMethodBuilder; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.mapstruct.intellij.util.MapStructVersion; @@ -86,6 +87,12 @@ builderSupportPresent && isBuilderEnabled( getMappingMethod() ) if ( constructor != null && constructor.hasParameters() ) { for ( PsiParameter parameter : constructor.getParameterList().getParameters() ) { if ( value.equals( parameter.getName() ) ) { + if ( constructor instanceof LombokLightMethodBuilder ) { + PsiField field = psiClass.findFieldByName( value, true ); + if ( field != null ) { + return field; + } + } return parameter; } } diff --git a/src/main/java/org/mapstruct/intellij/util/TargetUtils.java b/src/main/java/org/mapstruct/intellij/util/TargetUtils.java index 8e51b4c1..fc095422 100644 --- a/src/main/java/org/mapstruct/intellij/util/TargetUtils.java +++ b/src/main/java/org/mapstruct/intellij/util/TargetUtils.java @@ -223,8 +223,8 @@ public static PsiMethod resolveMappingConstructor(@NotNull PsiClass psiClass) { List accessibleConstructors = new ArrayList<>(constructors.length); for ( PsiMethod constructor : constructors ) { - if ( constructor.hasModifier( JvmModifier.PRIVATE ) ) { - // private constructors are ignored + if ( constructor.hasModifier( JvmModifier.PRIVATE ) || constructor.hasModifier( JvmModifier.PROTECTED ) ) { + // private and protected constructors are ignored continue; } if ( !constructor.hasParameters() ) { diff --git a/src/main/resources/META-INF/withKotlin.xml b/src/main/resources/META-INF/org.mapstruct.intellij-withKotlin.xml similarity index 100% rename from src/main/resources/META-INF/withKotlin.xml rename to src/main/resources/META-INF/org.mapstruct.intellij-withKotlin.xml diff --git a/src/main/resources/META-INF/org.mapstruct.intellij-withLombok.xml b/src/main/resources/META-INF/org.mapstruct.intellij-withLombok.xml new file mode 100644 index 00000000..fb15428b --- /dev/null +++ b/src/main/resources/META-INF/org.mapstruct.intellij-withLombok.xml @@ -0,0 +1,9 @@ + + + diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 7963dd71..86814f77 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -29,7 +29,8 @@ com.intellij.modules.java - org.jetbrains.kotlin + org.jetbrains.kotlin + Lombook Plugin From 9a212c8bbcbd59bd95681c42bfd624deeeaafbfe Mon Sep 17 00:00:00 2001 From: Hyeonmin Park Date: Tue, 15 Feb 2022 00:15:21 +0900 Subject: [PATCH 2/4] Fix plugin repository link in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ccd3045f..6989a07b 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ The MapStruct plugin requires Java 11 or later ## Building from Source -Since the project has been migrated to the Gradle and [Gradle IntelliJ plugin][gradle-intellij-plugin], +Since the project has been migrated to the Gradle and [Gradle IntelliJ plugin](https://github.com/JetBrains/gradle-intellij-plugin), the build process is much simpler. The only thing to build the plugin is to run: ./gradlew build From 5762b8dc3449bef2568b34d262acf5087cb96d82 Mon Sep 17 00:00:00 2001 From: Hyeonmin Park Date: Thu, 8 Dec 2022 10:04:16 +0900 Subject: [PATCH 3/4] Fix format from supporting language injection for field --- .../mapstruct/intellij/expression/JavaExpressionInjector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/mapstruct/intellij/expression/JavaExpressionInjector.java b/src/main/java/org/mapstruct/intellij/expression/JavaExpressionInjector.java index 9c0e0c2b..812f853e 100644 --- a/src/main/java/org/mapstruct/intellij/expression/JavaExpressionInjector.java +++ b/src/main/java/org/mapstruct/intellij/expression/JavaExpressionInjector.java @@ -182,7 +182,7 @@ public void getLanguagesToInject(@NotNull MultiHostRegistrar registrar, @NotNull else if ( resolved instanceof PsiParameter ) { targetType = ( (PsiParameter) resolved ).getType(); } - else if ( resolved instanceof PsiField) { + else if ( resolved instanceof PsiField ) { targetType = ( (PsiField) resolved ).getType(); } } From 05a6f675c691d65924bc23407d489cb232d3b5bb Mon Sep 17 00:00:00 2001 From: Filip Hrisafov Date: Sun, 23 Apr 2023 21:27:10 +0200 Subject: [PATCH 4/4] Support lombok without a dependency on the plugin --- build.gradle | 2 +- .../references/MapstructSourceReference.java | 3 +- .../references/MapstructTargetReference.java | 14 ++--- .../mapstruct/intellij/util/LombokUtil.java | 56 +++++++++++++++++++ .../org.mapstruct.intellij-withLombok.xml | 9 --- src/main/resources/META-INF/plugin.xml | 1 - 6 files changed, 63 insertions(+), 22 deletions(-) create mode 100644 src/main/java/org/mapstruct/intellij/util/LombokUtil.java delete mode 100644 src/main/resources/META-INF/org.mapstruct.intellij-withLombok.xml diff --git a/build.gradle b/build.gradle index b414b059..381dc108 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ intellij { pluginName = 'MapStruct-Intellij-Plugin' // The properties plugin is needed because Kotlin uses it // and for some reason plugins does not transitively pull itx - plugins = ['java', 'Kotlin', 'properties', 'lombok'] + plugins = ['java', 'Kotlin', 'properties'] } // Simple function to load change-notes.html and description.html into valid text for plugin.xml diff --git a/src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructSourceReference.java b/src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructSourceReference.java index 11a8f40f..16cd7f3b 100644 --- a/src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructSourceReference.java +++ b/src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructSourceReference.java @@ -19,6 +19,7 @@ import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.mapstruct.intellij.util.LombokUtil; import org.mapstruct.intellij.util.MapstructUtil; import java.util.Objects; @@ -68,7 +69,7 @@ PsiElement resolveInternal(@NotNull String value, @NotNull PsiType psiType) { methods = psiClass.findMethodsByName( "is" + MapstructUtil.capitalize( value ), true ); } if ( methods.length > 0 && isPublicNonStatic( methods[0] ) ) { - return methods[0]; + return LombokUtil.resolvePsiElementForMethod( methods[0], value, psiClass ); } PsiField field = psiClass.findFieldByName( value, true ); 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 a4c8e3cd..b15c7fb1 100644 --- a/src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructTargetReference.java +++ b/src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructTargetReference.java @@ -21,9 +21,9 @@ import com.intellij.psi.PsiType; import com.intellij.psi.PsiVariable; import com.intellij.psi.util.PsiUtil; -import de.plushnikov.intellij.plugin.psi.LombokLightMethodBuilder; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.mapstruct.intellij.util.LombokUtil; import org.mapstruct.intellij.util.MapStructVersion; import org.mapstruct.intellij.util.MapstructUtil; import org.mapstruct.intellij.util.TargetType; @@ -87,13 +87,7 @@ builderSupportPresent && isBuilderEnabled( getMappingMethod() ) if ( constructor != null && constructor.hasParameters() ) { for ( PsiParameter parameter : constructor.getParameterList().getParameters() ) { if ( value.equals( parameter.getName() ) ) { - if ( constructor instanceof LombokLightMethodBuilder ) { - PsiField field = psiClass.findFieldByName( value, true ); - if ( field != null ) { - return field; - } - } - return parameter; + return LombokUtil.resolvePsiElement( constructor, parameter, value, psiClass ); } } } @@ -101,14 +95,14 @@ builderSupportPresent && isBuilderEnabled( getMappingMethod() ) PsiMethod[] methods = psiClass.findMethodsByName( "set" + MapstructUtil.capitalize( value ), true ); if ( methods.length != 0 && isPublicNonStatic( methods[0] ) ) { - return methods[0]; + return LombokUtil.resolvePsiElementForMethod( methods[0], value, psiClass ); } if ( builderSupportPresent ) { for ( PsiMethod method : psiClass.findMethodsByName( value, true ) ) { if ( method.getParameterList().getParametersCount() == 1 && MapstructUtil.isFluentSetter( method, typeToUse ) ) { - return method; + return LombokUtil.resolvePsiElementForMethod( method, value, psiClass ); } } } diff --git a/src/main/java/org/mapstruct/intellij/util/LombokUtil.java b/src/main/java/org/mapstruct/intellij/util/LombokUtil.java new file mode 100644 index 00000000..0a6069e4 --- /dev/null +++ b/src/main/java/org/mapstruct/intellij/util/LombokUtil.java @@ -0,0 +1,56 @@ +/* + * 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.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiMethod; + +/** + * @author Filip Hrisafov + */ +public final class LombokUtil { + + private static final Class LOMBOK_LIGHT_METHOD; + + static { + Class lombokLightMethod; + try { + lombokLightMethod = Class.forName( "de.plushnikov.intellij.plugin.psi.LombokLightMethodBuilder" ); + } + catch ( ClassNotFoundException e ) { + lombokLightMethod = null; + } + LOMBOK_LIGHT_METHOD = lombokLightMethod; + } + + private LombokUtil() { + } + + public static boolean isLombokLightMethod(PsiMethod method) { + if ( LOMBOK_LIGHT_METHOD != null ) { + return LOMBOK_LIGHT_METHOD.isInstance( method ); + } + return false; + } + + public static PsiElement resolvePsiElementForMethod(PsiMethod method, String value, PsiClass psiClass) { + return resolvePsiElement( method, method, value, psiClass ); + } + + public static PsiElement resolvePsiElement(PsiMethod method, PsiElement currentResolved, String value, + PsiClass psiClass) { + if ( isLombokLightMethod( method ) ) { + PsiField field = psiClass.findFieldByName( value, true ); + if ( field != null ) { + return field; + } + } + + return currentResolved; + } +} diff --git a/src/main/resources/META-INF/org.mapstruct.intellij-withLombok.xml b/src/main/resources/META-INF/org.mapstruct.intellij-withLombok.xml deleted file mode 100644 index fb15428b..00000000 --- a/src/main/resources/META-INF/org.mapstruct.intellij-withLombok.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 86814f77..41547b85 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -30,7 +30,6 @@ on how to target different products --> com.intellij.modules.java org.jetbrains.kotlin - Lombook Plugin