[lombok] IDEA-310810 IDEA-380110 Show Lombok-generated methods in 'Caller-Hierarchy' tool window

GitOrigin-RevId: 063456efa192d4d60b402a14c4b860cf231d585c
This commit is contained in:
Michail Plushnikov
2025-12-17 21:12:59 +00:00
committed by intellij-monorepo-bot
parent cd926ffe35
commit b836adb49b
35 changed files with 820 additions and 23 deletions
@@ -106,6 +106,8 @@
</extensionPoint>
<extensionPoint qualifiedName="com.intellij.hierarchy.referenceProcessor"
interface="com.intellij.ide.hierarchy.call.CallReferenceProcessor" dynamic="true"/>
<extensionPoint qualifiedName="com.intellij.hierarchy.elementProvider"
interface="com.intellij.ide.hierarchy.call.CallHierarchyElementProvider" dynamic="true"/>
<extensionPoint qualifiedName="com.intellij.refactoring.pullUpHelperFactory" beanClass="com.intellij.lang.LanguageExtensionPoint"
dynamic="true">
<with attribute="implementationClass" implements="com.intellij.refactoring.memberPullUp.PullUpHelperFactory"/>
@@ -17,10 +17,8 @@ import com.intellij.util.ArrayUtilRt;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.stream.Stream;
public final class CallerMethodsTreeStructure extends HierarchyTreeStructure {
private final String myScopeType;
@@ -119,6 +117,11 @@ public final class CallerMethodsTreeStructure extends HierarchyTreeStructure {
}
return true;
});
// add other method elements without references
for (CallHierarchyElementProvider provider : CallHierarchyElementProvider.EP_NAME.getExtensionList()) {
provider.appendReferencedMethods(methodToFind, data);
}
}
return ArrayUtil.toObjectArray(methodToDescriptorMap.values());
@@ -127,9 +130,19 @@ public final class CallerMethodsTreeStructure extends HierarchyTreeStructure {
assert enclosingElement instanceof PsiField || enclosingElement instanceof PsiRecordComponent
: "Enclosing element should be a field, but was " + enclosingElement.getClass() + ", text: " + enclosingElement.getText();
return ReferencesSearch
final Stream<@NotNull PsiElement> referencedElements = ReferencesSearch
.search(enclosingElement, searchScope).findAll().stream()
.map(PsiReference::getElement)
.map(PsiReference::getElement);
// collect other field elements without references
Collection<@NotNull PsiElement> providedElements = new ArrayList<>();
for (CallHierarchyElementProvider provider : CallHierarchyElementProvider.EP_NAME.getExtensionList()) {
if(provider.canProvide(enclosingElement)) {
providedElements.addAll(provider.provideReferencedMembers(enclosingElement));
}
}
return Stream.concat(referencedElements, providedElements.stream())
.distinct()
.map(e -> new CallHierarchyNodeDescriptor(myProject, nodeDescriptor, e, false, false))
.filter(n -> n.getEnclosingElement() != null)
@@ -0,0 +1,22 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.ide.hierarchy.call;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMember;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.search.SearchScope;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
public interface CallHierarchyElementProvider {
ExtensionPointName<CallHierarchyElementProvider> EP_NAME =
ExtensionPointName.create("com.intellij.hierarchy.elementProvider");
boolean canProvide(@NotNull PsiMember element);
Collection<PsiElement> provideReferencedMembers(@NotNull PsiMember reference);
void appendReferencedMethods(@NotNull PsiMethod methodToFind, @NotNull JavaCallHierarchyData hierarchyData);
}
@@ -0,0 +1,69 @@
package de.plushnikov.intellij.plugin.hierarchy;
import com.intellij.ide.hierarchy.call.CallHierarchyElementProvider;
import com.intellij.ide.hierarchy.call.CallHierarchyNodeDescriptor;
import com.intellij.ide.hierarchy.call.JavaCallHierarchyData;
import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.psi.*;
import com.intellij.psi.search.SearchScope;
import de.plushnikov.intellij.plugin.psi.LombokLightMethodBuilder;
import org.jetbrains.annotations.NotNull;
import java.util.*;
public class LombokFieldHierarchyElementProvider implements CallHierarchyElementProvider {
@Override
public boolean canProvide(@NotNull PsiMember element) {
return element instanceof PsiField;
}
@Override
public Collection<PsiElement> provideReferencedMembers(@NotNull PsiMember elementToSearch) {
final PsiClass containingClass = elementToSearch.getContainingClass();
if (containingClass != null) {
final Collection<PsiElement> result = new ArrayList<>();
Arrays.stream(containingClass.getMethods())
.filter(LombokLightMethodBuilder.class::isInstance)
.map(LombokLightMethodBuilder.class::cast)
.filter(psiMethod -> psiMethod.getNavigationElement() == elementToSearch || psiMethod.hasRelatedMember(elementToSearch))
.forEach(result::add);
Arrays.stream(containingClass.getInnerClasses())
.map(PsiClass::getMethods)
.flatMap(Arrays::stream)
.filter(LombokLightMethodBuilder.class::isInstance)
.map(LombokLightMethodBuilder.class::cast)
.filter(psiMethod -> psiMethod.hasRelatedMember(elementToSearch))
.forEach(result::add);
return result;
}
return Collections.emptyList();
}
@Override
public void appendReferencedMethods(@NotNull PsiMethod methodToFind, @NotNull JavaCallHierarchyData hierarchyData) {
if (methodToFind.isConstructor()) {
final PsiClass containingClass = methodToFind.getContainingClass();
if (null != containingClass) {
Arrays.stream(containingClass.getInnerClasses())
.map(PsiClass::getMethods)
.flatMap(Arrays::stream)
.filter(LombokLightMethodBuilder.class::isInstance)
.map(LombokLightMethodBuilder.class::cast)
.filter(methodBuilder -> methodBuilder.hasRelatedMember(methodToFind))
.forEach(methodBuilder -> {
CallHierarchyNodeDescriptor parentDescriptor = (CallHierarchyNodeDescriptor)hierarchyData.getNodeDescriptor();
final Map<PsiMember, NodeDescriptor<?>> nodeDescriptorMap = hierarchyData.getResultMap();
CallHierarchyNodeDescriptor d = (CallHierarchyNodeDescriptor)nodeDescriptorMap.get(methodBuilder);
if (d == null) {
d = new CallHierarchyNodeDescriptor(hierarchyData.getProject(), parentDescriptor, methodBuilder, false, true);
nodeDescriptorMap.put(methodBuilder, d);
}
});
}
}
}
}
@@ -3,6 +3,7 @@ package de.plushnikov.intellij.plugin.processor.clazz;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTypesUtil;
import com.intellij.util.containers.ContainerUtil;
import de.plushnikov.intellij.plugin.LombokClassNames;
import de.plushnikov.intellij.plugin.lombokconfig.ConfigKey;
import de.plushnikov.intellij.plugin.problem.ProblemSink;
@@ -194,19 +195,28 @@ public final class EqualsAndHashCodeProcessor extends AbstractClassProcessor {
LombokAddNullAnnotations.createRelevantNullableAnnotation(psiClass, parameter);
copyOnXAnnotationsForFirstParam(psiAnnotation, parameter);
}
methodBuilder.withRelatedMembers(m -> {
final Collection<MemberInfo> memberInfos = collectEqualsAndHashcodeMemberInfo(m);
return ContainerUtil.map(memberInfos, MemberInfo::getField);
});
methodBuilder.withBodyText(m -> {
PsiClass containingClass = m.getContainingClass();
PsiAnnotation anno = (PsiAnnotation)m.getNavigationElement();
return createEqualsBlockString(containingClass, anno, hasCanEqualMethod,
EqualsAndHashCodeToStringHandler.filterMembers(containingClass, anno, true,
INCLUDE_ANNOTATION_METHOD, null,
EQUALS_AND_HASHCODE_INCLUDE,
EQUALS_AND_HASHCODE_EXCLUDE));
final PsiClass containingClass = m.getContainingClass();
final PsiAnnotation anno = (PsiAnnotation)m.getNavigationElement();
final Collection<MemberInfo> memberInfos = collectEqualsAndHashcodeMemberInfo(m);
return createEqualsBlockString(containingClass, anno, hasCanEqualMethod, memberInfos);
});
return methodBuilder;
}
private static @NotNull Collection<MemberInfo> collectEqualsAndHashcodeMemberInfo(LombokLightMethodBuilder m) {
PsiClass containingClass = m.getContainingClass();
PsiAnnotation anno = (PsiAnnotation)m.getNavigationElement();
return EqualsAndHashCodeToStringHandler.filterMembers(containingClass, anno, true,
INCLUDE_ANNOTATION_METHOD, null,
EQUALS_AND_HASHCODE_INCLUDE,
EQUALS_AND_HASHCODE_EXCLUDE);
}
private @NotNull PsiMethod createHashCodeMethod(@NotNull PsiClass psiClass,
@NotNull PsiAnnotation psiAnnotation) {
final PsiManager psiManager = psiClass.getManager();
@@ -216,14 +226,15 @@ public final class EqualsAndHashCodeProcessor extends AbstractClassProcessor {
.withMethodReturnType(PsiTypes.intType())
.withContainingClass(psiClass)
.withNavigationElement(psiAnnotation)
.withRelatedMembers(m -> {
final Collection<MemberInfo> memberInfos = collectEqualsAndHashcodeMemberInfo(m);
return ContainerUtil.map(memberInfos, MemberInfo::getField);
})
.withBodyText(m -> {
PsiClass containingClass = m.getContainingClass();
PsiAnnotation anno = (PsiAnnotation)m.getNavigationElement();
return createHashcodeBlockString(containingClass, anno,
EqualsAndHashCodeToStringHandler.filterMembers(containingClass, anno, true,
INCLUDE_ANNOTATION_METHOD, null,
EQUALS_AND_HASHCODE_INCLUDE,
EQUALS_AND_HASHCODE_EXCLUDE));
final Collection<MemberInfo> memberInfos = collectEqualsAndHashcodeMemberInfo(m);
return createHashcodeBlockString(containingClass, anno, memberInfos);
});
}
@@ -126,6 +126,10 @@ public final class ToStringProcessor extends AbstractClassProcessor {
LombokAddNullAnnotations.createRelevantNonNullAnnotation(psiClass, methodBuilder);
for (MemberInfo memberInfo : memberInfos) {
methodBuilder.withRelatedMember(memberInfo.getField());
}
return methodBuilder;
}
@@ -328,6 +328,10 @@ public abstract class AbstractConstructorClassProcessor extends AbstractClassPro
.withModifier(modifier)
.withWriteAccess();
for (PsiField param : params) {
constructorBuilder.withRelatedMember(param);
}
LombokCopyableAnnotations.copyOnXAnnotations(psiAnnotation, constructorBuilder.getModifierList(), "onConstructor");
if (useJavaDefaults) {
@@ -395,6 +399,10 @@ public abstract class AbstractConstructorClassProcessor extends AbstractClassPro
.withModifier(PsiModifier.STATIC)
.withWriteAccess();
for (PsiField param : params) {
methodBuilder.withRelatedMember(param);
}
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
if (psiClass.hasTypeParameters()) {
final PsiTypeParameter[] classTypeParameters = psiClass.getTypeParameters();
@@ -23,10 +23,7 @@ import de.plushnikov.intellij.plugin.provider.LombokUserDataKeys;
import de.plushnikov.intellij.plugin.psi.LombokLightClassBuilder;
import de.plushnikov.intellij.plugin.psi.LombokLightMethodBuilder;
import de.plushnikov.intellij.plugin.thirdparty.LombokCopyableAnnotations;
import de.plushnikov.intellij.plugin.util.LombokProcessorUtil;
import de.plushnikov.intellij.plugin.util.PsiAnnotationSearchUtil;
import de.plushnikov.intellij.plugin.util.PsiAnnotationUtil;
import de.plushnikov.intellij.plugin.util.PsiClassUtil;
import de.plushnikov.intellij.plugin.util.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -766,6 +763,16 @@ public class BuilderHandler {
.withContainingClass(builderClass)
.withNavigationElement(parentClass)
.withModifier(getBuilderInnerAccessVisibility(psiAnnotation));
if (null == psiMethod) {
Stream.of(parentClass.getConstructors())
.filter(m -> sameParameters(m.getParameterList().getParameters(), builderInfos))
.findFirst().ifPresent(methodBuilder::withRelatedMember);
}
else if (psiMethod.isConstructor()) {
methodBuilder.withRelatedMember(psiMethod);
}
final String codeBlockText =
createBuildMethodCodeBlockText(psiMethod, builderClass, returnType, buildMethodPrepare, buildMethodParameters);
methodBuilder.withBodyText(codeBlockText);
@@ -21,6 +21,9 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
@@ -38,6 +41,11 @@ public class LombokLightMethodBuilder extends LightMethodBuilder implements Synt
private boolean myReadWriteAccess = false;
private Function<LombokLightMethodBuilder, Collection<PsiElement>> myRelatedMembersFunction = builder -> {
return List.of();
};
private Collection<PsiElement> myRelatedMembers;
public LombokLightMethodBuilder(@NotNull PsiManager manager, @NotNull String name) {
super(manager, JavaLanguage.INSTANCE, name,
new LombokLightParameterListBuilder(manager, JavaLanguage.INSTANCE),
@@ -48,6 +56,29 @@ public class LombokLightMethodBuilder extends LightMethodBuilder implements Synt
setBaseIcon(LombokIcons.Nodes.LombokMethod);
}
public LombokLightMethodBuilder withRelatedMembers(@NotNull Function<LombokLightMethodBuilder, Collection<PsiElement>> buildFunction) {
myRelatedMembersFunction = buildFunction;
myRelatedMembers = null;
return this;
}
public LombokLightMethodBuilder withRelatedMember(@Nullable PsiElement member) {
if(null != member) {
if (myRelatedMembers == null) {
myRelatedMembers = new ArrayList<>();
}
myRelatedMembers.add(member);
}
return this;
}
public boolean hasRelatedMember(@NotNull PsiMember member) {
if(myRelatedMembers == null) {
myRelatedMembers = myRelatedMembersFunction.apply(this);
}
return myRelatedMembers.contains(member);
}
public LombokLightMethodBuilder withNavigationElement(PsiElement navigationElement) {
setNavigationElement(navigationElement);
return this;
@@ -113,6 +113,8 @@
<canBeFinal implementation="de.plushnikov.intellij.plugin.extension.LombokCanBeFinalHandler"/>
<hierarchy.elementProvider implementation="de.plushnikov.intellij.plugin.hierarchy.LombokFieldHierarchyElementProvider"/>
<localInspection groupPath="Java" language="JAVA" shortName="LombokGetterMayBeUsed" enabledByDefault="true" level="WARNING"
bundle="messages.LombokBundle" key="inspection.lombok.getter.may.be.used.display.name"
groupBundle="messages.InspectionsBundle" groupKey="group.names.verbose.or.redundant.code.constructs"
@@ -0,0 +1,152 @@
package de.plushnikov.intellij.plugin.hierarchy;
import com.intellij.ide.hierarchy.HierarchyBrowserBaseEx;
import com.intellij.ide.hierarchy.JavaHierarchyUtil;
import com.intellij.ide.hierarchy.call.CallerMethodsTreeStructure;
import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiField;
import com.intellij.psi.search.ProjectScope;
import com.intellij.testFramework.codeInsight.hierarchy.HierarchyViewTestFixture;
import de.plushnikov.intellij.plugin.AbstractLombokLightCodeInsightTestCase;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Comparator;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
/**
* Tests for CallHierarchy with Lombok annotations.
* Compares the call hierarchy of Lombok-generated methods with equivalent plain Java implementations.
* The test normalizes class names in the hierarchy dumps so that only the caller methods matter.
* Only caller methods are compared, excluding internal class hierarchy elements.
*/
public class LombokCallHierarchyTest extends AbstractLombokLightCodeInsightTestCase {
@Override
protected String getBasePath() {
return super.getBasePath() + "/hierarchy";
}
// ==================== @Getter Comparison Test ====================
public void testGetterHierarchyComparison() {
doCompareFieldHierarchies(
"GetterLombok", "GetterLombokCaller", "name",
"GetterPlainJava", "GetterPlainJavaCaller"
);
}
// ==================== @Setter Comparison Test ====================
public void testSetterHierarchyComparison() {
doCompareFieldHierarchies(
"SetterLombok", "SetterLombokCaller", "value",
"SetterPlainJava", "SetterPlainJavaCaller"
);
}
// ==================== @Data Comparison Test ====================
public void testDataHierarchyComparison() {
doCompareFieldHierarchies(
"DataLombok", "DataLombokCaller", "id",
"DataPlainJava", "DataPlainJavaCaller"
);
}
// ==================== @Value Comparison Test ====================
public void testValueHierarchyComparison() {
doCompareFieldHierarchies(
"ValueLombok", "ValueLombokCaller", "code",
"ValuePlainJava", "ValuePlainJavaCaller"
);
}
// ==================== @ToString Comparison Test ====================
public void testToStringHierarchyComparison() {
doCompareFieldHierarchies(
"ToStringLombok", "ToStringLombokCaller", "description",
"ToStringPlainJava", "ToStringPlainJavaCaller"
);
}
// ==================== @Builder Comparison Test ====================
public void testBuilderHierarchyComparison() {
doCompareFieldHierarchies(
"BuilderLombok", "BuilderLombokCaller", "title",
"BuilderPlainJava", "BuilderPlainJavaCaller"
);
}
// ==================== Helper Methods ====================
/**
* Compares the call hierarchy of a field in a Lombok class with a one in a plain Java class.
* The hierarchies are normalized to remove class name differences, so only the method structure matters.
*/
private void doCompareFieldHierarchies(
String lombokClassName, String lombokCallerClassName, String fieldName,
String plainJavaClassName, String plainJavaCallerClassName) {
// Load all files together
myFixture.configureByFiles(
"/" + lombokClassName.replace('$', '/') + ".java",
"/" + lombokCallerClassName + ".java",
"/" + plainJavaClassName.replace('$', '/').split("\\$")[0] + ".java",
"/" + plainJavaCallerClassName + ".java"
);
// Get Lombok hierarchy (field-based)
@NotNull CallerMethodsTreeStructure lombokHierarchy = getFieldCallerHierarchy(lombokClassName, fieldName);
// Get Plain Java hierarchy (field-based)
@NotNull CallerMethodsTreeStructure plainJavaHierarchy = getFieldCallerHierarchy(plainJavaClassName, fieldName);
final Comparator<NodeDescriptor<?>> nodeDescriptorComparator = JavaHierarchyUtil.getComparator(getProject());
String plainDumped = HierarchyViewTestFixture.dump(plainJavaHierarchy, null, nodeDescriptorComparator, 0);
String plainDumpedNormalized = plainDumped.replaceAll(plainJavaClassName, lombokClassName);
plainDumpedNormalized = plainDumpedNormalized.replaceAll(plainJavaCallerClassName, lombokCallerClassName);
final String equalsMethodCall = lombokClassName + ".equals(Object)";
if(StringUtil.getOccurrenceCount(plainDumpedNormalized, equalsMethodCall) > 1) {
plainDumpedNormalized = removeFirstLineWithSubstring(plainDumpedNormalized, equalsMethodCall);
}
HierarchyViewTestFixture.doHierarchyTest(lombokHierarchy, plainDumpedNormalized);
}
public static String removeFirstLineWithSubstring(String text, String substring) {
AtomicBoolean removed = new AtomicBoolean(false);
return Arrays.stream(text.split("\\R"))
.filter(line -> {
if (!removed.get() && line.contains(substring)) {
removed.set(true);
return false; // erstes Vorkommen raus
}
return true;
})
.collect(Collectors.joining(System.lineSeparator()));
}
@NotNull
private CallerMethodsTreeStructure getFieldCallerHierarchy(String className, String fieldName) {
PsiClass psiClass = JavaPsiFacade.getInstance(getProject())
.findClass(className, ProjectScope.getProjectScope(getProject()));
assertNotNull("Class '" + className + "' not found", psiClass);
PsiField field = psiClass.findFieldByName(fieldName, false);
assertNotNull("Field '" + fieldName + "' not found in " + className, field);
return new CallerMethodsTreeStructure(getProject(), field, HierarchyBrowserBaseEx.SCOPE_PROJECT);
}
}
@@ -0,0 +1,9 @@
import lombok.Builder;
@Builder
public class BuilderLombok {
private String title;
private String author;
private int pages;
private boolean published;
}
@@ -0,0 +1,25 @@
public class BuilderLombokCaller {
public void useBuilder() {
BuilderLombok book = BuilderLombok.builder()
.title("Clean Code")
.author("Robert C. Martin")
.pages(464)
.published(true)
.build();
}
public BuilderLombok createBook(String title, String author) {
return BuilderLombok.builder()
.title(title)
.author(author)
.pages(100)
.published(false)
.build();
}
public BuilderLombok.BuilderLombokBuilder startBuilding() {
return BuilderLombok.builder()
.title("New Book");
}
}
@@ -0,0 +1,51 @@
public class BuilderPlainJava {
private String title;
private String author;
private int pages;
private boolean published;
BuilderPlainJava(String title, String author, int pages, boolean published) {
this.title = title;
this.author = author;
this.pages = pages;
this.published = published;
}
public static BuilderPlainJavaBuilder builder() {
return new BuilderPlainJavaBuilder();
}
public static class BuilderPlainJavaBuilder {
private String title;
private String author;
private int pages;
private boolean published;
BuilderPlainJavaBuilder() {
}
public BuilderPlainJavaBuilder title(String title) {
this.title = title;
return this;
}
public BuilderPlainJavaBuilder author(String author) {
this.author = author;
return this;
}
public BuilderPlainJavaBuilder pages(int pages) {
this.pages = pages;
return this;
}
public BuilderPlainJavaBuilder published(boolean published) {
this.published = published;
return this;
}
public BuilderPlainJava build() {
return new BuilderPlainJava(title, author, pages, published);
}
}
}
@@ -0,0 +1,25 @@
public class BuilderPlainJavaCaller {
public void useBuilder() {
BuilderPlainJava book = BuilderPlainJava.builder()
.title("Clean Code")
.author("Robert C. Martin")
.pages(464)
.published(true)
.build();
}
public BuilderPlainJava createBook(String title, String author) {
return BuilderPlainJava.builder()
.title(title)
.author(author)
.pages(100)
.published(false)
.build();
}
public BuilderPlainJava.BuilderPlainJavaBuilder startBuilding() {
return BuilderPlainJava.builder()
.title("New Book");
}
}
@@ -0,0 +1,8 @@
import lombok.Data;
@Data
public class DataLombok {
private Long id;
private String name;
private boolean active;
}
@@ -0,0 +1,23 @@
public class DataLombokCaller {
public void useData() {
DataLombok obj = new DataLombok();
obj.setId(1L);
obj.setName("Test");
obj.setActive(true);
Long id = obj.getId();
String name = obj.getName();
boolean active = obj.isActive();
System.out.println("ID: " + id + ", Name: " + name + ", Active: " + active);
}
public Long fetchId(DataLombok data) {
return data.getId();
}
public void updateId(DataLombok data, Long newId) {
data.setId(newId);
}
}
@@ -0,0 +1,53 @@
import java.util.Objects;
public class DataPlainJava {
private Long id;
private String name;
private boolean active;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DataPlainJava that = (DataPlainJava) o;
return active == that.active && Objects.equals(id, that.id) && Objects.equals(name, that.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name, active);
}
@Override
public String toString() {
return "DataPlainJava{" +
"id=" + id +
", name='" + name + '\'' +
", active=" + active +
'}';
}
}
@@ -0,0 +1,23 @@
public class DataPlainJavaCaller {
public void useData() {
DataPlainJava obj = new DataPlainJava();
obj.setId(1L);
obj.setName("Test");
obj.setActive(true);
Long id = obj.getId();
String name = obj.getName();
boolean active = obj.isActive();
System.out.println("ID: " + id + ", Name: " + name + ", Active: " + active);
}
public Long fetchId(DataPlainJava data) {
return data.getId();
}
public void updateId(DataPlainJava data, Long newId) {
data.setId(newId);
}
}
@@ -0,0 +1,12 @@
import lombok.Getter;
@Getter
public class GetterLombok {
private String name;
private int age;
public GetterLombok(String name, int age) {
this.name = name;
this.age = age;
}
}
@@ -0,0 +1,13 @@
public class GetterLombokCaller {
public void useGetter() {
GetterLombok obj = new GetterLombok("Test", 25);
String name = obj.getName();
int age = obj.getAge();
System.out.println("Name: " + name + ", Age: " + age);
}
public String fetchName(GetterLombok lombok) {
return lombok.getName();
}
}
@@ -0,0 +1,17 @@
public class GetterPlainJava {
private String name;
private int age;
public GetterPlainJava(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
@@ -0,0 +1,13 @@
public class GetterPlainJavaCaller {
public void useGetter() {
GetterPlainJava obj = new GetterPlainJava("Test", 25);
String name = obj.getName();
int age = obj.getAge();
System.out.println("Name: " + name + ", Age: " + age);
}
public String fetchName(GetterPlainJava plainJava) {
return plainJava.getName();
}
}
@@ -0,0 +1,7 @@
import lombok.Setter;
@Setter
public class SetterLombok {
private String value;
private int count;
}
@@ -0,0 +1,12 @@
public class SetterLombokCaller {
public void useSetter() {
SetterLombok obj = new SetterLombok();
obj.setValue("Hello");
obj.setCount(42);
}
public void updateValue(SetterLombok lombok, String newValue) {
lombok.setValue(newValue);
}
}
@@ -0,0 +1,12 @@
public class SetterPlainJava {
private String value;
private int count;
public void setValue(String value) {
this.value = value;
}
public void setCount(int count) {
this.count = count;
}
}
@@ -0,0 +1,12 @@
public class SetterPlainJavaCaller {
public void useSetter() {
SetterPlainJava obj = new SetterPlainJava();
obj.setValue("Hello");
obj.setCount(42);
}
public void updateValue(SetterPlainJava plainJava, String newValue) {
plainJava.setValue(newValue);
}
}
@@ -0,0 +1,14 @@
import lombok.ToString;
@ToString
public class ToStringLombok {
private String description;
private int priority;
private boolean completed;
public ToStringLombok(String description, int priority, boolean completed) {
this.description = description;
this.priority = priority;
this.completed = completed;
}
}
@@ -0,0 +1,16 @@
public class ToStringLombokCaller {
public void useToString() {
ToStringLombok obj = new ToStringLombok("Task description", 1, false);
String result = obj.toString();
System.out.println(result);
}
public String getStringRepresentation(ToStringLombok lombok) {
return lombok.toString();
}
public void logObject(ToStringLombok lombok) {
System.out.println("Object: " + lombok.toString());
}
}
@@ -0,0 +1,20 @@
public class ToStringPlainJava {
private String description;
private int priority;
private boolean completed;
public ToStringPlainJava(String description, int priority, boolean completed) {
this.description = description;
this.priority = priority;
this.completed = completed;
}
@Override
public String toString() {
return "ToStringPlainJava{" +
"description='" + description + '\'' +
", priority=" + priority +
", completed=" + completed +
'}';
}
}
@@ -0,0 +1,16 @@
public class ToStringPlainJavaCaller {
public void useToString() {
ToStringPlainJava obj = new ToStringPlainJava("Task description", 1, false);
String result = obj.toString();
System.out.println(result);
}
public String getStringRepresentation(ToStringPlainJava plainJava) {
return plainJava.toString();
}
public void logObject(ToStringPlainJava plainJava) {
System.out.println("Object: " + plainJava.toString());
}
}
@@ -0,0 +1,8 @@
import lombok.Value;
@Value
public class ValueLombok {
String code;
int version;
boolean enabled;
}
@@ -0,0 +1,20 @@
public class ValueLombokCaller {
public void useValue() {
ValueLombok obj = new ValueLombok("ABC", 1, true);
String code = obj.getCode();
int version = obj.getVersion();
boolean enabled = obj.isEnabled();
System.out.println("Code: " + code + ", Version: " + version + ", Enabled: " + enabled);
}
public String fetchCode(ValueLombok value) {
return value.getCode();
}
public boolean checkEnabled(ValueLombok value) {
return value.isEnabled();
}
}
@@ -0,0 +1,47 @@
import java.util.Objects;
public final class ValuePlainJava {
private final String code;
private final int version;
private final boolean enabled;
public ValuePlainJava(String code, int version, boolean enabled) {
this.code = code;
this.version = version;
this.enabled = enabled;
}
public String getCode() {
return code;
}
public int getVersion() {
return version;
}
public boolean isEnabled() {
return enabled;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ValuePlainJava that = (ValuePlainJava) o;
return version == that.version && enabled == that.enabled && Objects.equals(code, that.code);
}
@Override
public int hashCode() {
return Objects.hash(code, version, enabled);
}
@Override
public String toString() {
return "ValuePlainJava{" +
"code='" + code + '\'' +
", version=" + version +
", enabled=" + enabled +
'}';
}
}
@@ -0,0 +1,20 @@
public class ValuePlainJavaCaller {
public void useValue() {
ValuePlainJava obj = new ValuePlainJava("ABC", 1, true);
String code = obj.getCode();
int version = obj.getVersion();
boolean enabled = obj.isEnabled();
System.out.println("Code: " + code + ", Version: " + version + ", Enabled: " + enabled);
}
public String fetchCode(ValuePlainJava value) {
return value.getCode();
}
public boolean checkEnabled(ValuePlainJava value) {
return value.isEnabled();
}
}