mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-15 02:59:33 +07:00
[lombok] IDEA-333062 IDEA-255688 Added support for underscored (_) syntethic onX-Methods of lombok onX-Annotations
Reduced usages of custom HighlightErrorFilter GitOrigin-RevId: 7aa66eb9ecb9cc2e534015893d4701ab37d32f1c
This commit is contained in:
committed by
intellij-monorepo-bot
parent
8e8170ec3b
commit
61fe7a68b6
@@ -126,6 +126,7 @@ public final class AnnotationsHighlightUtil {
|
|||||||
}
|
}
|
||||||
PsiAnnotationMethod annotationMethod = ObjectUtils.tryCast(method, PsiAnnotationMethod.class);
|
PsiAnnotationMethod annotationMethod = ObjectUtils.tryCast(method, PsiAnnotationMethod.class);
|
||||||
if (annotationMethod == null) return null;
|
if (annotationMethod == null) return null;
|
||||||
|
if (!annotationMethod.isPhysical()) return null;
|
||||||
boolean fromDefaultValue = PsiTreeUtil.isAncestor(annotationMethod.getDefaultValue(), value, false);
|
boolean fromDefaultValue = PsiTreeUtil.isAncestor(annotationMethod.getDefaultValue(), value, false);
|
||||||
if (value instanceof PsiAnnotation) {
|
if (value instanceof PsiAnnotation) {
|
||||||
PsiJavaCodeReferenceElement nameRef = ((PsiAnnotation)value).getNameReferenceElement();
|
PsiJavaCodeReferenceElement nameRef = ((PsiAnnotation)value).getNameReferenceElement();
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package de.plushnikov.intellij.plugin.completion;
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.completion.CompletionContributor;
|
||||||
|
import com.intellij.codeInsight.completion.CompletionParameters;
|
||||||
|
import com.intellij.codeInsight.completion.CompletionResultSet;
|
||||||
|
import com.intellij.codeInsight.lookup.LookupElement;
|
||||||
|
import com.intellij.openapi.util.text.StringUtil;
|
||||||
|
import com.intellij.pom.java.LanguageLevel;
|
||||||
|
import com.intellij.psi.PsiClass;
|
||||||
|
import com.intellij.psi.PsiMethod;
|
||||||
|
import com.intellij.psi.util.PsiUtil;
|
||||||
|
import com.intellij.util.containers.ContainerUtil;
|
||||||
|
import de.plushnikov.intellij.plugin.LombokClassNames;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A completion contributor filter for Lombok onX-Annotations, and they default onX-Methods without underscore (_) at the end.
|
||||||
|
* These default methods can/should be used only for old JDKs like 1.7 From 1.8 synthetic underscored methods should be used.
|
||||||
|
* @see <a href="https://projectlombok.org/features/experimental/onX">Lombok onX-Documentation</a>
|
||||||
|
*/
|
||||||
|
public class LombokOnXCompletionContributorFilter extends CompletionContributor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
|
||||||
|
if (PsiUtil.getLanguageLevel(parameters.getPosition().getProject()).isLessThan(LanguageLevel.JDK_1_8)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.runRemainingContributors(parameters, completionResult -> {
|
||||||
|
LookupElement lookupElement = completionResult.getLookupElement();
|
||||||
|
if (shouldKeepItem(lookupElement)) {
|
||||||
|
result.passResult(completionResult);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean shouldKeepItem(LookupElement item) {
|
||||||
|
if (ONX_PARAMETERS.contains(item.getLookupString())) {
|
||||||
|
if (item.getPsiElement() instanceof PsiMethod psiMethod) {
|
||||||
|
final PsiClass containingClass = psiMethod.getContainingClass();
|
||||||
|
if (null != containingClass && containingClass.isAnnotationType()) {
|
||||||
|
if (ONXABLE_ANNOTATION_NAMES.contains(containingClass.getName())) {
|
||||||
|
return !ONXABLE_ANNOTATION_FQNS.contains(containingClass.getQualifiedName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Collection<String> ONX_PARAMETERS = Arrays.asList(
|
||||||
|
"onConstructor",
|
||||||
|
"onMethod",
|
||||||
|
"onParam"
|
||||||
|
);
|
||||||
|
|
||||||
|
private static final Collection<String> ONXABLE_ANNOTATION_FQNS = Arrays.asList(
|
||||||
|
LombokClassNames.GETTER,
|
||||||
|
LombokClassNames.SETTER,
|
||||||
|
LombokClassNames.WITH,
|
||||||
|
LombokClassNames.WITHER,
|
||||||
|
LombokClassNames.NO_ARGS_CONSTRUCTOR,
|
||||||
|
LombokClassNames.REQUIRED_ARGS_CONSTRUCTOR,
|
||||||
|
LombokClassNames.ALL_ARGS_CONSTRUCTOR,
|
||||||
|
LombokClassNames.EQUALS_AND_HASHCODE
|
||||||
|
);
|
||||||
|
private static final Collection<String> ONXABLE_ANNOTATION_NAMES = ContainerUtil.map(ONXABLE_ANNOTATION_FQNS, StringUtil::getShortName);
|
||||||
|
}
|
||||||
@@ -23,9 +23,6 @@ import java.util.regex.Pattern;
|
|||||||
public class LombokHighlightErrorFilter implements HighlightInfoFilter {
|
public class LombokHighlightErrorFilter implements HighlightInfoFilter {
|
||||||
|
|
||||||
private static final class Holder {
|
private static final class Holder {
|
||||||
static final Pattern LOMBOK_ANY_ANNOTATION_REQUIRED =
|
|
||||||
Pattern.compile(JavaErrorBundle.message("incompatible.types", "lombok.*AnyAnnotation\\[\\]", "__*"));
|
|
||||||
|
|
||||||
static final Map<HighlightSeverity, Map<TextAttributesKey, List<LombokHighlightFixHook>>> registeredHooks;
|
static final Map<HighlightSeverity, Map<TextAttributesKey, List<LombokHighlightFixHook>>> registeredHooks;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@@ -59,12 +56,9 @@ public class LombokHighlightErrorFilter implements HighlightInfoFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle rest cases
|
// handle rest cases
|
||||||
String description = highlightInfo.getDescription();
|
|
||||||
if (HighlightSeverity.ERROR.equals(highlightInfo.getSeverity())) {
|
if (HighlightSeverity.ERROR.equals(highlightInfo.getSeverity())) {
|
||||||
//Handling onX parameters
|
//Handling onX parameters
|
||||||
if (OnXAnnotationHandler.isOnXParameterAnnotation(highlightInfo, file)
|
if (OnXAnnotationHandler.isOnXParameterAnnotation(highlightInfo, file)) {
|
||||||
|| OnXAnnotationHandler.isOnXParameterValue(highlightInfo, file)
|
|
||||||
|| (description != null && Holder.LOMBOK_ANY_ANNOTATION_REQUIRED.matcher(description).matches())) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,12 +93,14 @@ public class LombokHighlightErrorFilter implements HighlightInfoFilter {
|
|||||||
@Override
|
@Override
|
||||||
public void processHook(@NotNull PsiElement highlightedElement, @NotNull HighlightInfo highlightInfo) {
|
public void processHook(@NotNull PsiElement highlightedElement, @NotNull HighlightInfo highlightInfo) {
|
||||||
PsiElement importantParent = PsiTreeUtil.getParentOfType(highlightedElement,
|
PsiElement importantParent = PsiTreeUtil.getParentOfType(highlightedElement,
|
||||||
PsiMethod.class, PsiLambdaExpression.class, PsiMethodReferenceExpression.class, PsiClassInitializer.class
|
PsiMethod.class, PsiLambdaExpression.class,
|
||||||
|
PsiMethodReferenceExpression.class, PsiClassInitializer.class
|
||||||
);
|
);
|
||||||
|
|
||||||
// applicable only for methods
|
// applicable only for methods
|
||||||
if (importantParent instanceof PsiMethod) {
|
if (importantParent instanceof PsiMethod) {
|
||||||
AddAnnotationFix fix = PsiQuickFixFactory.createAddAnnotationFix(LombokClassNames.SNEAKY_THROWS, (PsiModifierListOwner) importantParent);
|
AddAnnotationFix fix =
|
||||||
|
PsiQuickFixFactory.createAddAnnotationFix(LombokClassNames.SNEAKY_THROWS, (PsiModifierListOwner)importantParent);
|
||||||
highlightInfo.registerFix(fix, null, null, null, null);
|
highlightInfo.registerFix(fix, null, null, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -122,5 +118,4 @@ public class LombokHighlightErrorFilter implements HighlightInfoFilter {
|
|||||||
|
|
||||||
abstract public void processHook(@NotNull PsiElement highlightedElement, @NotNull HighlightInfo highlightInfo);
|
abstract public void processHook(@NotNull PsiElement highlightedElement, @NotNull HighlightInfo highlightInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,12 +12,11 @@ import java.util.regex.Pattern;
|
|||||||
|
|
||||||
|
|
||||||
public final class OnXAnnotationHandler {
|
public final class OnXAnnotationHandler {
|
||||||
private static final Pattern UNDERSCORES = Pattern.compile("__*");
|
private static final Pattern LOMBOK_ANY_ANNOTATION_REQUIRED =
|
||||||
private static final Pattern CANNOT_RESOLVE_SYMBOL_UNDERSCORES_MESSAGE = Pattern.compile(JavaErrorBundle.message("cannot.resolve.symbol", "__*"));
|
Pattern.compile(JavaErrorBundle.message("incompatible.types", "lombok.*AnyAnnotation\\[\\]", "__*"));
|
||||||
private static final Pattern CANNOT_RESOLVE_METHOD_UNDERSCORES_MESSAGE = Pattern.compile(JavaErrorBundle.message("cannot.resolve.method", "(onMethod|onConstructor|onParam)_+"));
|
private static final Pattern CANNOT_RESOLVE_SYMBOL_UNDERSCORES_MESSAGE =
|
||||||
|
Pattern.compile(JavaErrorBundle.message("cannot.resolve.symbol", "__*"));
|
||||||
private static final String ANNOTATION_TYPE_EXPECTED = JavaErrorBundle.message("annotation.annotation.type.expected");
|
private static final String ANNOTATION_TYPE_EXPECTED = JavaErrorBundle.message("annotation.annotation.type.expected");
|
||||||
private static final String CANNOT_FIND_METHOD_VALUE_MESSAGE = JavaErrorBundle.message("annotation.missing.method", "value");
|
|
||||||
|
|
||||||
private static final Collection<String> ONXABLE_ANNOTATIONS = Arrays.asList(
|
private static final Collection<String> ONXABLE_ANNOTATIONS = Arrays.asList(
|
||||||
LombokClassNames.GETTER,
|
LombokClassNames.GETTER,
|
||||||
@@ -38,8 +37,8 @@ public final class OnXAnnotationHandler {
|
|||||||
public static boolean isOnXParameterAnnotation(HighlightInfo highlightInfo, PsiFile file) {
|
public static boolean isOnXParameterAnnotation(HighlightInfo highlightInfo, PsiFile file) {
|
||||||
final String description = StringUtil.notNullize(highlightInfo.getDescription());
|
final String description = StringUtil.notNullize(highlightInfo.getDescription());
|
||||||
if (!(ANNOTATION_TYPE_EXPECTED.equals(description)
|
if (!(ANNOTATION_TYPE_EXPECTED.equals(description)
|
||||||
|| CANNOT_RESOLVE_SYMBOL_UNDERSCORES_MESSAGE.matcher(description).matches()
|
|| CANNOT_RESOLVE_SYMBOL_UNDERSCORES_MESSAGE.matcher(description).matches()
|
||||||
|| CANNOT_RESOLVE_METHOD_UNDERSCORES_MESSAGE.matcher(description).matches())) {
|
|| LOMBOK_ANY_ANNOTATION_REQUIRED.matcher(description).matches())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,22 +58,8 @@ public final class OnXAnnotationHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PsiElement containingAnnotation = nameValuePair.getContext().getContext();
|
PsiElement containingAnnotation = nameValuePair.getContext().getContext();
|
||||||
return containingAnnotation instanceof PsiAnnotation && ONXABLE_ANNOTATIONS.contains(((PsiAnnotation) containingAnnotation).getQualifiedName());
|
return containingAnnotation instanceof PsiAnnotation &&
|
||||||
}
|
ONXABLE_ANNOTATIONS.contains(((PsiAnnotation)containingAnnotation).getQualifiedName());
|
||||||
|
|
||||||
public static boolean isOnXParameterValue(HighlightInfo highlightInfo, PsiFile file) {
|
|
||||||
if (!CANNOT_FIND_METHOD_VALUE_MESSAGE.equals(highlightInfo.getDescription())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
PsiElement highlightedElement = file.findElementAt(highlightInfo.getStartOffset());
|
|
||||||
PsiNameValuePair nameValuePair = findContainingNameValuePair(highlightedElement);
|
|
||||||
if (nameValuePair == null || !(nameValuePair.getContext() instanceof PsiAnnotationParameterList)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
PsiElement leftSibling = nameValuePair.getContext().getPrevSibling();
|
|
||||||
return (leftSibling != null && UNDERSCORES.matcher(StringUtil.notNullize(leftSibling.getText())).matches());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PsiNameValuePair findContainingNameValuePair(PsiElement highlightedElement) {
|
private static PsiNameValuePair findContainingNameValuePair(PsiElement highlightedElement) {
|
||||||
@@ -83,6 +68,6 @@ public final class OnXAnnotationHandler {
|
|||||||
nameValuePair = nameValuePair.getContext();
|
nameValuePair = nameValuePair.getContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (PsiNameValuePair) nameValuePair;
|
return (PsiNameValuePair)nameValuePair;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package de.plushnikov.intellij.plugin.processor.lombok;
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.Pair;
|
||||||
|
import com.intellij.openapi.util.text.StringUtil;
|
||||||
|
import com.intellij.psi.PsiArrayType;
|
||||||
|
import com.intellij.psi.PsiClass;
|
||||||
|
import com.intellij.psi.PsiMethod;
|
||||||
|
import com.intellij.psi.PsiType;
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope;
|
||||||
|
import com.intellij.util.containers.ContainerUtil;
|
||||||
|
import de.plushnikov.intellij.plugin.psi.LombokLightAnnotationMethodBuilder;
|
||||||
|
import de.plushnikov.intellij.plugin.psi.LombokLightArrayInitializerMemberValue;
|
||||||
|
import de.plushnikov.intellij.plugin.psi.LombokLightMethodBuilder;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static de.plushnikov.intellij.plugin.LombokClassNames.*;
|
||||||
|
|
||||||
|
public final class LombokAnnotationProcessor {
|
||||||
|
private static final Map<String, Pair<Collection<String>, Collection<String>>> config = initializeConfig();
|
||||||
|
|
||||||
|
private static Map<String, Pair<Collection<String>, Collection<String>>> initializeConfig() {
|
||||||
|
return Map.of(
|
||||||
|
"onParam_", createAnnotationsPair(SETTER, EQUALS_AND_HASHCODE, WITH, WITHER),
|
||||||
|
"onMethod_", createAnnotationsPair(GETTER, SETTER, WITH, WITHER),
|
||||||
|
"onConstructor_", createAnnotationsPair(ALL_ARGS_CONSTRUCTOR, REQUIRED_ARGS_CONSTRUCTOR, NO_ARGS_CONSTRUCTOR)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Pair<Collection<String>, Collection<String>> createAnnotationsPair(String... fqns) {
|
||||||
|
Collection<String> fqnList = Arrays.asList(fqns);
|
||||||
|
Collection<String> shortNamesList = ContainerUtil.map(fqnList, StringUtil::getShortName);
|
||||||
|
return Pair.pair(shortNamesList, fqnList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static List<PsiMethod> process(@NotNull PsiClass psiClass, @Nullable String nameHint) {
|
||||||
|
if (nameHint != null && !ContainerUtil.exists(config.keySet(), nameHint::startsWith)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<PsiMethod> result = new ArrayList<>();
|
||||||
|
|
||||||
|
if (nameHint != null) {
|
||||||
|
final Pair<Collection<String>, Collection<String>> hintConfig = config.get(nameHint);
|
||||||
|
addAnnotationMethods(psiClass, hintConfig.getFirst(), hintConfig.getSecond(), nameHint, result);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (Map.Entry<String, Pair<Collection<String>, Collection<String>>> entry : config.entrySet()) {
|
||||||
|
addAnnotationMethods(psiClass, entry.getValue().getFirst(), entry.getValue().getSecond(), entry.getKey(), result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addAnnotationMethods(@NotNull PsiClass psiClass,
|
||||||
|
@NotNull Collection<String> onXAnnotationNames,
|
||||||
|
@NotNull Collection<String> onXAnnotationFQNs,
|
||||||
|
@NotNull String methodName,
|
||||||
|
@NotNull List<PsiMethod> result) {
|
||||||
|
if (onXAnnotationNames.contains(psiClass.getName()) && onXAnnotationFQNs.contains(psiClass.getQualifiedName())) {
|
||||||
|
result.add(createAnnotationMethod(psiClass, methodName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LombokLightMethodBuilder createAnnotationMethod(@NotNull PsiClass psiClass, @NotNull String methodName) {
|
||||||
|
final PsiType myAnnotationType =
|
||||||
|
PsiType.getJavaLangObject(psiClass.getManager(), GlobalSearchScope.projectScope(psiClass.getProject()));
|
||||||
|
return new LombokLightAnnotationMethodBuilder(psiClass.getManager(), methodName)
|
||||||
|
.withDefaultValue(new LombokLightArrayInitializerMemberValue(psiClass.getManager(), psiClass.getLanguage()))
|
||||||
|
.withContainingClass(psiClass)
|
||||||
|
.withMethodReturnType(new PsiArrayType(myAnnotationType));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,13 +5,18 @@ import com.intellij.psi.*;
|
|||||||
import com.intellij.psi.augment.PsiAugmentProvider;
|
import com.intellij.psi.augment.PsiAugmentProvider;
|
||||||
import com.intellij.psi.augment.PsiExtensionMethod;
|
import com.intellij.psi.augment.PsiExtensionMethod;
|
||||||
import com.intellij.psi.impl.source.PsiExtensibleClass;
|
import com.intellij.psi.impl.source.PsiExtensibleClass;
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope;
|
||||||
import com.siyeh.ig.psiutils.InitializationUtils;
|
import com.siyeh.ig.psiutils.InitializationUtils;
|
||||||
import de.plushnikov.intellij.plugin.LombokClassNames;
|
import de.plushnikov.intellij.plugin.LombokClassNames;
|
||||||
import de.plushnikov.intellij.plugin.processor.LombokProcessorManager;
|
import de.plushnikov.intellij.plugin.processor.LombokProcessorManager;
|
||||||
import de.plushnikov.intellij.plugin.processor.Processor;
|
import de.plushnikov.intellij.plugin.processor.Processor;
|
||||||
import de.plushnikov.intellij.plugin.processor.ValProcessor;
|
import de.plushnikov.intellij.plugin.processor.ValProcessor;
|
||||||
|
import de.plushnikov.intellij.plugin.processor.lombok.LombokAnnotationProcessor;
|
||||||
import de.plushnikov.intellij.plugin.processor.method.ExtensionMethodsHelper;
|
import de.plushnikov.intellij.plugin.processor.method.ExtensionMethodsHelper;
|
||||||
import de.plushnikov.intellij.plugin.processor.modifier.ModifierProcessor;
|
import de.plushnikov.intellij.plugin.processor.modifier.ModifierProcessor;
|
||||||
|
import de.plushnikov.intellij.plugin.psi.LombokLightAnnotationMethodBuilder;
|
||||||
|
import de.plushnikov.intellij.plugin.psi.LombokLightClassBuilder;
|
||||||
|
import de.plushnikov.intellij.plugin.psi.LombokLightMethodBuilder;
|
||||||
import de.plushnikov.intellij.plugin.util.PsiAnnotationSearchUtil;
|
import de.plushnikov.intellij.plugin.util.PsiAnnotationSearchUtil;
|
||||||
import de.plushnikov.intellij.plugin.util.PsiAnnotationUtil;
|
import de.plushnikov.intellij.plugin.util.PsiAnnotationUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -118,22 +123,26 @@ public class LombokAugmentProvider extends PsiAugmentProvider {
|
|||||||
@NotNull final Class<Psi> type,
|
@NotNull final Class<Psi> type,
|
||||||
@Nullable String nameHint) {
|
@Nullable String nameHint) {
|
||||||
final List<Psi> emptyResult = Collections.emptyList();
|
final List<Psi> emptyResult = Collections.emptyList();
|
||||||
if ((type != PsiClass.class && type != PsiField.class && type != PsiMethod.class) || !(element instanceof PsiExtensibleClass)
|
if (type != PsiClass.class && type != PsiField.class && type != PsiMethod.class || !(element instanceof PsiExtensibleClass psiClass)) {
|
||||||
|| (element instanceof PsiCompiledElement) // skip compiled classes
|
|
||||||
) {
|
|
||||||
return emptyResult;
|
return emptyResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
final PsiClass psiClass = (PsiClass)element;
|
|
||||||
if (!psiClass.getLanguage().isKindOf(JavaLanguage.INSTANCE)) {
|
if (!psiClass.getLanguage().isKindOf(JavaLanguage.INSTANCE)) {
|
||||||
return emptyResult;
|
return emptyResult;
|
||||||
}
|
}
|
||||||
// Skip processing of Annotations and Interfaces
|
|
||||||
|
// skip processing if disabled, or no lombok library is present
|
||||||
|
if (!hasLombokLibrary(element.getProject())) {
|
||||||
|
return emptyResult;
|
||||||
|
}
|
||||||
|
if (psiClass.isAnnotationType() && type == PsiMethod.class) {
|
||||||
|
return (List<Psi>)LombokAnnotationProcessor.process(psiClass, nameHint);
|
||||||
|
}
|
||||||
|
// Skip processing of other Annotations and Interfaces
|
||||||
if (psiClass.isAnnotationType() || psiClass.isInterface()) {
|
if (psiClass.isAnnotationType() || psiClass.isInterface()) {
|
||||||
return emptyResult;
|
return emptyResult;
|
||||||
}
|
}
|
||||||
// skip processing if disabled, or no lombok library is present
|
if (element instanceof PsiCompiledElement) { // skip compiled classes)
|
||||||
if (!hasLombokLibrary(element.getProject())) {
|
|
||||||
return emptyResult;
|
return emptyResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package de.plushnikov.intellij.plugin.psi;
|
||||||
|
|
||||||
|
import com.intellij.lang.Language;
|
||||||
|
import com.intellij.psi.PsiAnnotationMemberValue;
|
||||||
|
import com.intellij.psi.PsiManager;
|
||||||
|
import com.intellij.psi.SyntheticElement;
|
||||||
|
import com.intellij.psi.impl.light.LightElement;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class LombokLightAnnotationMemberValue extends LightElement implements PsiAnnotationMemberValue, SyntheticElement {
|
||||||
|
|
||||||
|
public LombokLightAnnotationMemberValue(@NotNull PsiManager manager,
|
||||||
|
@NotNull Language language) {
|
||||||
|
super(manager, language);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "LombokLightAnnotationMemberValue:" + getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package de.plushnikov.intellij.plugin.psi;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiAnnotationMemberValue;
|
||||||
|
import com.intellij.psi.PsiAnnotationMethod;
|
||||||
|
import com.intellij.psi.PsiManager;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class LombokLightAnnotationMethodBuilder extends LombokLightMethodBuilder implements PsiAnnotationMethod {
|
||||||
|
private PsiAnnotationMemberValue defaultValue;
|
||||||
|
|
||||||
|
public LombokLightAnnotationMethodBuilder(@NotNull PsiManager manager, @NotNull String name) {
|
||||||
|
super(manager, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LombokLightAnnotationMethodBuilder withDefaultValue(PsiAnnotationMemberValue defaultValue) {
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable PsiAnnotationMemberValue getDefaultValue() {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package de.plushnikov.intellij.plugin.psi;
|
||||||
|
|
||||||
|
import com.intellij.lang.Language;
|
||||||
|
import com.intellij.psi.PsiAnnotationMemberValue;
|
||||||
|
import com.intellij.psi.PsiArrayInitializerMemberValue;
|
||||||
|
import com.intellij.psi.PsiManager;
|
||||||
|
import com.intellij.psi.SyntheticElement;
|
||||||
|
import com.intellij.psi.impl.light.LightElement;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class LombokLightArrayInitializerMemberValue extends LightElement implements PsiArrayInitializerMemberValue, SyntheticElement {
|
||||||
|
|
||||||
|
public LombokLightArrayInitializerMemberValue(@NotNull PsiManager manager,
|
||||||
|
@NotNull Language language) {
|
||||||
|
super(manager, language);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "LombokLightArrayInitializerMemberValue:" + getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PsiAnnotationMemberValue @NotNull [] getInitializers() {
|
||||||
|
return PsiAnnotationMemberValue.EMPTY_ARRAY;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,6 +26,7 @@ public class LombokLightClassBuilder extends LightPsiClassBuilder implements Psi
|
|||||||
private final LombokLightModifierList myModifierList;
|
private final LombokLightModifierList myModifierList;
|
||||||
|
|
||||||
private boolean myIsEnum;
|
private boolean myIsEnum;
|
||||||
|
private boolean myIsAnnotationType;
|
||||||
private PsiField[] myFields;
|
private PsiField[] myFields;
|
||||||
private PsiMethod[] myMethods;
|
private PsiMethod[] myMethods;
|
||||||
|
|
||||||
@@ -35,6 +36,7 @@ public class LombokLightClassBuilder extends LightPsiClassBuilder implements Psi
|
|||||||
public LombokLightClassBuilder(@NotNull PsiElement context, @NotNull String simpleName, @NotNull String qualifiedName) {
|
public LombokLightClassBuilder(@NotNull PsiElement context, @NotNull String simpleName, @NotNull String qualifiedName) {
|
||||||
super(context, simpleName);
|
super(context, simpleName);
|
||||||
myIsEnum = false;
|
myIsEnum = false;
|
||||||
|
myIsAnnotationType = false;
|
||||||
myQualifiedName = qualifiedName;
|
myQualifiedName = qualifiedName;
|
||||||
myBaseIcon = LombokIcons.Nodes.LombokClass;
|
myBaseIcon = LombokIcons.Nodes.LombokClass;
|
||||||
myModifierList = new LombokLightModifierList(context.getManager(), context.getLanguage());
|
myModifierList = new LombokLightModifierList(context.getManager(), context.getLanguage());
|
||||||
@@ -91,6 +93,11 @@ public class LombokLightClassBuilder extends LightPsiClassBuilder implements Psi
|
|||||||
return myIsEnum;
|
return myIsEnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnnotationType() {
|
||||||
|
return myIsAnnotationType;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PsiField @NotNull [] getFields() {
|
public PsiField @NotNull [] getFields() {
|
||||||
if (null == myFields) {
|
if (null == myFields) {
|
||||||
@@ -141,6 +148,11 @@ public class LombokLightClassBuilder extends LightPsiClassBuilder implements Psi
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LombokLightClassBuilder withAnnotationType(boolean isAnnotationType) {
|
||||||
|
myIsAnnotationType = isAnnotationType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public LombokLightClassBuilder withImplicitModifier(@PsiModifier.ModifierConstant @NotNull @NonNls String modifier) {
|
public LombokLightClassBuilder withImplicitModifier(@PsiModifier.ModifierConstant @NotNull @NonNls String modifier) {
|
||||||
myModifierList.addImplicitModifierProperty(modifier);
|
myModifierList.addImplicitModifierProperty(modifier);
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
@@ -76,6 +76,8 @@
|
|||||||
<colorSettingsPage implementation="de.plushnikov.intellij.plugin.language.LombokConfigColorSettingsPage"/>
|
<colorSettingsPage implementation="de.plushnikov.intellij.plugin.language.LombokConfigColorSettingsPage"/>
|
||||||
<completion.contributor language="Lombok.Config"
|
<completion.contributor language="Lombok.Config"
|
||||||
implementationClass="de.plushnikov.intellij.plugin.language.LombokConfigCompletionContributor"/>
|
implementationClass="de.plushnikov.intellij.plugin.language.LombokConfigCompletionContributor"/>
|
||||||
|
|
||||||
|
<completion.contributor language="JAVA" implementationClass="de.plushnikov.intellij.plugin.completion.LombokOnXCompletionContributorFilter" order="first"/>
|
||||||
<lang.commenter language="Lombok.Config"
|
<lang.commenter language="Lombok.Config"
|
||||||
implementationClass="de.plushnikov.intellij.plugin.language.LombokConfigCommentor"/>
|
implementationClass="de.plushnikov.intellij.plugin.language.LombokConfigCommentor"/>
|
||||||
<fileBasedIndex implementation="de.plushnikov.intellij.plugin.lombokconfig.LombokConfigIndex"/>
|
<fileBasedIndex implementation="de.plushnikov.intellij.plugin.lombokconfig.LombokConfigIndex"/>
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ public class LombokHighlightingTest extends LightDaemonAnalyzerTestCase {
|
|||||||
doTest();
|
doTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testOnXExample() {
|
||||||
|
doTest();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package de.plushnikov.intellij.plugin.completion;
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.completion.CompletionType;
|
||||||
|
import com.intellij.ide.highlighter.JavaFileType;
|
||||||
|
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||||
|
import com.intellij.pom.java.LanguageLevel;
|
||||||
|
import de.plushnikov.intellij.plugin.AbstractLombokLightCodeInsightTestCase;
|
||||||
|
import org.intellij.lang.annotations.Language;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class LombokOnXCompletionContributorFilterTest extends AbstractLombokLightCodeInsightTestCase {
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testOnConstructorJdk7() {
|
||||||
|
LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_7);
|
||||||
|
testOnAnnotation("""
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
|
@AllArgsConstructor(<caret>)
|
||||||
|
public class OnXExample {
|
||||||
|
private final long unid;
|
||||||
|
}
|
||||||
|
""", Arrays.asList("access", "onConstructor", "onConstructor_", "staticName"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testOnConstructor() {
|
||||||
|
testOnAnnotation("""
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor(<caret>onConstructor_ = @Deprecated)
|
||||||
|
public class OnXExample {
|
||||||
|
private final long unid;
|
||||||
|
}
|
||||||
|
""", Arrays.asList("access", "onConstructor_", "staticName"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testOnMethod() {
|
||||||
|
testOnAnnotation("""
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
public class OnXExample {
|
||||||
|
@Getter(<caret>onMethod_ = {@Deprecated, @SuppressWarnings(value = "someId")})
|
||||||
|
private long unid;
|
||||||
|
}
|
||||||
|
""", Arrays.asList("lazy = true", "onMethod_", "value", "lazy = false"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testOnParam() {
|
||||||
|
testOnAnnotation("""
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
public class OnXExample {
|
||||||
|
@Setter(<caret>onMethod_ = @Deprecated, onParam_ = @SuppressWarnings(value ="someOtherId"))
|
||||||
|
private long unid;
|
||||||
|
}
|
||||||
|
""", Arrays.asList("onMethod_", "onParam_", "value"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testOnAnnotation(@Language("JAVA") String textInput, List<String> expected) {
|
||||||
|
myFixture.configureByText(JavaFileType.INSTANCE, textInput);
|
||||||
|
myFixture.complete(CompletionType.BASIC);
|
||||||
|
List<String> strings = myFixture.getLookupElementStrings();
|
||||||
|
assertSameElements(strings, expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
15
plugins/lombok/testData/highlighting/OnXExample.java
Normal file
15
plugins/lombok/testData/highlighting/OnXExample.java
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package highlighting;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
//@AllArgsConstructor(onConstructor_ = @Deprecated)
|
||||||
|
@AllArgsConstructor(onConstructor = @__( @Deprecated))
|
||||||
|
@RequiredArgsConstructor(onConstructor_ = @Deprecated)
|
||||||
|
public class OnXExample {
|
||||||
|
@Getter(onMethod_ = {@Deprecated, @SuppressWarnings(value = "someId")}) //JDK8
|
||||||
|
@Setter(onMethod_ = @Deprecated, onParam_ = @SuppressWarnings(value = "someOtherId")) //JDK8
|
||||||
|
private long unid;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user