mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-13 15:52:01 +07:00
[lombok] IDEA-352727 Support incomplete mode
- support main processors (except ConstantField, because it depends on a lombok version) - parser tests are executed in three modes (normal, incomplete, dumb) by default The main idea is to provide users some functionality in incomplete mode (when libraries are not downloaded yet), but users can already do something. After downloading psi caches will be dropped and everything will be recomputed in an accurate way. GitOrigin-RevId: a7b2774a01be86a60aa5bdcd69a3826682b4135e
This commit is contained in:
committed by
intellij-monorepo-bot
parent
56117ec688
commit
8a33c22212
@@ -5,6 +5,7 @@ import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElementFinder;
|
||||
import com.intellij.psi.impl.file.impl.JavaFileManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import de.plushnikov.intellij.plugin.util.IncompleteModeUtil;
|
||||
import de.plushnikov.intellij.plugin.util.LombokLibraryUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -22,7 +23,8 @@ public final class LombokElementFinder extends PsiElementFinder {
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiClass findClass(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
|
||||
if (!LombokLibraryUtil.hasLombokLibrary(myProject)) {
|
||||
if (!LombokLibraryUtil.hasLombokLibrary(myProject) &&
|
||||
!IncompleteModeUtil.isIncompleteMode(myProject)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiJavaCodeReferenceElement;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import de.plushnikov.intellij.plugin.processor.clazz.*;
|
||||
import de.plushnikov.intellij.plugin.processor.clazz.builder.*;
|
||||
import de.plushnikov.intellij.plugin.processor.clazz.constructor.AllArgsConstructorProcessor;
|
||||
@@ -21,12 +22,15 @@ import de.plushnikov.intellij.plugin.processor.method.BuilderClassMethodProcesso
|
||||
import de.plushnikov.intellij.plugin.processor.method.BuilderMethodProcessor;
|
||||
import de.plushnikov.intellij.plugin.processor.method.DelegateMethodProcessor;
|
||||
import de.plushnikov.intellij.plugin.processor.modifier.*;
|
||||
import de.plushnikov.intellij.plugin.util.PsiAnnotationSearchUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public final class LombokProcessorManager {
|
||||
@@ -85,10 +89,18 @@ public final class LombokProcessorManager {
|
||||
private final SynchronizedProcessor mySynchronizedProcessor = new SynchronizedProcessor();
|
||||
private final JacksonizedProcessor myJacksonizedProcessor = new JacksonizedProcessor();
|
||||
|
||||
private final Set<String> ourSupportedShortNames = getAllProcessors()
|
||||
.stream().flatMap(p -> Arrays.stream(p.getSupportedAnnotationClasses()))
|
||||
.map(StringUtil::getShortName)
|
||||
.collect(Collectors.toSet());
|
||||
private final MultiMap<String, String> ourSupportedShortNames = createSupportedShortNames();
|
||||
|
||||
@NotNull
|
||||
private MultiMap<String, String> createSupportedShortNames() {
|
||||
MultiMap<String, String> map = new MultiMap<>();
|
||||
for (Processor processor : getAllProcessors()) {
|
||||
for (String annotationClass : processor.getSupportedAnnotationClasses()) {
|
||||
map.putValue(StringUtil.getShortName(annotationClass), annotationClass);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public static LombokProcessorManager getInstance() {
|
||||
return ApplicationManager.getApplication().getService(LombokProcessorManager.class);
|
||||
@@ -266,6 +278,10 @@ public final class LombokProcessorManager {
|
||||
return myJacksonizedProcessor;
|
||||
}
|
||||
|
||||
public MultiMap<String, String> getOurSupportedShortNames() {
|
||||
return ourSupportedShortNames;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Collection<Processor> getAllProcessors() {
|
||||
return Arrays.asList(
|
||||
@@ -348,15 +364,19 @@ public final class LombokProcessorManager {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
String referenceName = nameReferenceElement.getReferenceName();
|
||||
if (referenceName == null || !manager.ourSupportedShortNames.contains(referenceName)) {
|
||||
if (referenceName == null || !manager.ourSupportedShortNames.containsKey(referenceName)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final String qualifiedName = psiAnnotation.getQualifiedName();
|
||||
String qualifiedName = psiAnnotation.getQualifiedName();
|
||||
if (PsiAnnotationSearchUtil.isDumbOrIncompleteMode(psiAnnotation)) {
|
||||
qualifiedName = PsiAnnotationSearchUtil.findLombokAnnotationQualifiedNameInIncompleteMode(psiAnnotation);
|
||||
}
|
||||
if (StringUtil.isEmpty(qualifiedName) || !qualifiedName.contains("lombok")) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
String finalQualifiedName = qualifiedName;
|
||||
return manager.getWithCache("byAnnotationFQN_" + qualifiedName,
|
||||
() -> ContainerUtil.filter(manager.getAllProcessors(), p -> p.isSupportedAnnotationFQN(qualifiedName))
|
||||
() -> ContainerUtil.filter(manager.getAllProcessors(), p -> p.isSupportedAnnotationFQN(finalQualifiedName))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ public abstract class AbstractFieldNameConstantsProcessor extends AbstractClassP
|
||||
|
||||
@Override
|
||||
protected boolean supportAnnotationVariant(@NotNull PsiAnnotation psiAnnotation) {
|
||||
//it can help for dumb mode or incomplete mode
|
||||
if (null != psiAnnotation.findDeclaredAttributeValue("asEnum")) return true;
|
||||
// new version of @FieldNameConstants has an attribute "asEnum", the old one not
|
||||
return null != psiAnnotation.findAttributeValue("asEnum");
|
||||
}
|
||||
|
||||
@@ -39,8 +39,11 @@ public final class FieldNameConstantsOldProcessor extends AbstractClassProcessor
|
||||
|
||||
@Override
|
||||
protected boolean supportAnnotationVariant(@NotNull PsiAnnotation psiAnnotation) {
|
||||
String prefix = "prefix";
|
||||
//it can help for dumb mode or incomplete mode
|
||||
if (null != psiAnnotation.findDeclaredAttributeValue(prefix)) return true;
|
||||
// old version of @FieldNameConstants has attributes "prefix" and "suffix", the new one not
|
||||
return null != psiAnnotation.findAttributeValue("prefix");
|
||||
return null != psiAnnotation.findAttributeValue(prefix);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -33,8 +33,11 @@ public final class FieldNameConstantsFieldProcessor extends AbstractFieldProcess
|
||||
|
||||
@Override
|
||||
protected boolean supportAnnotationVariant(@NotNull PsiAnnotation psiAnnotation) {
|
||||
String prefix = "prefix";
|
||||
//it can help for dumb mode or incomplete mode
|
||||
if (null != psiAnnotation.findDeclaredAttributeValue(prefix)) return true;
|
||||
// old version of @FieldNameConstants has attributes "prefix" and "suffix", the new one not
|
||||
return null != psiAnnotation.findAttributeValue("prefix");
|
||||
return null != psiAnnotation.findAttributeValue(prefix);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -8,6 +8,9 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.augment.PsiAugmentProvider;
|
||||
import com.intellij.psi.augment.PsiExtensionMethod;
|
||||
import com.intellij.psi.impl.source.PsiExtensibleClass;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.siyeh.ig.psiutils.InitializationUtils;
|
||||
import de.plushnikov.intellij.plugin.LombokClassNames;
|
||||
import de.plushnikov.intellij.plugin.processor.LombokProcessorManager;
|
||||
@@ -16,6 +19,7 @@ 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.modifier.ModifierProcessor;
|
||||
import de.plushnikov.intellij.plugin.util.IncompleteModeUtil;
|
||||
import de.plushnikov.intellij.plugin.util.PsiAnnotationSearchUtil;
|
||||
import de.plushnikov.intellij.plugin.util.PsiAnnotationUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -47,7 +51,7 @@ public final class LombokAugmentProvider extends PsiAugmentProvider implements P
|
||||
@Override
|
||||
protected Set<String> transformModifiers(@NotNull PsiModifierList modifierList, @NotNull final Set<String> modifiers) {
|
||||
// skip if no lombok library is present
|
||||
if (!hasLombokLibrary(modifierList.getProject())) {
|
||||
if (!hasLombokLibrary(modifierList.getProject()) && !isIncompleteModeWithLombokAnnotation(modifierList)) {
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
@@ -68,7 +72,6 @@ public final class LombokAugmentProvider extends PsiAugmentProvider implements P
|
||||
}
|
||||
else {
|
||||
runnable.run();
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -154,7 +157,7 @@ public final class LombokAugmentProvider extends PsiAugmentProvider implements P
|
||||
}
|
||||
|
||||
// skip processing if disabled, or no lombok library is present
|
||||
if (!hasLombokLibrary(element.getProject())) {
|
||||
if (!hasLombokLibrary(element.getProject()) && !isIncompleteModeWithLombokAnnotation(psiClass)) {
|
||||
return emptyResult;
|
||||
}
|
||||
if (psiClass.isAnnotationType() && type == PsiMethod.class) {
|
||||
@@ -201,4 +204,79 @@ public final class LombokAugmentProvider extends PsiAugmentProvider implements P
|
||||
}
|
||||
return ExtensionMethodsHelper.getExtensionMethods(aClass, nameHint, context);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the project is in incomplete mode and the class contains Lombok annotation.
|
||||
* Incomplete mode means that the project contains incomplete dependencies.
|
||||
* There is no purpose to be absolutely accurate, but it can help to reduce false red-code highlighting and help with some completion
|
||||
* This method can be quite slow, but it calls only in incomplete mode and cache value for file
|
||||
* @param context The PsiElement to check for Lombok annotations.
|
||||
* @return true if the project is in incomplete mode and the class has any Lombok annotation or if any of the class fields have any Lombok annotation;
|
||||
* otherwise, false.
|
||||
*/
|
||||
private static boolean isIncompleteModeWithLombokAnnotation(@NotNull PsiElement context) {
|
||||
if (!IncompleteModeUtil.isIncompleteMode(context)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (context.getLanguage() != JavaLanguage.INSTANCE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (context instanceof PsiModifierList modifierList && hasAnyLombokAnnotation(modifierList.getAnnotations())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
PsiClass psiClass = context instanceof PsiClass castedClass ? castedClass :
|
||||
PsiTreeUtil.getParentOfType(context, PsiClass.class);
|
||||
|
||||
if (psiClass == null) return false;
|
||||
|
||||
return CachedValuesManager.getProjectPsiDependentCache(psiClass, psiElement -> {
|
||||
if (!(psiElement.getContainingFile() instanceof PsiJavaFile file)) {
|
||||
return false;
|
||||
}
|
||||
if (file.getImportList() != null && ContainerUtil.exists(file.getImportList().getAllImportStatements(), statement -> {
|
||||
PsiJavaCodeReferenceElement reference = statement.getImportReference();
|
||||
return reference != null && reference.getText().startsWith("lombok");
|
||||
})) {
|
||||
return true;
|
||||
}
|
||||
while (psiElement != null) {
|
||||
if (psiElement instanceof PsiExtensibleClass extensibleClass &&
|
||||
(hasAnyLombokAnnotation(extensibleClass.getAnnotations()) ||
|
||||
ContainerUtil.exists(extensibleClass.getOwnFields(), field -> hasAnyLombokAnnotation(field.getAnnotations())) ||
|
||||
ContainerUtil.exists(extensibleClass.getOwnMethods(), method -> hasAnyLombokAnnotation(method.getAnnotations())) ||
|
||||
(file.getImportList() != null && ContainerUtil.exists(file.getImportList().getAllImportStatements(), statement -> {
|
||||
PsiJavaCodeReferenceElement reference = statement.getImportReference();
|
||||
return reference != null && reference.getText().startsWith("lombok");
|
||||
})))) {
|
||||
return true;
|
||||
}
|
||||
psiElement = PsiTreeUtil.getParentOfType(psiElement, PsiClass.class);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given PsiModifierListOwner has any Lombok annotation.
|
||||
* It is used only for incomplete mode.
|
||||
*
|
||||
* @param annotations The annotations to check for Lombok annotations.
|
||||
* @return true if the modifierListOwner has any Lombok annotation, otherwise false.
|
||||
*/
|
||||
private static boolean hasAnyLombokAnnotation(PsiAnnotation @NotNull [] annotations) {
|
||||
return ContainerUtil.exists(annotations, annotation -> {
|
||||
if (annotation == null) {
|
||||
return false;
|
||||
}
|
||||
String qualifiedName = annotation.getText();
|
||||
if (qualifiedName == null) {
|
||||
return false;
|
||||
}
|
||||
return qualifiedName.startsWith("@lombok.");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public enum LombokCopyableAnnotations {
|
||||
|
||||
List<PsiAnnotation> result = new ArrayList<>();
|
||||
for (PsiAnnotation annotation : fieldAnnotations) {
|
||||
if (ContainerUtil.exists(annotationNames, annotation::hasQualifiedName)) {
|
||||
if (PsiAnnotationSearchUtil.checkAnnotationHasOneOfFQNs(annotation, annotationNames)) {
|
||||
result.add(annotation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package de.plushnikov.intellij.plugin.util;
|
||||
|
||||
import com.intellij.openapi.project.IncompleteDependenciesService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiJavaFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public final class IncompleteModeUtil {
|
||||
private IncompleteModeUtil() {
|
||||
}
|
||||
|
||||
public static boolean isIncompleteMode(@NotNull PsiElement context) {
|
||||
if (!(context.getContainingFile() instanceof PsiJavaFile)) return false;
|
||||
return isIncompleteMode(context.getProject());
|
||||
}
|
||||
|
||||
public static boolean isIncompleteMode(@NotNull Project project) {
|
||||
return Registry.is("lombok.incomplete.mode.enabled", false) &&
|
||||
!project.getService(IncompleteDependenciesService.class).getState().isComplete();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package de.plushnikov.intellij.plugin.util;
|
||||
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
@@ -86,7 +85,7 @@ public final class LombokProcessorUtil {
|
||||
|
||||
public static Collection<String> getOldOnX(@NotNull PsiAnnotation psiAnnotation, @NotNull String parameterName) {
|
||||
PsiAnnotationMemberValue onXValue;
|
||||
if (DumbService.isDumb(psiAnnotation.getProject())) {
|
||||
if (PsiAnnotationSearchUtil.isDumbOrIncompleteMode(psiAnnotation)) {
|
||||
onXValue = psiAnnotation.findDeclaredAttributeValue(parameterName);
|
||||
}
|
||||
else {
|
||||
@@ -100,7 +99,7 @@ public final class LombokProcessorUtil {
|
||||
}
|
||||
|
||||
public static Collection<String> getNewOnX(@NotNull PsiAnnotation psiAnnotation, @NotNull String parameterName) {
|
||||
if (DumbService.isDumb(psiAnnotation.getProject()) || psiAnnotation.hasAttribute(parameterName)) {
|
||||
if (PsiAnnotationSearchUtil.isDumbOrIncompleteMode(psiAnnotation) || psiAnnotation.hasAttribute(parameterName)) {
|
||||
final Collection<PsiAnnotation> annotations =
|
||||
PsiAnnotationUtil.getAnnotationValues(psiAnnotation, parameterName, PsiAnnotation.class, List.of());
|
||||
return collectAnnotationStrings(annotations);
|
||||
|
||||
@@ -5,16 +5,19 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import de.plushnikov.intellij.plugin.processor.LombokProcessorManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
public final class PsiAnnotationSearchUtil {
|
||||
|
||||
@Nullable
|
||||
public static PsiAnnotation findAnnotation(@NotNull PsiModifierListOwner psiModifierListOwner, @NotNull String annotationFQN) {
|
||||
if (isDumbMode(psiModifierListOwner)) {
|
||||
if (isDumbOrIncompleteMode(psiModifierListOwner)) {
|
||||
return findAnnotationInDumbMode(psiModifierListOwner, annotationFQN);
|
||||
}
|
||||
return psiModifierListOwner.getAnnotation(annotationFQN);
|
||||
@@ -52,14 +55,15 @@ public final class PsiAnnotationSearchUtil {
|
||||
(mayBeOuterClass!=null && importList.findSingleClassImportStatement(mayBeOuterClass) != null);
|
||||
}
|
||||
|
||||
private static boolean isDumbMode(@NotNull PsiElement context) {
|
||||
public static boolean isDumbOrIncompleteMode(@NotNull PsiElement context) {
|
||||
Project project = context.getProject();
|
||||
return DumbService.isDumb(project);
|
||||
return DumbService.isDumb(project) ||
|
||||
IncompleteModeUtil.isIncompleteMode(context);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiAnnotation findAnnotation(@NotNull PsiModifierListOwner psiModifierListOwner, String @NotNull ... annotationFQNs) {
|
||||
boolean isDumbMode = isDumbMode(psiModifierListOwner);
|
||||
boolean isDumbMode = isDumbOrIncompleteMode(psiModifierListOwner);
|
||||
for (String annotationFQN : annotationFQNs) {
|
||||
PsiAnnotation annotation;
|
||||
if (isDumbMode) {
|
||||
@@ -76,7 +80,7 @@ public final class PsiAnnotationSearchUtil {
|
||||
}
|
||||
|
||||
public static boolean isAnnotatedWith(@NotNull PsiModifierListOwner psiModifierListOwner, @NotNull String annotationFQN) {
|
||||
if (isDumbMode(psiModifierListOwner)) {
|
||||
if (isDumbOrIncompleteMode(psiModifierListOwner)) {
|
||||
return findAnnotationInDumbMode(psiModifierListOwner, annotationFQN) != null;
|
||||
}
|
||||
return psiModifierListOwner.hasAnnotation(annotationFQN);
|
||||
@@ -129,9 +133,49 @@ public final class PsiAnnotationSearchUtil {
|
||||
|
||||
public static boolean checkAnnotationHasOneOfFQNs(@NotNull PsiAnnotation psiAnnotation,
|
||||
String @NotNull ... annotationFQNs) {
|
||||
if (isDumbMode(psiAnnotation)) {
|
||||
if (isDumbOrIncompleteMode(psiAnnotation)) {
|
||||
return ContainerUtil.or(annotationFQNs, fqn-> hasQualifiedNameInDumbMode(psiAnnotation, fqn));
|
||||
}
|
||||
return ContainerUtil.or(annotationFQNs, psiAnnotation::hasQualifiedName);
|
||||
}
|
||||
|
||||
public static boolean checkAnnotationHasOneOfFQNs(@NotNull PsiAnnotation psiAnnotation,
|
||||
@NotNull Set<String> annotationFQNs) {
|
||||
if (isDumbOrIncompleteMode(psiAnnotation)) {
|
||||
return ContainerUtil.or(annotationFQNs, fqn -> hasQualifiedNameInDumbMode(psiAnnotation, fqn));
|
||||
}
|
||||
return ContainerUtil.or(annotationFQNs, psiAnnotation::hasQualifiedName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the fully qualified name of a Lombok annotation based only on psi structure, without resolving.
|
||||
* Only annotations which have processors are supported
|
||||
*
|
||||
* @param psiAnnotation the PsiAnnotation object representing the Lombok annotation
|
||||
* @return the fully qualified name of the Lombok annotation, or null if the annotation is unresolved or not a Lombok annotation
|
||||
*/
|
||||
public static @Nullable String findLombokAnnotationQualifiedNameInIncompleteMode(@NotNull PsiAnnotation psiAnnotation) {
|
||||
String qualifiedName = psiAnnotation.getQualifiedName();
|
||||
if (StringUtil.isEmpty(qualifiedName)) return null;
|
||||
if (qualifiedName.startsWith("lombok")) return qualifiedName;
|
||||
LombokProcessorManager instance = LombokProcessorManager.getInstance();
|
||||
MultiMap<String, String> names = instance.getOurSupportedShortNames();
|
||||
Collection<String> fullQualifiedNames = names.get(qualifiedName);
|
||||
for (String fullQualifiedName : fullQualifiedNames) {
|
||||
if (hasQualifiedNameInDumbMode(psiAnnotation, fullQualifiedName)) {
|
||||
return fullQualifiedName;
|
||||
}
|
||||
}
|
||||
String proposedQualifiedName = "lombok." + qualifiedName;
|
||||
if (hasQualifiedNameInDumbMode(psiAnnotation, proposedQualifiedName)) {
|
||||
qualifiedName = proposedQualifiedName;
|
||||
}
|
||||
else {
|
||||
proposedQualifiedName = "lombok.experimental." + qualifiedName;
|
||||
if (hasQualifiedNameInDumbMode(psiAnnotation, proposedQualifiedName)) {
|
||||
qualifiedName = proposedQualifiedName;
|
||||
}
|
||||
}
|
||||
return qualifiedName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package de.plushnikov.intellij.plugin.util;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -43,7 +42,7 @@ public final class PsiAnnotationUtil {
|
||||
@NotNull List<T> defaultDumbValue) {
|
||||
Collection<T> result = Collections.emptyList();
|
||||
PsiAnnotationMemberValue attributeValue;
|
||||
if (DumbService.isDumb(psiAnnotation.getProject())) {
|
||||
if (PsiAnnotationSearchUtil.isDumbOrIncompleteMode(psiAnnotation)) {
|
||||
attributeValue = psiAnnotation.findDeclaredAttributeValue(parameter);
|
||||
if (attributeValue == null) return defaultDumbValue;
|
||||
}
|
||||
@@ -85,6 +84,10 @@ public final class PsiAnnotationUtil {
|
||||
|
||||
public static String getEnumAnnotationValue(@NotNull PsiAnnotation psiAnnotation, @NotNull String attributeName, @NotNull String defaultValue) {
|
||||
PsiAnnotationMemberValue attrValue = psiAnnotation.findDeclaredAttributeValue(attributeName);
|
||||
if (IncompleteModeUtil.isIncompleteMode(psiAnnotation) && attrValue instanceof PsiReferenceExpression referenceExpression) {
|
||||
//more or less good approximation if it is a complete mode
|
||||
return referenceExpression.getReferenceName();
|
||||
}
|
||||
String result = attrValue != null ? resolveElementValue(attrValue, String.class) : null;
|
||||
return result != null ? result : defaultValue;
|
||||
}
|
||||
|
||||
@@ -253,6 +253,8 @@
|
||||
|
||||
<registryKey key="lombok.dumb.mode.enabled" defaultValue="true" restartRequired="true"
|
||||
description="Lombok augment works in dumb mode"/>
|
||||
<registryKey key="lombok.incomplete.mode.enabled" defaultValue="true" restartRequired="true"
|
||||
description="Lombok supports incomplete mode"/>
|
||||
</extensions>
|
||||
|
||||
<projectListeners>
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
package de.plushnikov.intellij.plugin;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.IncompleteDependenciesService;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.pom.PomNamedTarget;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.testFramework.DumbModeTestUtils;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import com.intellij.util.ThrowableRunnable;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import de.plushnikov.intellij.plugin.util.IncompleteModeUtil;
|
||||
import de.plushnikov.intellij.plugin.util.PsiAnnotationSearchUtil;
|
||||
import de.plushnikov.intellij.plugin.util.PsiElementUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -19,6 +25,8 @@ import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static com.intellij.openapi.project.IncompleteDependenciesServiceKt.asAutoCloseable;
|
||||
|
||||
/**
|
||||
* Base test case for testing that the Lombok plugin parses the Lombok annotations correctly.
|
||||
*/
|
||||
@@ -26,10 +34,53 @@ public abstract class AbstractLombokParsingTestCase extends AbstractLombokLightC
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(AbstractLombokParsingTestCase.class);
|
||||
|
||||
@Nullable
|
||||
protected ModeRunnerType myRunnerType;
|
||||
|
||||
@NotNull
|
||||
protected List<ModeRunnerType> modes() {
|
||||
return List.of(ModeRunnerType.INCOMPLETE, ModeRunnerType.DUMB, ModeRunnerType.NORMAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* All tests are run in three modes: normal, incomplete and dumb mode.
|
||||
* If it is necessary to skip some of them, use @SkipMode
|
||||
*/
|
||||
@Override
|
||||
protected void runBare(@NotNull ThrowableRunnable<Throwable> testRunnable) throws Throwable {
|
||||
String testName = getName();
|
||||
|
||||
for (ModeRunnerType value : modes()) {
|
||||
myRunnerType = value;
|
||||
try {
|
||||
LOG.info("Method: " + testName + " starts with " + value);
|
||||
super.runBare(testRunnable);
|
||||
LOG.info("Method: " + testName + " finish with " + value);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
LOG.warn("Method: " + testName + "failed for " + value);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum ModeRunnerType {
|
||||
INCOMPLETE, DUMB, NORMAL
|
||||
}
|
||||
|
||||
protected boolean shouldCompareAnnotations() {
|
||||
return !".*".equals(annotationToComparePattern());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final @NotNull LightProjectDescriptor getProjectDescriptor() {
|
||||
return (myRunnerType == ModeRunnerType.INCOMPLETE) ? LombokTestUtil.WITHOUT_LOMBOK_DESCRIPTOR : getParsingDescriptor();
|
||||
}
|
||||
|
||||
protected @NotNull LightProjectDescriptor getParsingDescriptor() {
|
||||
return super.getProjectDescriptor();
|
||||
}
|
||||
|
||||
protected String annotationToComparePattern() {
|
||||
return ".*";
|
||||
}
|
||||
@@ -46,13 +97,25 @@ public abstract class AbstractLombokParsingTestCase extends AbstractLombokLightC
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
public void doTest(final boolean lowercaseFirstLetter) {
|
||||
doTest(getTestName(lowercaseFirstLetter));
|
||||
public final void doTest(final boolean lowercaseFirstLetter) {
|
||||
PsiManager.getInstance(getProject()).dropPsiCaches();
|
||||
if (myRunnerType == ModeRunnerType.DUMB) {
|
||||
DumbModeTestUtils.runInDumbModeSynchronously(getProject(),
|
||||
() -> compareFiles(lowercaseFirstLetter));
|
||||
}
|
||||
else if (myRunnerType == ModeRunnerType.INCOMPLETE) {
|
||||
IncompleteDependenciesService service = getProject().getService(IncompleteDependenciesService.class);
|
||||
try (var ignored = asAutoCloseable(WriteAction.compute(() -> service.enterIncompleteState()))) {
|
||||
compareFiles(lowercaseFirstLetter);
|
||||
}
|
||||
}
|
||||
else {
|
||||
compareFiles(lowercaseFirstLetter);
|
||||
}
|
||||
}
|
||||
|
||||
public void doTest(String testName) {
|
||||
DumbModeTestUtils.runInDumbModeSynchronously(getProject(),
|
||||
() -> compareFiles(loadBeforeLombokFile(testName), loadAfterDeLombokFile(testName)));
|
||||
protected void compareFiles(boolean lowercaseFirstLetter) {
|
||||
String testName = getTestName(lowercaseFirstLetter);
|
||||
compareFiles(loadBeforeLombokFile(testName), loadAfterDeLombokFile(testName));
|
||||
}
|
||||
|
||||
@@ -193,13 +256,13 @@ public abstract class AbstractLombokParsingTestCase extends AbstractLombokLightC
|
||||
private void compareAnnotations(PsiModifierList beforeModifierList, PsiModifierList afterModifierList) {
|
||||
if (shouldCompareAnnotations()) {
|
||||
Collection<String> beforeAnnotations = Arrays.stream(beforeModifierList.getAnnotations())
|
||||
.map(an-> getAnnotationQualifiedName(an))
|
||||
.map(an -> getAnnotationQualifiedName(an))
|
||||
.filter(Pattern.compile("lombok.*").asPredicate().negate().or(LombokClassNames.NON_NULL::equals))
|
||||
.filter(Pattern.compile(annotationToComparePattern()).asPredicate())
|
||||
.filter(Predicate.not(annotationsToIgnoreList()::contains))
|
||||
.toList();
|
||||
Collection<String> afterAnnotations = Arrays.stream(afterModifierList.getAnnotations())
|
||||
.map(an-> getAnnotationQualifiedName(an))
|
||||
.map(an -> getAnnotationQualifiedName(an))
|
||||
.filter(Pattern.compile(annotationToComparePattern()).asPredicate())
|
||||
.filter(Predicate.not(annotationsToIgnoreList()::contains))
|
||||
.toList();
|
||||
@@ -229,9 +292,17 @@ public abstract class AbstractLombokParsingTestCase extends AbstractLombokLightC
|
||||
.computeWithAlternativeResolveEnabled(() -> modifierList.findAnnotation(qualifiedName));
|
||||
}
|
||||
|
||||
private static @Nullable String getAnnotationQualifiedName(PsiAnnotation annotation) {
|
||||
return DumbService.getInstance(annotation.getProject())
|
||||
private static @NotNull String getAnnotationQualifiedName(@NotNull PsiAnnotation annotation) {
|
||||
String qualifiedName = DumbService.getInstance(annotation.getProject())
|
||||
.computeWithAlternativeResolveEnabled(() -> annotation.getQualifiedName());
|
||||
|
||||
if (!qualifiedName.contains(".") && IncompleteModeUtil.isIncompleteMode(annotation)) {
|
||||
String lombokAnnotation = PsiAnnotationSearchUtil.findLombokAnnotationQualifiedNameInIncompleteMode(annotation);
|
||||
if (lombokAnnotation.startsWith("lombok")) {
|
||||
qualifiedName = lombokAnnotation;
|
||||
}
|
||||
}
|
||||
return qualifiedName;
|
||||
}
|
||||
|
||||
private void compareMethods(PsiClass beforeClass, PsiClass afterClass) {
|
||||
@@ -245,7 +316,10 @@ public abstract class AbstractLombokParsingTestCase extends AbstractLombokLightC
|
||||
|
||||
final Collection<PsiMethod> matchedMethods = filterMethods(beforeMethods, afterMethod);
|
||||
if (matchedMethods.isEmpty()) {
|
||||
fail("Method names are not equal, Method: " + afterMethod.getPresentation().getPresentableText() + " not found in class : " + beforeClass.getName());
|
||||
fail("Method names are not equal, Method: " +
|
||||
afterMethod.getPresentation().getPresentableText() +
|
||||
" not found in class : " +
|
||||
beforeClass.getName());
|
||||
}
|
||||
|
||||
for (PsiMethod beforeMethod : matchedMethods) {
|
||||
@@ -326,7 +400,7 @@ public abstract class AbstractLombokParsingTestCase extends AbstractLombokLightC
|
||||
for (PsiClassType beforeType : beforeTypes) {
|
||||
boolean found = false;
|
||||
for (PsiClassType afterType : afterTypes) {
|
||||
boolean equals = dumbService.computeWithAlternativeResolveEnabled(()->beforeType.equals(afterType));
|
||||
boolean equals = dumbService.computeWithAlternativeResolveEnabled(() -> beforeType.equals(afterType));
|
||||
if (equals) {
|
||||
found = true;
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package de.plushnikov.intellij.plugin;
|
||||
|
||||
import org.junit.runners.BlockJUnit4ClassRunner;
|
||||
import org.junit.runners.model.InitializationError;
|
||||
|
||||
public class IncompleteAndDumbModeRunner extends BlockJUnit4ClassRunner {
|
||||
|
||||
public @interface InsertModeType {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public IncompleteAndDumbModeRunner(Class<?> testClass) throws InitializationError {
|
||||
super(testClass);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -34,6 +34,22 @@ public final class LombokTestUtil {
|
||||
}
|
||||
};
|
||||
|
||||
public static final DefaultLightProjectDescriptor WITHOUT_LOMBOK_DESCRIPTOR = new DefaultLightProjectDescriptor() {
|
||||
@Override
|
||||
public void configureModule(@NotNull Module module, @NotNull ModifiableRootModel model, @NotNull ContentEntry contentEntry) {
|
||||
DefaultLightProjectDescriptor.addJetBrainsAnnotations(model);
|
||||
MavenDependencyUtil.addFromMaven(model, JACKSON_MAVEN_COORDINATES);
|
||||
MavenDependencyUtil.addFromMaven(model, "com.google.guava:guava:27.0.1-jre");
|
||||
MavenDependencyUtil.addFromMaven(model, "org.slf4j:slf4j-api:1.7.30");
|
||||
model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(LanguageLevel.HIGHEST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sdk getSdk() {
|
||||
return IdeaTestUtil.getMockJdk18();
|
||||
}
|
||||
};
|
||||
|
||||
public static final DefaultLightProjectDescriptor LOMBOK_NEW_DESCRIPTOR = new DefaultLightProjectDescriptor() {
|
||||
@Override
|
||||
public void configureModule(@NotNull Module module, @NotNull ModifiableRootModel model, @NotNull ContentEntry contentEntry) {
|
||||
|
||||
@@ -5,9 +5,15 @@ import com.intellij.psi.PsiJavaFile;
|
||||
import de.plushnikov.intellij.plugin.AbstractLombokParsingTestCase;
|
||||
|
||||
public abstract class AbstractLombokConfigSystemTestCase extends AbstractLombokParsingTestCase {
|
||||
|
||||
@Override
|
||||
public void doTest() {
|
||||
final String fullFileName = getTestName(true).replace('$', '/') + ".java";
|
||||
doTest(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compareFiles(boolean lowercaseFirstLetter) {
|
||||
final String fullFileName = getTestName(lowercaseFirstLetter).replace('$', '/') + ".java";
|
||||
final int lastIndexOf = fullFileName.lastIndexOf('/');
|
||||
final String subPath = fullFileName.substring(0, lastIndexOf);
|
||||
final String fileName = fullFileName.substring(lastIndexOf + 1);
|
||||
@@ -25,6 +31,6 @@ public abstract class AbstractLombokConfigSystemTestCase extends AbstractLombokP
|
||||
fail("The test file type is not supported");
|
||||
}
|
||||
|
||||
compareFiles((PsiJavaFile) psiLombokFile, (PsiJavaFile) psiDelombokFile);
|
||||
compareFiles((PsiJavaFile)psiLombokFile, (PsiJavaFile)psiDelombokFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,6 @@ public class FieldDefaultsTest extends AbstractLombokConfigSystemTestCase {
|
||||
return super.getBasePath() + "/configsystem/fieldDefaults";
|
||||
}
|
||||
|
||||
//region DefaultFinal
|
||||
public void testDefaultFinal$DefaultFinalFieldTest() throws IOException {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testDefaultFinal$DefaultFinalFieldWithFieldDefaultsTest() throws IOException {
|
||||
doTest();
|
||||
@@ -31,10 +27,6 @@ public class FieldDefaultsTest extends AbstractLombokConfigSystemTestCase {
|
||||
//endregion
|
||||
|
||||
//region DefaultPrivate
|
||||
public void testDefaultPrivate$DefaultPrivateFieldTest() throws IOException {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testDefaultPrivate$DefaultPrivateFieldWithFieldDefaultsTest() throws IOException {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package de.plushnikov.intellij.plugin.configsystem;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Unit tests for IntelliJPlugin for Lombok with activated config system
|
||||
*/
|
||||
public class FieldDefaultsWithoutLombokImportTest extends AbstractLombokConfigSystemTestCase {
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return super.getBasePath() + "/configsystem/fieldDefaults";
|
||||
}
|
||||
|
||||
public void testDefaultFinal$DefaultFinalFieldTest() throws IOException {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testDefaultPrivate$DefaultPrivateFieldTest() throws IOException {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull List<ModeRunnerType> modes() {
|
||||
//incomplete mode is not supported, because files don't contain any lombok annotations,
|
||||
//checking lombok.config is expensive, so skip such cases
|
||||
//after returning to normal mode, caches will be dropped
|
||||
return List.of(ModeRunnerType.NORMAL, ModeRunnerType.DUMB);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,9 @@
|
||||
package de.plushnikov.intellij.plugin.configsystem;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class FieldNameConstantsTest extends AbstractLombokConfigSystemTestCase {
|
||||
|
||||
@Override
|
||||
@@ -14,4 +18,11 @@ public class FieldNameConstantsTest extends AbstractLombokConfigSystemTestCase {
|
||||
public void testUppercase$FieldNameConstantsUppercased() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull List<ModeRunnerType> modes() {
|
||||
//now incomplete mode is not supported for this processor, because it depends on the lombok version
|
||||
//after returning to normal mode, caches will be dropped
|
||||
return List.of(ModeRunnerType.NORMAL, ModeRunnerType.DUMB);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package de.plushnikov.intellij.plugin.configsystem;
|
||||
|
||||
import com.intellij.testFramework.DumbModeTestUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GetterDumbModeTest extends AbstractLombokConfigSystemTestCase {
|
||||
|
||||
@@ -38,4 +41,10 @@ public class GetterDumbModeTest extends AbstractLombokConfigSystemTestCase {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull List<ModeRunnerType> modes() {
|
||||
//use normal mode, because it is configured manually in tests
|
||||
return List.of(ModeRunnerType.NORMAL);
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class Builder16Test extends AbstractLombokParsingTestCase {
|
||||
|
||||
@Override
|
||||
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
|
||||
protected @NotNull LightProjectDescriptor getParsingDescriptor() {
|
||||
return LombokTestUtil.LOMBOK_NEW_DESCRIPTOR;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ import de.plushnikov.intellij.plugin.AbstractLombokParsingTestCase;
|
||||
import de.plushnikov.intellij.plugin.LombokTestUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Unit tests for @FieldNameConstants annotation from old version of lombok (1.18.2)
|
||||
*/
|
||||
@@ -12,11 +14,18 @@ public class FieldNameConstantsOldTest extends AbstractLombokParsingTestCase {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
protected LightProjectDescriptor getParsingDescriptor() {
|
||||
return LombokTestUtil.LOMBOK_OLD_DESCRIPTOR;
|
||||
}
|
||||
|
||||
public void testFieldnameconstants$FieldNameConstantsOldBasic() {
|
||||
doTest(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull List<ModeRunnerType> modes() {
|
||||
//now incomplete mode is not supported for this processor, because it depends on the lombok version
|
||||
//after returning to normal mode, caches will be dropped
|
||||
return List.of(ModeRunnerType.NORMAL, ModeRunnerType.DUMB);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import de.plushnikov.intellij.plugin.AbstractLombokParsingTestCase;
|
||||
import de.plushnikov.intellij.plugin.LombokTestUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Unit tests for @FieldNameConstants annotation from current version of lombok
|
||||
*/
|
||||
@@ -21,14 +23,21 @@ public class FieldNameConstantsTest extends AbstractLombokParsingTestCase {
|
||||
public void testFieldnameconstants$FieldNameConstantsHandrolled() {
|
||||
doTest(true);
|
||||
}
|
||||
|
||||
public void testFieldnameconstants$FieldNameConstantsOnRecord() {
|
||||
doTest(true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
protected LightProjectDescriptor getParsingDescriptor() {
|
||||
return LombokTestUtil.LOMBOK_NEW_DESCRIPTOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull List<ModeRunnerType> modes() {
|
||||
//now incomplete mode is not supported for this processor, because it depends on the lombok version
|
||||
//after returning to normal mode, caches will be dropped
|
||||
return List.of(ModeRunnerType.NORMAL, ModeRunnerType.DUMB);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,4 +18,7 @@ public class OnXAnnotationTest extends AbstractLombokParsingTestCase {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
public void testTestOnXSimple() {
|
||||
doTest(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,4 +7,4 @@ public class UtilityClassTest extends AbstractLombokParsingTestCase {
|
||||
public void testUtilityclass$UtilityClassPlain() {
|
||||
doTest(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,14 +6,14 @@ import javax.validation.Valid;
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.Size;
|
||||
import lombok.NonNull;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class TestOnX {
|
||||
@NonNull
|
||||
@NotNull
|
||||
private final Integer someIntField;
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
@NonNull
|
||||
@NotNull
|
||||
private String someStringField;
|
||||
private float someFloatField;
|
||||
|
||||
@@ -30,7 +30,7 @@ public class TestOnX {
|
||||
|
||||
@Inject
|
||||
@Named("myName1")
|
||||
public TestOnX(@NonNull Integer someIntField, @NonNull String someStringField) {
|
||||
public TestOnX(@NotNull Integer someIntField, @NotNull String someStringField) {
|
||||
if (someIntField == null) {
|
||||
throw new NullPointerException("someIntField is marked non-null but is null");
|
||||
} else if (someStringField == null) {
|
||||
@@ -43,7 +43,7 @@ public class TestOnX {
|
||||
|
||||
@Inject
|
||||
@Named("myName2")
|
||||
public TestOnX(@NonNull Integer someIntField, @NonNull String someStringField, float someFloatField) {
|
||||
public TestOnX(@NotNull Integer someIntField, @NotNull String someStringField, float someFloatField) {
|
||||
if (someIntField == null) {
|
||||
throw new NullPointerException("someIntField is marked non-null but is null");
|
||||
} else if (someStringField == null) {
|
||||
@@ -108,7 +108,7 @@ public class TestOnX {
|
||||
}
|
||||
|
||||
@Max(100)
|
||||
@NonNull
|
||||
@NotNull
|
||||
public Integer getSomeIntField() {
|
||||
return this.someIntField;
|
||||
}
|
||||
@@ -118,7 +118,7 @@ public class TestOnX {
|
||||
@Size(
|
||||
max = 20
|
||||
)
|
||||
@NonNull
|
||||
@NotNull
|
||||
public String getSomeStringField() {
|
||||
return this.someStringField;
|
||||
}
|
||||
@@ -128,7 +128,7 @@ public class TestOnX {
|
||||
@Size(
|
||||
min = 10
|
||||
)
|
||||
public void setSomeStringField(@Size(min = 15) @NonNull String someStringField) {
|
||||
public void setSomeStringField(@Size(min = 15) @NotNull String someStringField) {
|
||||
if (someStringField == null) {
|
||||
throw new NullPointerException("someStringField is marked non-null but is null");
|
||||
} else {
|
||||
@@ -136,7 +136,7 @@ public class TestOnX {
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@NotNull
|
||||
public TestOnX withSomeFloatField(@Min(1) float someFloatField) {
|
||||
return this.someFloatField == someFloatField ? this : new TestOnX(this.someIntField, this.someStringField, someFloatField);
|
||||
}
|
||||
|
||||
18
plugins/lombok/testData/after/TestOnXSimple.java
Normal file
18
plugins/lombok/testData/after/TestOnXSimple.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package action.delombok.onx;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
public class TestOnX {
|
||||
@NonNull
|
||||
private final Integer someIntField;
|
||||
|
||||
@Named("myName1")
|
||||
@Inject
|
||||
public TestOnX(@NonNull Integer someIntField) {
|
||||
this.someIntField = someIntField;
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import javax.validation.Valid;
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.Size;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@ToString
|
||||
@RequiredArgsConstructor(onConstructor_ = {@Inject, @Named("myName1")})
|
||||
@@ -15,16 +16,16 @@ import javax.validation.constraints.Size;
|
||||
@EqualsAndHashCode(onParam_ = @Valid)
|
||||
public class TestOnX {
|
||||
@Getter(onMethod_ = @Max(100))
|
||||
@NonNull
|
||||
@NotNull
|
||||
private final Integer someIntField;
|
||||
|
||||
@NonNull
|
||||
@NotNull
|
||||
@Deprecated
|
||||
@Getter(onMethod_ = @Size(max = 20))
|
||||
@Setter(onMethod_ = @Size(min = 10), onParam_ = @Size(min = 15))
|
||||
private String someStringField;
|
||||
|
||||
@With(onMethod_ = @NonNull, onParam_ = @Min(1))
|
||||
@With(onMethod_ = @NotNull, onParam_ = @Min(1))
|
||||
private float someFloatField;
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
13
plugins/lombok/testData/before/TestOnXSimple.java
Normal file
13
plugins/lombok/testData/before/TestOnXSimple.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package action.delombok.onx;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
@RequiredArgsConstructor(onConstructor_ = {@Inject, @Named("myName1")})
|
||||
public class TestOnX {
|
||||
@NonNull
|
||||
private final Integer someIntField;
|
||||
}
|
||||
Reference in New Issue
Block a user