mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-15 11:53:49 +07:00
IDEA-305079 show usages for record fields using lombok @Builder and @With #2252
GitOrigin-RevId: fae916295f1a3cc40d759bf10a995446aa43a7ca
This commit is contained in:
committed by
intellij-monorepo-bot
parent
c072a65cd8
commit
2504ec6d32
@@ -6,6 +6,8 @@ import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiField;
|
||||
import com.intellij.psi.PsiMember;
|
||||
import com.intellij.psi.PsiRecordComponent;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import de.plushnikov.intellij.plugin.psi.LombokLightClassBuilder;
|
||||
import de.plushnikov.intellij.plugin.psi.LombokLightFieldBuilder;
|
||||
@@ -26,9 +28,9 @@ public class LombokFieldFindUsagesHandlerFactory extends FindUsagesHandlerFactor
|
||||
|
||||
@Override
|
||||
public boolean canFindUsages(@NotNull PsiElement element) {
|
||||
if (element instanceof PsiField && !DumbService.isDumb(element.getProject())) {
|
||||
final PsiField psiField = (PsiField) element;
|
||||
final PsiClass containingClass = psiField.getContainingClass();
|
||||
if ((element instanceof PsiField || element instanceof PsiRecordComponent) && !DumbService.isDumb(element.getProject())) {
|
||||
final PsiMember psiMember = (PsiMember) element;
|
||||
final PsiClass containingClass = psiMember.getContainingClass();
|
||||
if (containingClass != null) {
|
||||
return Arrays.stream(containingClass.getMethods()).anyMatch(LombokLightMethodBuilder.class::isInstance) ||
|
||||
Arrays.stream(containingClass.getInnerClasses()).anyMatch(LombokLightClassBuilder.class::isInstance);
|
||||
@@ -42,34 +44,34 @@ public class LombokFieldFindUsagesHandlerFactory extends FindUsagesHandlerFactor
|
||||
return new FindUsagesHandler(element) {
|
||||
@Override
|
||||
public PsiElement @NotNull [] getSecondaryElements() {
|
||||
final PsiField psiField = (PsiField) getPsiElement();
|
||||
final PsiClass containingClass = psiField.getContainingClass();
|
||||
final PsiMember psiMember = (PsiMember) getPsiElement();
|
||||
final PsiClass containingClass = psiMember.getContainingClass();
|
||||
if (containingClass != null) {
|
||||
|
||||
final Collection<PsiElement> elements = new ArrayList<>();
|
||||
processClass(containingClass, psiField, elements);
|
||||
processClass(containingClass, psiMember, elements);
|
||||
|
||||
Arrays.stream(containingClass.getInnerClasses())
|
||||
.forEach(psiClass -> processClass(psiClass, psiField, elements));
|
||||
.forEach(psiClass -> processClass(psiClass, psiMember, elements));
|
||||
|
||||
return PsiUtilCore.toPsiElementArray(elements);
|
||||
}
|
||||
return PsiElement.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
private static void processClass(PsiClass containingClass, PsiField refPsiField, Collection<PsiElement> collector) {
|
||||
private static void processClass(PsiClass containingClass, PsiMember refPsiField, Collection<PsiElement> collector) {
|
||||
processClassMethods(containingClass, refPsiField, collector);
|
||||
processClassFields(containingClass, refPsiField, collector);
|
||||
}
|
||||
|
||||
private static void processClassFields(PsiClass containingClass, PsiField refPsiField, Collection<PsiElement> collector) {
|
||||
private static void processClassFields(PsiClass containingClass, PsiMember refPsiField, Collection<PsiElement> collector) {
|
||||
Arrays.stream(containingClass.getFields())
|
||||
.filter(LombokLightFieldBuilder.class::isInstance)
|
||||
.filter(psiField -> psiField.getNavigationElement() == refPsiField)
|
||||
.forEach(collector::add);
|
||||
}
|
||||
|
||||
private static void processClassMethods(PsiClass containingClass, PsiField refPsiField, Collection<PsiElement> collector) {
|
||||
private static void processClassMethods(PsiClass containingClass, PsiMember refPsiField, Collection<PsiElement> collector) {
|
||||
Arrays.stream(containingClass.getMethods())
|
||||
.filter(LombokLightMethodBuilder.class::isInstance)
|
||||
.filter(psiMethod -> psiMethod.getNavigationElement() == refPsiField)
|
||||
|
||||
@@ -83,12 +83,14 @@ public class BuilderProcessor extends AbstractClassProcessor {
|
||||
|
||||
@Override
|
||||
protected void generatePsiElements(@NotNull PsiClass psiClass, @NotNull PsiAnnotation psiAnnotation, @NotNull List<? super PsiElement> target) {
|
||||
if (PsiAnnotationSearchUtil.isNotAnnotatedWith(psiClass, LombokClassNames.ALL_ARGS_CONSTRUCTOR,
|
||||
LombokClassNames.REQUIRED_ARGS_CONSTRUCTOR, LombokClassNames.NO_ARGS_CONSTRUCTOR)) {
|
||||
// Create all args constructor only if there is no declared constructors and no lombok constructor annotations
|
||||
final Collection<PsiMethod> definedConstructors = PsiClassUtil.collectClassConstructorIntern(psiClass);
|
||||
if (definedConstructors.isEmpty()) {
|
||||
target.addAll(getAllArgsConstructorProcessor().createAllArgsConstructor(psiClass, PsiModifier.PACKAGE_LOCAL, psiAnnotation));
|
||||
if (!psiClass.isRecord()) {
|
||||
if (PsiAnnotationSearchUtil.isNotAnnotatedWith(psiClass, LombokClassNames.ALL_ARGS_CONSTRUCTOR,
|
||||
LombokClassNames.REQUIRED_ARGS_CONSTRUCTOR, LombokClassNames.NO_ARGS_CONSTRUCTOR)) {
|
||||
// Create all args constructor only if there is no declared constructors and no lombok constructor annotations
|
||||
final Collection<PsiMethod> definedConstructors = PsiClassUtil.collectClassConstructorIntern(psiClass);
|
||||
if (definedConstructors.isEmpty()) {
|
||||
target.addAll(getAllArgsConstructorProcessor().createAllArgsConstructor(psiClass, PsiModifier.PACKAGE_LOCAL, psiAnnotation));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package de.plushnikov.intellij.plugin.processor.clazz.constructor;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.SafeDeleteFix;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.RecordAugmentProvider;
|
||||
import com.intellij.psi.impl.light.LightReferenceListBuilder;
|
||||
import com.intellij.psi.impl.light.LightTypeParameterBuilder;
|
||||
import com.intellij.psi.util.PsiTypesUtil;
|
||||
@@ -182,7 +183,9 @@ public abstract class AbstractConstructorClassProcessor extends AbstractClassPro
|
||||
protected static Collection<PsiField> getAllNotInitializedAndNotStaticFields(@NotNull PsiClass psiClass) {
|
||||
Collection<PsiField> allNotInitializedNotStaticFields = new ArrayList<>();
|
||||
final boolean classAnnotatedWithValue = PsiAnnotationSearchUtil.isAnnotatedWith(psiClass, LombokClassNames.VALUE);
|
||||
for (PsiField psiField : PsiClassUtil.collectClassFieldsIntern(psiClass)) {
|
||||
Collection<PsiField> fields = psiClass.isRecord() ? RecordAugmentProvider.getFieldAugments(psiClass)
|
||||
: PsiClassUtil.collectClassFieldsIntern(psiClass);
|
||||
for (PsiField psiField : fields) {
|
||||
// skip fields named $
|
||||
boolean addField = !psiField.getName().startsWith(LombokUtils.LOMBOK_INTERN_FIELD_MARKER);
|
||||
|
||||
|
||||
@@ -7,9 +7,11 @@ import com.intellij.find.findUsages.JavaClassFindUsagesOptions;
|
||||
import com.intellij.find.impl.FindManagerImpl;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.util.CommonProcessors;
|
||||
import de.plushnikov.intellij.plugin.AbstractLombokLightCodeInsightTestCase;
|
||||
import de.plushnikov.intellij.plugin.LombokTestUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -21,6 +23,12 @@ import java.util.List;
|
||||
*/
|
||||
public class LombokUsageTest extends AbstractLombokLightCodeInsightTestCase {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
return LombokTestUtil.LOMBOK_NEW_DESCRIPTOR;
|
||||
}
|
||||
|
||||
public void testFindUsageGetterSetter() {
|
||||
final Collection<UsageInfo> usages = loadTestClass();
|
||||
assertUsages(usages, "findUsageGetterSetter.setBar", "findUsageGetterSetter.getBar");
|
||||
@@ -36,11 +44,21 @@ public class LombokUsageTest extends AbstractLombokLightCodeInsightTestCase {
|
||||
assertUsages(usages, "findUsageWither.withBar", "findUsageWither.getBar");
|
||||
}
|
||||
|
||||
public void testFindUsageWitherRecord() {
|
||||
final Collection<UsageInfo> usages = loadTestClass();
|
||||
assertUsages(usages, "findUsageWitherRecord.withBar", "findUsageWitherRecord.bar");
|
||||
}
|
||||
|
||||
public void testFindUsageBuilder() {
|
||||
final Collection<UsageInfo> usages = loadTestClass();
|
||||
assertUsages(usages, "FindUsageBuilder.builder().bar", "findUsageBuilder.getBar");
|
||||
}
|
||||
|
||||
public void testFindUsageBuilderRecord() {
|
||||
final Collection<UsageInfo> usages = loadTestClass();
|
||||
assertUsages(usages, "FindUsageBuilderRecord.builder().bar", "findUsageBuilderRecord.bar");
|
||||
}
|
||||
|
||||
public void testFindUsageSingularBuilder() {
|
||||
final Collection<UsageInfo> usages = loadTestClass();
|
||||
assertUsages(usages, "FindUsageSingularBuilder.builder().bar", "FindUsageSingularBuilder.builder().bars",
|
||||
|
||||
19
plugins/lombok/testData/usage/FindUsageBuilderRecord.java
Normal file
19
plugins/lombok/testData/usage/FindUsageBuilderRecord.java
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
import lombok.Builder;
|
||||
|
||||
@Builder
|
||||
public record FindUsageBuilderRecord(
|
||||
int foo,
|
||||
String b<caret>ar
|
||||
) {
|
||||
|
||||
public static void main(String[] args) {
|
||||
FindUsageBuilderRecord findUsageBuilderRecord = FindUsageBuilderRecord.builder()
|
||||
.bar("bar")
|
||||
.foo(1981)
|
||||
.build();
|
||||
|
||||
System.out.println("Bar is: " + findUsageBuilderRecord.bar());
|
||||
System.out.println("Foo is: " + findUsageBuilderRecord.foo());
|
||||
}
|
||||
}
|
||||
20
plugins/lombok/testData/usage/FindUsageWitherRecord.java
Normal file
20
plugins/lombok/testData/usage/FindUsageWitherRecord.java
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
import lombok.Value;
|
||||
import lombok.experimental.Wither;
|
||||
|
||||
@Wither
|
||||
@Value
|
||||
public record FindUsageWitherRecord(
|
||||
int foo,
|
||||
String b<caret>ar
|
||||
) {
|
||||
|
||||
public static void main(String[] args) {
|
||||
FindUsageWitherRecord findUsageWitherRecord = new FindUsageWitherRecord(1, "bar");
|
||||
findUsageWitherRecord
|
||||
.withBar("myBar")
|
||||
.withFoo(1981);
|
||||
System.out.println("Bar is: " + findUsageWitherRecord.bar());
|
||||
System.out.println("Foo is: " + findUsageWitherRecord.foo());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user