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 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 ab2eb495..b15c7fb1 100644 --- a/src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructTargetReference.java +++ b/src/main/java/org/mapstruct/intellij/codeinsight/references/MapstructTargetReference.java @@ -23,6 +23,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.MapStructVersion; import org.mapstruct.intellij.util.MapstructUtil; import org.mapstruct.intellij.util.TargetType; @@ -86,7 +87,7 @@ builderSupportPresent && isBuilderEnabled( getMappingMethod() ) if ( constructor != null && constructor.hasParameters() ) { for ( PsiParameter parameter : constructor.getParameterList().getParameters() ) { if ( value.equals( parameter.getName() ) ) { - return parameter; + return LombokUtil.resolvePsiElement( constructor, parameter, value, psiClass ); } } } @@ -94,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/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(); } } 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/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/plugin.xml b/src/main/resources/META-INF/plugin.xml index 7963dd71..41547b85 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -29,7 +29,7 @@ com.intellij.modules.java - org.jetbrains.kotlin + org.jetbrains.kotlin