mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-13 15:52:01 +07:00
[java-lombok] IDEA-352726 Augment class in dumb mode in Lombok
- support dumb mode GitOrigin-RevId: 93a6325ee1fa6ef515c579aa09bec9eb290ed967
This commit is contained in:
committed by
intellij-monorepo-bot
parent
b88da56f34
commit
2ca5b2bcd4
@@ -75,8 +75,9 @@ public final class SneakyThrowsExceptionHandler extends CustomExceptionHandler {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<PsiType> throwable = List.of(PsiType.getJavaLangThrowable(psiAnnotation.getManager(), psiAnnotation.getResolveScope()));
|
||||
final Collection<PsiType> sneakedExceptionTypes =
|
||||
PsiAnnotationUtil.getAnnotationValues(psiAnnotation, PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME, PsiType.class);
|
||||
PsiAnnotationUtil.getAnnotationValues(psiAnnotation, PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME, PsiType.class, throwable);
|
||||
//Default SneakyThrows handles all exceptions
|
||||
return sneakedExceptionTypes.isEmpty()
|
||||
|| sneakedExceptionTypes.iterator().next().equalsToText(JAVA_LANG_THROWABLE)
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package de.plushnikov.intellij.plugin.inspection;
|
||||
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.modcommand.ModPsiUpdater;
|
||||
import com.intellij.modcommand.PsiUpdateModCommandQuickFix;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -13,6 +15,7 @@ import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.javadoc.PsiDocTag;
|
||||
import com.intellij.psi.javadoc.PsiDocToken;
|
||||
import com.siyeh.ig.psiutils.CommentTracker;
|
||||
import de.plushnikov.intellij.plugin.util.PsiAnnotationSearchUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -21,7 +24,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class LombokGetterOrSetterMayBeUsedInspection extends LombokJavaInspectionBase {
|
||||
|
||||
@@ -58,7 +60,7 @@ public abstract class LombokGetterOrSetterMayBeUsedInspection extends LombokJava
|
||||
}
|
||||
boolean isLombokAnnotationAtClassLevel = true;
|
||||
for (PsiField field : psiClass.getFields()) {
|
||||
PsiAnnotation annotation = field.getAnnotation(getAnnotationName());
|
||||
PsiAnnotation annotation = PsiAnnotationSearchUtil.findAnnotation(field, getAnnotationName());
|
||||
if (annotation != null) {
|
||||
if (!annotation.getAttributes().isEmpty() || field.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
isLombokAnnotationAtClassLevel = false;
|
||||
@@ -183,7 +185,7 @@ public abstract class LombokGetterOrSetterMayBeUsedInspection extends LombokJava
|
||||
removeMethodAndMoveJavaDoc(field, method);
|
||||
}
|
||||
for (PsiField annotatedField : annotatedFields) {
|
||||
PsiAnnotation oldAnnotation = annotatedField.getAnnotation(getAnnotationName());
|
||||
PsiAnnotation oldAnnotation = PsiAnnotationSearchUtil.findAnnotation(annotatedField, getAnnotationName());
|
||||
if (oldAnnotation != null) {
|
||||
new CommentTracker().deleteAndRestoreComments(oldAnnotation);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
package de.plushnikov.intellij.plugin.inspection;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.SafeDeleteFix;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.codeInspection.RemoveAnnotationQuickFix;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteAnnotation;
|
||||
import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteOverrideAnnotation;
|
||||
import com.intellij.util.JavaPsiConstructorUtil;
|
||||
import de.plushnikov.intellij.plugin.LombokBundle;
|
||||
import de.plushnikov.intellij.plugin.LombokClassNames;
|
||||
@@ -19,6 +15,7 @@ import de.plushnikov.intellij.plugin.processor.Processor;
|
||||
import de.plushnikov.intellij.plugin.processor.ValProcessor;
|
||||
import de.plushnikov.intellij.plugin.psi.LombokLightMethodBuilder;
|
||||
import de.plushnikov.intellij.plugin.quickfix.PsiQuickFixFactory;
|
||||
import de.plushnikov.intellij.plugin.util.PsiAnnotationSearchUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -86,8 +83,8 @@ public final class LombokInspection extends LombokJavaInspectionBase {
|
||||
if (annotation.hasQualifiedName(LombokClassNames.BUILDER_DEFAULT)) {
|
||||
final PsiClass parentOfAnnotation = PsiTreeUtil.getParentOfType(annotation, PsiClass.class);
|
||||
if (null != parentOfAnnotation) {
|
||||
if (!parentOfAnnotation.hasAnnotation(LombokClassNames.BUILDER) &&
|
||||
!parentOfAnnotation.hasAnnotation(LombokClassNames.SUPER_BUILDER)) {
|
||||
if (!PsiAnnotationSearchUtil.isAnnotatedWith(parentOfAnnotation, LombokClassNames.BUILDER) &&
|
||||
!PsiAnnotationSearchUtil.isAnnotatedWith(parentOfAnnotation, LombokClassNames.SUPER_BUILDER)) {
|
||||
final LombokProblemInstance problemInstance = new LombokProblemInstance(
|
||||
LombokBundle.message("inspection.message.builder.default.requires.builder.annotation"), ProblemHighlightType.GENERIC_ERROR);
|
||||
problemInstance.withLocalQuickFixes(
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package de.plushnikov.intellij.plugin.inspection.modifiers;
|
||||
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.siyeh.ig.fixes.RemoveModifierFix;
|
||||
import de.plushnikov.intellij.plugin.inspection.LombokJavaInspectionBase;
|
||||
import de.plushnikov.intellij.plugin.util.PsiAnnotationSearchUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -82,8 +82,8 @@ public abstract class LombokRedundantModifierInspection extends LombokJavaInspec
|
||||
|| (infoType != RedundantModifiersInfoType.VARIABLE && !(parentModifierListOwner instanceof PsiClass))) {
|
||||
continue;
|
||||
}
|
||||
if ((supportedAnnotation == null || parentModifierListOwner.hasAnnotation(supportedAnnotation)) &&
|
||||
redundantModifiersInfo.getType().getSupportedClass().isAssignableFrom(psiModifierListOwner.getClass())) {
|
||||
if ((supportedAnnotation == null || PsiAnnotationSearchUtil.isAnnotatedWith(parentModifierListOwner, supportedAnnotation)) &&
|
||||
redundantModifiersInfo.getType().getSupportedClass().isAssignableFrom(psiModifierListOwner.getClass())) {
|
||||
PsiModifierList psiModifierList = psiModifierListOwner.getModifierList();
|
||||
if (psiModifierList == null ||
|
||||
(redundantModifiersInfo.getDontRunOnModifier() != null && psiModifierList.hasExplicitModifier(redundantModifiersInfo.getDontRunOnModifier()))) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package de.plushnikov.intellij.plugin.lombokconfig;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -124,6 +125,9 @@ public class ConfigDiscovery {
|
||||
|
||||
@Nullable
|
||||
private ConfigValue readProperty(@NotNull ConfigKey configKey, @NotNull Project project, @NotNull VirtualFile directory) {
|
||||
if (DumbService.getInstance(project).isAlternativeResolveEnabled()) {
|
||||
return LombokConfigIndex.readPropertyWithAlternativeResolver(configKey, project, directory);
|
||||
}
|
||||
GlobalSearchScope directoryScope = GlobalSearchScopes.directoryScope(project, directory, false);
|
||||
List<ConfigValue> values = getFileBasedIndex().getValues(LombokConfigIndex.NAME, configKey, directoryScope);
|
||||
if (!values.isEmpty()) {
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
package de.plushnikov.intellij.plugin.lombokconfig;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.indexing.*;
|
||||
@@ -16,6 +23,7 @@ import de.plushnikov.intellij.plugin.language.psi.LombokConfigFile;
|
||||
import de.plushnikov.intellij.plugin.language.psi.LombokConfigProperty;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
@@ -25,6 +33,8 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class LombokConfigIndex extends FileBasedIndexExtension<ConfigKey, ConfigValue> {
|
||||
@NotNull
|
||||
private static final String LOMBOK_CONFIG_FILE_NAME = "lombok.config";
|
||||
@NonNls
|
||||
public static final ID<ConfigKey, ConfigValue> NAME = ID.create("LombokConfigIndex");
|
||||
|
||||
@@ -41,56 +51,64 @@ public final class LombokConfigIndex extends FileBasedIndexExtension<ConfigKey,
|
||||
@NotNull
|
||||
@Override
|
||||
public Map<ConfigKey, ConfigValue> map(@NotNull FileContent inputData) {
|
||||
Map<ConfigKey, ConfigValue> result = Collections.emptyMap();
|
||||
|
||||
final VirtualFile directoryFile = inputData.getFile().getParent();
|
||||
if (null != directoryFile) {
|
||||
final String canonicalPath = PathUtil.toSystemIndependentName(directoryFile.getCanonicalPath());
|
||||
if (null != canonicalPath) {
|
||||
final Map<String, String> configValues = extractValues((LombokConfigFile)inputData.getPsiFile());
|
||||
|
||||
final boolean stopBubblingValue = Boolean.parseBoolean(configValues.get(StringUtil.toLowerCase(ConfigKey.CONFIG_STOP_BUBBLING.getConfigKey())));
|
||||
result = ContainerUtil.map2Map(ConfigKey.values(),
|
||||
key -> Pair.create(key,
|
||||
new ConfigValue(configValues.get(StringUtil.toLowerCase(key.getConfigKey())), stopBubblingValue)));
|
||||
PsiFile psiFile = inputData.getPsiFile();
|
||||
return createConfigMapResult(psiFile);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Map<String, String> extractValues(LombokConfigFile configFile) {
|
||||
Map<String, String> result = new HashMap<>();
|
||||
|
||||
final LombokConfigCleaner[] configCleaners = LombokConfigUtil.getLombokConfigCleaners(configFile);
|
||||
for (LombokConfigCleaner configCleaner : configCleaners) {
|
||||
final String key = StringUtil.toLowerCase(configCleaner.getKey());
|
||||
|
||||
final ConfigKey configKey = ConfigKey.fromConfigStringKey(key);
|
||||
if (null != configKey) {
|
||||
result.put(key, configKey.getConfigDefaultValue());
|
||||
}
|
||||
}
|
||||
|
||||
final LombokConfigProperty[] configProperties = LombokConfigUtil.getLombokConfigProperties(configFile);
|
||||
for (LombokConfigProperty configProperty : configProperties) {
|
||||
final String key = StringUtil.toLowerCase(configProperty.getKey());
|
||||
final String value = configProperty.getValue();
|
||||
final String sign = configProperty.getSign();
|
||||
if (null == sign) {
|
||||
result.put(key, value);
|
||||
}
|
||||
else {
|
||||
final String previousValue = StringUtil.defaultIfEmpty(result.get(key), "");
|
||||
final String combinedValue = previousValue + sign + value + ";";
|
||||
result.put(key, combinedValue);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static @NotNull Map<ConfigKey, ConfigValue> createConfigMapResult(@Nullable PsiFile psiFile) {
|
||||
if (!(psiFile instanceof LombokConfigFile)) {
|
||||
return Map.of();
|
||||
}
|
||||
final Map<String, String> configValues = extractValues((LombokConfigFile)psiFile);
|
||||
|
||||
final boolean stopBubblingValue =
|
||||
Boolean.parseBoolean(configValues.get(StringUtil.toLowerCase(ConfigKey.CONFIG_STOP_BUBBLING.getConfigKey())));
|
||||
return ContainerUtil.map2Map(ConfigKey.values(),
|
||||
key -> Pair.create(key,
|
||||
new ConfigValue(configValues.get(StringUtil.toLowerCase(key.getConfigKey())),
|
||||
stopBubblingValue)));
|
||||
}
|
||||
|
||||
private static Map<String, String> extractValues(LombokConfigFile configFile) {
|
||||
Map<String, String> result = new HashMap<>();
|
||||
|
||||
final LombokConfigCleaner[] configCleaners = LombokConfigUtil.getLombokConfigCleaners(configFile);
|
||||
for (LombokConfigCleaner configCleaner : configCleaners) {
|
||||
final String key = StringUtil.toLowerCase(configCleaner.getKey());
|
||||
|
||||
final ConfigKey configKey = ConfigKey.fromConfigStringKey(key);
|
||||
if (null != configKey) {
|
||||
result.put(key, configKey.getConfigDefaultValue());
|
||||
}
|
||||
}
|
||||
|
||||
final LombokConfigProperty[] configProperties = LombokConfigUtil.getLombokConfigProperties(configFile);
|
||||
for (LombokConfigProperty configProperty : configProperties) {
|
||||
final String key = StringUtil.toLowerCase(configProperty.getKey());
|
||||
final String value = configProperty.getValue();
|
||||
final String sign = configProperty.getSign();
|
||||
if (null == sign) {
|
||||
result.put(key, value);
|
||||
}
|
||||
else {
|
||||
final String previousValue = StringUtil.defaultIfEmpty(result.get(key), "");
|
||||
final String combinedValue = previousValue + sign + value + ";";
|
||||
result.put(key, combinedValue);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public KeyDescriptor<ConfigKey> getKeyDescriptor() {
|
||||
@@ -134,4 +152,27 @@ public final class LombokConfigIndex extends FileBasedIndexExtension<ConfigKey,
|
||||
public int getVersion() {
|
||||
return 14;
|
||||
}
|
||||
|
||||
static @Nullable ConfigValue readPropertyWithAlternativeResolver(@NotNull ConfigKey key,
|
||||
@NotNull Project project,
|
||||
@NotNull VirtualFile directory) {
|
||||
VirtualFile configVirtualFile = directory.findFileByRelativePath(LOMBOK_CONFIG_FILE_NAME);
|
||||
if (configVirtualFile == null) {
|
||||
return null;
|
||||
}
|
||||
Document document = FileDocumentManager.getInstance().getDocument(configVirtualFile);
|
||||
if (document == null) {
|
||||
return null;
|
||||
}
|
||||
PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document);
|
||||
if (psiFile == null) {
|
||||
return null;
|
||||
}
|
||||
Map<ConfigKey, ConfigValue> values = CachedValuesManager.getCachedValue(psiFile, () -> {
|
||||
Map<ConfigKey, ConfigValue> result = createConfigMapResult(psiFile);
|
||||
//CONFIG_CHANGE_TRACKER is not really accurate, but it is already used for this purpose
|
||||
return CachedValueProvider.Result.create(result, LombokConfigChangeListener.CONFIG_CHANGE_TRACKER);
|
||||
});
|
||||
return values.get(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,8 +62,8 @@ public final class EqualsAndHashCodeProcessor extends AbstractClassProcessor {
|
||||
}
|
||||
|
||||
if (problemSink.deepValidation()) {
|
||||
final Collection<String> excludeProperty = PsiAnnotationUtil.getAnnotationValues(psiAnnotation, "exclude", String.class);
|
||||
final Collection<String> ofProperty = PsiAnnotationUtil.getAnnotationValues(psiAnnotation, "of", String.class);
|
||||
final Collection<String> excludeProperty = PsiAnnotationUtil.getAnnotationValues(psiAnnotation, "exclude", String.class, List.of());
|
||||
final Collection<String> ofProperty = PsiAnnotationUtil.getAnnotationValues(psiAnnotation, "of", String.class, List.of());
|
||||
|
||||
if (!excludeProperty.isEmpty() && !ofProperty.isEmpty()) {
|
||||
problemSink.addWarningMessage("inspection.message.exclude.are.mutually.exclusive.exclude.parameter.will.be.ignored")
|
||||
|
||||
@@ -55,8 +55,8 @@ public final class ToStringProcessor extends AbstractClassProcessor {
|
||||
}
|
||||
|
||||
if (problemSink.deepValidation()) {
|
||||
final Collection<String> excludeProperty = PsiAnnotationUtil.getAnnotationValues(psiAnnotation, "exclude", String.class);
|
||||
final Collection<String> ofProperty = PsiAnnotationUtil.getAnnotationValues(psiAnnotation, "of", String.class);
|
||||
final Collection<String> excludeProperty = PsiAnnotationUtil.getAnnotationValues(psiAnnotation, "exclude", String.class, List.of());
|
||||
final Collection<String> ofProperty = PsiAnnotationUtil.getAnnotationValues(psiAnnotation, "of", String.class, List.of());
|
||||
|
||||
if (!excludeProperty.isEmpty() && !ofProperty.isEmpty()) {
|
||||
problemSink.addWarningMessage("inspection.message.exclude.are.mutually.exclusive.exclude.parameter.will.be.ignored")
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Plushnikov Michail
|
||||
@@ -148,7 +149,7 @@ public class AccessorsInfo {
|
||||
Boolean chainDeclaredValue = PsiAnnotationUtil.getDeclaredBooleanAnnotationValue(accessorsAnnotation, CHAIN_VALUE);
|
||||
Boolean fluentDeclaredValue = PsiAnnotationUtil.getDeclaredBooleanAnnotationValue(accessorsAnnotation, FLUENT_VALUE);
|
||||
Boolean makeFinalDeclaredValue = PsiAnnotationUtil.getDeclaredBooleanAnnotationValue(accessorsAnnotation, MAKE_FINAL_VALUE);
|
||||
Collection<String> prefixes = PsiAnnotationUtil.getAnnotationValues(accessorsAnnotation, PREFIX_VALUE, String.class);
|
||||
Collection<String> prefixes = PsiAnnotationUtil.getAnnotationValues(accessorsAnnotation, PREFIX_VALUE, String.class, List.of());
|
||||
return new AccessorsValues(chainDeclaredValue, fluentDeclaredValue, makeFinalDeclaredValue, prefixes);
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ public class BuilderHandler {
|
||||
|
||||
public static Map<String, List<List<PsiType>>> getExistingMethodsWithParameterTypes(@NotNull PsiClass psiClass) {
|
||||
return PsiClassUtil.collectClassMethodsIntern(psiClass).stream()
|
||||
.filter(psiMethod -> !psiMethod.hasAnnotation(LombokClassNames.TOLERATE))
|
||||
.filter(psiMethod -> !PsiAnnotationSearchUtil.isAnnotatedWith(psiMethod, LombokClassNames.TOLERATE))
|
||||
.collect(Collectors.groupingBy(PsiMethod::getName,
|
||||
Collectors.mapping(BuilderHandler::getMethodParameterTypes, Collectors.toList())));
|
||||
}
|
||||
|
||||
@@ -63,8 +63,8 @@ public class BuilderInfo {
|
||||
result.capitalizationStrategy = CapitalizationStrategy.defaultValue();
|
||||
result.deprecated = PsiImplUtil.isDeprecated(psiVariable);
|
||||
|
||||
result.hasBuilderDefaultAnnotation = psiVariable.hasAnnotation(BUILDER_DEFAULT_ANNOTATION);
|
||||
result.singularAnnotation = psiVariable.getAnnotation(LombokClassNames.SINGULAR);
|
||||
result.hasBuilderDefaultAnnotation = PsiAnnotationSearchUtil.isAnnotatedWith(psiVariable, BUILDER_DEFAULT_ANNOTATION);
|
||||
result.singularAnnotation = PsiAnnotationSearchUtil.findAnnotation(psiVariable, LombokClassNames.SINGULAR);
|
||||
result.builderElementHandler = SingularHandlerFactory.getHandlerFor(psiVariable, null != result.singularAnnotation);
|
||||
|
||||
result.nullAnnotationLibrary = LombokNullAnnotationLibraryDefned.NONE;
|
||||
|
||||
@@ -88,7 +88,7 @@ public final class DelegateHandler {
|
||||
}
|
||||
|
||||
private static Collection<PsiType> collectDelegateTypes(PsiAnnotation psiAnnotation, PsiType psiType) {
|
||||
Collection<PsiType> types = PsiAnnotationUtil.getAnnotationValues(psiAnnotation, TYPES_PARAMETER, PsiType.class);
|
||||
Collection<PsiType> types = PsiAnnotationUtil.getAnnotationValues(psiAnnotation, TYPES_PARAMETER, PsiType.class, List.of());
|
||||
if (types.isEmpty()) {
|
||||
types = Collections.singletonList(psiType);
|
||||
}
|
||||
@@ -129,7 +129,7 @@ public final class DelegateHandler {
|
||||
}
|
||||
|
||||
private static Collection<PsiType> collectExcludeTypes(PsiAnnotation psiAnnotation) {
|
||||
return PsiAnnotationUtil.getAnnotationValues(psiAnnotation, EXCLUDES_PARAMETER, PsiType.class);
|
||||
return PsiAnnotationUtil.getAnnotationValues(psiAnnotation, EXCLUDES_PARAMETER, PsiType.class, List.of());
|
||||
}
|
||||
|
||||
public static <T extends PsiMember & PsiNamedElement> void generateElements(@NotNull T psiElement,
|
||||
|
||||
@@ -100,9 +100,9 @@ public final class EqualsAndHashCodeToStringHandler {
|
||||
final Collection<String> excludeProperty;
|
||||
if (!explicitOf) {
|
||||
ofProperty = Collections.emptyList();
|
||||
excludeProperty = makeSet(PsiAnnotationUtil.getAnnotationValues(psiAnnotation, "exclude", String.class));
|
||||
excludeProperty = makeSet(PsiAnnotationUtil.getAnnotationValues(psiAnnotation, "exclude", String.class, List.of()));
|
||||
} else {
|
||||
ofProperty = makeSet(PsiAnnotationUtil.getAnnotationValues(psiAnnotation, "of", String.class));
|
||||
ofProperty = makeSet(PsiAnnotationUtil.getAnnotationValues(psiAnnotation, "of", String.class, List.of()));
|
||||
excludeProperty = Collections.emptyList();
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import de.plushnikov.intellij.plugin.LombokClassNames;
|
||||
import de.plushnikov.intellij.plugin.psi.LombokExtensionMethod;
|
||||
import de.plushnikov.intellij.plugin.psi.LombokLightParameter;
|
||||
import de.plushnikov.intellij.plugin.util.PsiAnnotationSearchUtil;
|
||||
import de.plushnikov.intellij.plugin.util.PsiAnnotationUtil;
|
||||
import de.plushnikov.intellij.plugin.util.PsiClassUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -43,10 +44,10 @@ public final class ExtensionMethodsHelper {
|
||||
|
||||
@Nullable PsiClass context = PsiTreeUtil.getContextOfType(place, PsiClass.class);
|
||||
while (context != null) {
|
||||
final @Nullable PsiAnnotation annotation = context.getAnnotation(LombokClassNames.EXTENSION_METHOD);
|
||||
final @Nullable PsiAnnotation annotation = PsiAnnotationSearchUtil.findAnnotation(context, LombokClassNames.EXTENSION_METHOD);
|
||||
if (annotation != null) {
|
||||
|
||||
final Set<PsiClass> providers = PsiAnnotationUtil.getAnnotationValues(annotation, PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME, PsiType.class).stream()
|
||||
final Set<PsiClass> providers = PsiAnnotationUtil.getAnnotationValues(annotation, PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME, PsiType.class, List.of()).stream()
|
||||
.filter(PsiClassType.class::isInstance)
|
||||
.map(PsiClassType.class::cast)
|
||||
.map(PsiClassType::resolve)
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package de.plushnikov.intellij.plugin.provider;
|
||||
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.PossiblyDumbAware;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.augment.PsiAugmentProvider;
|
||||
import com.intellij.psi.augment.PsiExtensionMethod;
|
||||
@@ -28,7 +31,7 @@ import static de.plushnikov.intellij.plugin.util.LombokLibraryUtil.hasLombokLibr
|
||||
*
|
||||
* @author Plushnikov Michail
|
||||
*/
|
||||
public final class LombokAugmentProvider extends PsiAugmentProvider {
|
||||
public final class LombokAugmentProvider extends PsiAugmentProvider implements PossiblyDumbAware {
|
||||
private static final class Holder {
|
||||
static final Collection<ModifierProcessor> modifierProcessors = LombokProcessorManager.getLombokModifierProcessors();
|
||||
}
|
||||
@@ -36,6 +39,11 @@ public final class LombokAugmentProvider extends PsiAugmentProvider {
|
||||
public LombokAugmentProvider() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDumbAware() {
|
||||
return Registry.is("lombok.dumb.mode.enabled", false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Set<String> transformModifiers(@NotNull PsiModifierList modifierList, @NotNull final Set<String> modifiers) {
|
||||
@@ -47,18 +55,30 @@ public final class LombokAugmentProvider extends PsiAugmentProvider {
|
||||
// make copy of original modifiers
|
||||
Set<String> result = new HashSet<>(modifiers);
|
||||
|
||||
// Loop through all available processors and give all of them a chance to respond
|
||||
for (ModifierProcessor processor : Holder.modifierProcessors) {
|
||||
if (processor.isSupported(modifierList)) {
|
||||
processor.transformModifiers(modifierList, result);
|
||||
DumbService dumbService = DumbService.getInstance(modifierList.getProject());
|
||||
Runnable runnable = () -> {
|
||||
// Loop through all available processors and give all of them a chance to respond
|
||||
for (ModifierProcessor processor : Holder.modifierProcessors) {
|
||||
if (processor.isSupported(modifierList)) {
|
||||
processor.transformModifiers(modifierList, result);
|
||||
}
|
||||
}
|
||||
};
|
||||
if (dumbService.isDumb() && !dumbService.isAlternativeResolveEnabled()) {
|
||||
dumbService.runWithAlternativeResolveEnabled(() -> runnable.run());
|
||||
}
|
||||
else {
|
||||
runnable.run();
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInferType(@NotNull PsiTypeElement typeElement) {
|
||||
//skip if dumb mode, allow only `getAugments`
|
||||
if (DumbService.isDumb(typeElement.getProject())) return false;
|
||||
|
||||
return hasLombokLibrary(typeElement.getProject()) && ValProcessor.canInferType(typeElement);
|
||||
}
|
||||
|
||||
@@ -75,7 +95,10 @@ public final class LombokAugmentProvider extends PsiAugmentProvider {
|
||||
//see com.intellij.java.lomboktest.LombokHighlightingTest.testGetterLazyVariableNotInitialized
|
||||
@Override
|
||||
protected boolean fieldInitializerMightBeChanged(@NotNull PsiField field) {
|
||||
if (field.hasAnnotation(LombokClassNames.BUILDER_DEFAULT)) {
|
||||
//skip if dumb mode, allow only `getAugments`
|
||||
if (DumbService.isDumb(field.getProject())) return false;
|
||||
|
||||
if (PsiAnnotationSearchUtil.isAnnotatedWith(field, LombokClassNames.BUILDER_DEFAULT)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -104,6 +127,9 @@ public final class LombokAugmentProvider extends PsiAugmentProvider {
|
||||
@Nullable
|
||||
@Override
|
||||
protected PsiType inferType(@NotNull PsiTypeElement typeElement) {
|
||||
//skip if dumb mode, allow only `getAugments`
|
||||
if (DumbService.isDumb(typeElement.getProject())) return null;
|
||||
|
||||
return hasLombokLibrary(typeElement.getProject()) ? ValProcessor.inferType(typeElement) : null;
|
||||
}
|
||||
|
||||
@@ -145,7 +171,10 @@ public final class LombokAugmentProvider extends PsiAugmentProvider {
|
||||
|
||||
// All invoker of AugmentProvider already make caching,
|
||||
// and we want to try to skip recursive calls completely
|
||||
|
||||
DumbService dumbService = DumbService.getInstance(psiClass.getProject());
|
||||
if (DumbService.isDumb(psiClass.getProject()) && !dumbService.isAlternativeResolveEnabled()) {
|
||||
return dumbService.computeWithAlternativeResolveEnabled(()-> getPsis(psiClass, type, nameHint));
|
||||
}
|
||||
return getPsis(psiClass, type, nameHint);
|
||||
}
|
||||
|
||||
@@ -165,6 +194,9 @@ public final class LombokAugmentProvider extends PsiAugmentProvider {
|
||||
protected List<PsiExtensionMethod> getExtensionMethods(@NotNull PsiClass aClass,
|
||||
@NotNull String nameHint,
|
||||
@NotNull PsiElement context) {
|
||||
//skip if dumb mode, allow only `getAugments`
|
||||
if (DumbService.isDumb(aClass.getProject())) return Collections.emptyList();
|
||||
|
||||
if (!hasLombokLibrary(context.getProject())) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package de.plushnikov.intellij.plugin.psi;
|
||||
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.ElementPresentationUtil;
|
||||
@@ -101,7 +102,16 @@ public class LombokLightClassBuilder extends LightPsiClassBuilder implements Psi
|
||||
@Override
|
||||
public PsiField @NotNull [] getFields() {
|
||||
if (null == myFields) {
|
||||
Collection<PsiField> generatedFields = fieldSupplier.apply(this);
|
||||
Collection<PsiField> generatedFields;
|
||||
DumbService dumbService = DumbService.getInstance(getProject());
|
||||
if (dumbService.isDumb() && !dumbService.isAlternativeResolveEnabled()) {
|
||||
generatedFields = dumbService.computeWithAlternativeResolveEnabled(
|
||||
() -> fieldSupplier.apply(this)
|
||||
);
|
||||
}
|
||||
else {
|
||||
generatedFields = fieldSupplier.apply(this);
|
||||
}
|
||||
myFields = generatedFields.toArray(PsiField.EMPTY_ARRAY);
|
||||
fieldSupplier = c -> Collections.emptyList();
|
||||
}
|
||||
@@ -111,7 +121,16 @@ public class LombokLightClassBuilder extends LightPsiClassBuilder implements Psi
|
||||
@Override
|
||||
public PsiMethod @NotNull [] getMethods() {
|
||||
if (null == myMethods) {
|
||||
Collection<PsiMethod> generatedMethods = methodSupplier.apply(this);
|
||||
Collection<PsiMethod> generatedMethods;
|
||||
DumbService dumbService = DumbService.getInstance(getProject());
|
||||
if (dumbService.isDumb() && !dumbService.isAlternativeResolveEnabled()) {
|
||||
generatedMethods = dumbService.computeWithAlternativeResolveEnabled(
|
||||
() -> methodSupplier.apply(this)
|
||||
);
|
||||
}
|
||||
else {
|
||||
generatedMethods = methodSupplier.apply(this);
|
||||
}
|
||||
myMethods = generatedMethods.toArray(PsiMethod.EMPTY_ARRAY);
|
||||
methodSupplier = c -> Collections.emptyList();
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package de.plushnikov.intellij.plugin.psi;
|
||||
import com.intellij.codeInspection.dataFlow.JavaMethodContractUtil;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.ModificationTracker;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
@@ -189,7 +190,15 @@ public class LombokLightMethodBuilder extends LightMethodBuilder implements Synt
|
||||
Function<LombokLightMethodBuilder, String> builderBodyFunction = myBuilderBodyFunction;
|
||||
if (null == myBodyCodeBlock && (bodyAsText != null || builderBodyFunction != null)) {
|
||||
if (bodyAsText == null) {
|
||||
bodyAsText = builderBodyFunction.apply(this);
|
||||
DumbService dumbService = DumbService.getInstance(getProject());
|
||||
if (dumbService.isDumb() && !dumbService.isAlternativeResolveEnabled()) {
|
||||
bodyAsText = dumbService.computeWithAlternativeResolveEnabled(
|
||||
() -> builderBodyFunction.apply(this)
|
||||
);
|
||||
}
|
||||
else {
|
||||
bodyAsText = builderBodyFunction.apply(this);
|
||||
}
|
||||
}
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(getProject());
|
||||
myBodyCodeBlock = elementFactory.createCodeBlockFromText("{" + bodyAsText + "}", this);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
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;
|
||||
@@ -84,18 +85,24 @@ public final class LombokProcessorUtil {
|
||||
}
|
||||
|
||||
public static Collection<String> getOldOnX(@NotNull PsiAnnotation psiAnnotation, @NotNull String parameterName) {
|
||||
PsiAnnotationMemberValue onXValue = psiAnnotation.hasAttribute(parameterName) ? psiAnnotation.findAttributeValue(parameterName) : null;
|
||||
PsiAnnotationMemberValue onXValue;
|
||||
if (DumbService.isDumb(psiAnnotation.getProject())) {
|
||||
onXValue = psiAnnotation.findDeclaredAttributeValue(parameterName);
|
||||
}
|
||||
else {
|
||||
onXValue = psiAnnotation.hasAttribute(parameterName) ? psiAnnotation.findAttributeValue(parameterName) : null;
|
||||
}
|
||||
if (!(onXValue instanceof PsiAnnotation)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Collection<PsiAnnotation> annotations = PsiAnnotationUtil.getAnnotationValues((PsiAnnotation)onXValue, "value", PsiAnnotation.class);
|
||||
Collection<PsiAnnotation> annotations = PsiAnnotationUtil.getAnnotationValues((PsiAnnotation)onXValue, "value", PsiAnnotation.class, List.of());
|
||||
return collectAnnotationStrings(annotations);
|
||||
}
|
||||
|
||||
public static Collection<String> getNewOnX(@NotNull PsiAnnotation psiAnnotation, @NotNull String parameterName) {
|
||||
if (psiAnnotation.hasAttribute(parameterName)) {
|
||||
if (DumbService.isDumb(psiAnnotation.getProject()) || psiAnnotation.hasAttribute(parameterName)) {
|
||||
final Collection<PsiAnnotation> annotations =
|
||||
PsiAnnotationUtil.getAnnotationValues(psiAnnotation, parameterName, PsiAnnotation.class);
|
||||
PsiAnnotationUtil.getAnnotationValues(psiAnnotation, parameterName, PsiAnnotation.class, List.of());
|
||||
return collectAnnotationStrings(annotations);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package de.plushnikov.intellij.plugin.util;
|
||||
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiJavaCodeReferenceElement;
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -14,13 +14,60 @@ public final class PsiAnnotationSearchUtil {
|
||||
|
||||
@Nullable
|
||||
public static PsiAnnotation findAnnotation(@NotNull PsiModifierListOwner psiModifierListOwner, @NotNull String annotationFQN) {
|
||||
if (isDumbMode(psiModifierListOwner)) {
|
||||
return findAnnotationInDumbMode(psiModifierListOwner, annotationFQN);
|
||||
}
|
||||
return psiModifierListOwner.getAnnotation(annotationFQN);
|
||||
}
|
||||
|
||||
private static @Nullable PsiAnnotation findAnnotationInDumbMode(@NotNull PsiModifierListOwner owner, @NotNull String annotationFQN) {
|
||||
for (PsiAnnotation annotation : owner.getAnnotations()) {
|
||||
if (hasQualifiedNameInDumbMode(annotation, annotationFQN)) {
|
||||
return annotation;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean hasQualifiedNameInDumbMode(PsiAnnotation annotation, @NotNull String fqn) {
|
||||
PsiJavaCodeReferenceElement referenceElement = annotation.getNameReferenceElement();
|
||||
if (referenceElement == null) return false;
|
||||
String qualifiedName = referenceElement.getReferenceName();
|
||||
if (qualifiedName == null) return false;
|
||||
if (qualifiedName.equals(fqn)) return true;
|
||||
String referenceElementText = referenceElement.getText();
|
||||
if (referenceElementText != null && referenceElementText.equals(fqn)) return true;
|
||||
if (!fqn.endsWith(qualifiedName)) return false;
|
||||
PsiFile containingFile = annotation.getContainingFile();
|
||||
if (!(containingFile instanceof PsiJavaFile javaFile)) {
|
||||
return false;
|
||||
}
|
||||
String packageName = StringUtil.getPackageName(fqn);
|
||||
PsiImportList importList = javaFile.getImportList();
|
||||
if (importList == null) return false;
|
||||
int indexMayByOuterClass = fqn.length() - qualifiedName.length() - 1;
|
||||
String mayBeOuterClass = indexMayByOuterClass > 0 ? fqn.substring(0, indexMayByOuterClass) : null;
|
||||
return importList.findOnDemandImportStatement(packageName) != null ||
|
||||
importList.findSingleClassImportStatement(fqn) != null ||
|
||||
(mayBeOuterClass!=null && importList.findSingleClassImportStatement(mayBeOuterClass) != null);
|
||||
}
|
||||
|
||||
private static boolean isDumbMode(@NotNull PsiElement context) {
|
||||
Project project = context.getProject();
|
||||
return DumbService.isDumb(project);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiAnnotation findAnnotation(@NotNull PsiModifierListOwner psiModifierListOwner, String @NotNull ... annotationFQNs) {
|
||||
boolean isDumbMode = isDumbMode(psiModifierListOwner);
|
||||
for (String annotationFQN : annotationFQNs) {
|
||||
PsiAnnotation annotation = psiModifierListOwner.getAnnotation(annotationFQN);
|
||||
PsiAnnotation annotation;
|
||||
if (isDumbMode) {
|
||||
annotation = findAnnotationInDumbMode(psiModifierListOwner, annotationFQN);
|
||||
}
|
||||
else {
|
||||
annotation = psiModifierListOwner.getAnnotation(annotationFQN);
|
||||
}
|
||||
if (annotation != null) {
|
||||
return annotation;
|
||||
}
|
||||
@@ -29,6 +76,9 @@ public final class PsiAnnotationSearchUtil {
|
||||
}
|
||||
|
||||
public static boolean isAnnotatedWith(@NotNull PsiModifierListOwner psiModifierListOwner, @NotNull String annotationFQN) {
|
||||
if (isDumbMode(psiModifierListOwner)) {
|
||||
return findAnnotationInDumbMode(psiModifierListOwner, annotationFQN) != null;
|
||||
}
|
||||
return psiModifierListOwner.hasAnnotation(annotationFQN);
|
||||
}
|
||||
|
||||
@@ -79,6 +129,9 @@ public final class PsiAnnotationSearchUtil {
|
||||
|
||||
public static boolean checkAnnotationHasOneOfFQNs(@NotNull PsiAnnotation psiAnnotation,
|
||||
String @NotNull ... annotationFQNs) {
|
||||
if (isDumbMode(psiAnnotation)) {
|
||||
return ContainerUtil.or(annotationFQNs, fqn-> hasQualifiedNameInDumbMode(psiAnnotation, fqn));
|
||||
}
|
||||
return ContainerUtil.or(annotationFQNs, psiAnnotation::hasQualifiedName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
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;
|
||||
@@ -10,6 +11,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Some util methods for annotation processing
|
||||
@@ -35,9 +37,19 @@ public final class PsiAnnotationUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <T> Collection<T> getAnnotationValues(@NotNull PsiAnnotation psiAnnotation, @NotNull String parameter, @NotNull Class<T> asClass) {
|
||||
public static <T> Collection<T> getAnnotationValues(@NotNull PsiAnnotation psiAnnotation,
|
||||
@NotNull String parameter,
|
||||
@NotNull Class<T> asClass,
|
||||
@NotNull List<T> defaultDumbValue) {
|
||||
Collection<T> result = Collections.emptyList();
|
||||
PsiAnnotationMemberValue attributeValue = psiAnnotation.findAttributeValue(parameter);
|
||||
PsiAnnotationMemberValue attributeValue;
|
||||
if (DumbService.isDumb(psiAnnotation.getProject())) {
|
||||
attributeValue = psiAnnotation.findDeclaredAttributeValue(parameter);
|
||||
if (attributeValue == null) return defaultDumbValue;
|
||||
}
|
||||
else {
|
||||
attributeValue = psiAnnotation.findAttributeValue(parameter);
|
||||
}
|
||||
if (attributeValue instanceof PsiArrayInitializerMemberValue) {
|
||||
final PsiAnnotationMemberValue[] memberValues = ((PsiArrayInitializerMemberValue) attributeValue).getInitializers();
|
||||
result = new ArrayList<>(memberValues.length);
|
||||
|
||||
@@ -250,6 +250,9 @@
|
||||
<jvm.logging implementation="de.plushnikov.intellij.plugin.logging.LombokLog4j2Logger"/>
|
||||
<jvm.logging implementation="de.plushnikov.intellij.plugin.logging.LombokLog4jLogger"/>
|
||||
<jvm.logging implementation="de.plushnikov.intellij.plugin.logging.LombokApacheCommonsLogger"/>
|
||||
|
||||
<registryKey key="lombok.dumb.mode.enabled" defaultValue="true" restartRequired="true"
|
||||
description="Lombok augment works in dumb mode"/>
|
||||
</extensions>
|
||||
|
||||
<projectListeners>
|
||||
|
||||
@@ -2,10 +2,12 @@ package de.plushnikov.intellij.plugin;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
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.util.containers.ContainerUtil;
|
||||
import de.plushnikov.intellij.plugin.util.PsiElementUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -48,6 +50,8 @@ public abstract class AbstractLombokParsingTestCase extends AbstractLombokLightC
|
||||
}
|
||||
|
||||
public void doTest(String testName) {
|
||||
DumbModeTestUtils.runInDumbModeSynchronously(getProject(),
|
||||
() -> compareFiles(loadBeforeLombokFile(testName), loadAfterDeLombokFile(testName)));
|
||||
compareFiles(loadBeforeLombokFile(testName), loadAfterDeLombokFile(testName));
|
||||
}
|
||||
|
||||
@@ -147,11 +151,13 @@ public abstract class AbstractLombokParsingTestCase extends AbstractLombokLightC
|
||||
assertEquals("Initializers are not equals ", afterInitializerText, beforeInitializerText);
|
||||
}
|
||||
|
||||
private static void compareType(PsiType beforeType, PsiType afterType, PomNamedTarget whereTarget) {
|
||||
private void compareType(PsiType beforeType, PsiType afterType, PomNamedTarget whereTarget) {
|
||||
if (null != beforeType && null != afterType) {
|
||||
final String afterText = stripJavaLang(afterType.getCanonicalText());
|
||||
final String beforeText = stripJavaLang(beforeType.getCanonicalText());
|
||||
assertEquals(String.format("Types are not equal for element: %s", whereTarget.getName()), afterText, beforeText);
|
||||
DumbService.getInstance(getProject()).runWithAlternativeResolveEnabled(() -> {
|
||||
final String afterText = stripJavaLang(afterType.getCanonicalText());
|
||||
final String beforeText = stripJavaLang(beforeType.getCanonicalText());
|
||||
assertEquals(String.format("Types are not equal for element: %s", whereTarget.getName()), afterText, beforeText);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,15 +190,16 @@ public abstract class AbstractLombokParsingTestCase extends AbstractLombokLightC
|
||||
}
|
||||
|
||||
private void compareAnnotations(PsiModifierList beforeModifierList, PsiModifierList afterModifierList) {
|
||||
DumbService dumbService = DumbService.getInstance(beforeModifierList.getProject());
|
||||
if (shouldCompareAnnotations()) {
|
||||
Collection<String> beforeAnnotations = Arrays.stream(beforeModifierList.getAnnotations())
|
||||
.map(PsiAnnotation::getQualifiedName)
|
||||
.map(an-> dumbService.computeWithAlternativeResolveEnabled(()->an.getQualifiedName()))
|
||||
.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(PsiAnnotation::getQualifiedName)
|
||||
.map(an-> dumbService.computeWithAlternativeResolveEnabled(()->an.getQualifiedName()))
|
||||
.filter(Pattern.compile(annotationToComparePattern()).asPredicate())
|
||||
.filter(Predicate.not(annotationsToIgnoreList()::contains))
|
||||
.toList();
|
||||
@@ -204,8 +211,10 @@ public abstract class AbstractLombokParsingTestCase extends AbstractLombokLightC
|
||||
|
||||
// compare annotations parameter list
|
||||
for (PsiAnnotation beforeAnnotation : beforeModifierList.getAnnotations()) {
|
||||
String qualifiedName = beforeAnnotation.getQualifiedName();
|
||||
PsiAnnotation afterAnnotation = afterModifierList.findAnnotation(qualifiedName);
|
||||
String qualifiedName =
|
||||
dumbService.computeWithAlternativeResolveEnabled(() -> beforeAnnotation.getQualifiedName());
|
||||
PsiAnnotation afterAnnotation =
|
||||
dumbService.computeWithAlternativeResolveEnabled(() -> afterModifierList.findAnnotation(qualifiedName));
|
||||
if (null != afterAnnotation) {
|
||||
Map<String, String> beforeParameter = Stream.of(beforeAnnotation.getParameterList().getAttributes())
|
||||
.collect(Collectors.toMap(PsiNameValuePair::getAttributeName, p -> p.getValue().getText()));
|
||||
@@ -287,8 +296,10 @@ public abstract class AbstractLombokParsingTestCase extends AbstractLombokLightC
|
||||
private static Collection<String> mapToTypeString(PsiParameterList compareMethodParameterList) {
|
||||
Collection<String> result = new ArrayList<>();
|
||||
final PsiParameter[] compareMethodParameterListParameters = compareMethodParameterList.getParameters();
|
||||
DumbService dumbService = DumbService.getInstance(compareMethodParameterList.getProject());
|
||||
for (PsiParameter compareMethodParameterListParameter : compareMethodParameterListParameters) {
|
||||
result.add(stripJavaLang(compareMethodParameterListParameter.getType().getCanonicalText()));
|
||||
PsiType type = compareMethodParameterListParameter.getType();
|
||||
result.add(stripJavaLang(dumbService.computeWithAlternativeResolveEnabled(() -> type.getCanonicalText())));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -303,10 +314,12 @@ public abstract class AbstractLombokParsingTestCase extends AbstractLombokLightC
|
||||
PsiClassType[] afterTypes = afterThrows.getReferencedTypes();
|
||||
|
||||
assertEquals("Throws counts are different for Method :" + psiMethod.getName(), beforeTypes.length, afterTypes.length);
|
||||
DumbService dumbService = DumbService.getInstance(psiMethod.getProject());
|
||||
for (PsiClassType beforeType : beforeTypes) {
|
||||
boolean found = false;
|
||||
for (PsiClassType afterType : afterTypes) {
|
||||
if (beforeType.equals(afterType)) {
|
||||
boolean equals = dumbService.computeWithAlternativeResolveEnabled(()->beforeType.equals(afterType));
|
||||
if (equals) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@@ -332,7 +345,9 @@ public abstract class AbstractLombokParsingTestCase extends AbstractLombokLightC
|
||||
ContainerUtil.map(afterConstructor.getParameterList().getParameters(), PsiParameter::getType);
|
||||
|
||||
for (PsiMethod beforeConstructor : beforeConstructors) {
|
||||
if (PsiElementUtil.methodMatches(beforeConstructor, null, null, afterConstructor.getName(), afterConstructorParameterTypes)) {
|
||||
boolean methodMatches = DumbService.getInstance(getProject()).computeWithAlternativeResolveEnabled(
|
||||
() -> PsiElementUtil.methodMatches(beforeConstructor, null, null, afterConstructor.getName(), afterConstructorParameterTypes));
|
||||
if (methodMatches) {
|
||||
final PsiModifierList intellijConstructorModifierList = beforeConstructor.getModifierList();
|
||||
compareModifiers(intellijConstructorModifierList, theirsFieldModifierList);
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package de.plushnikov.intellij.plugin.configsystem;
|
||||
|
||||
import com.intellij.testFramework.DumbModeTestUtils;
|
||||
|
||||
public class GetterDumbModeTest extends AbstractLombokConfigSystemTestCase {
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return super.getBasePath() + "/configsystem/getter";
|
||||
}
|
||||
|
||||
public void testDumb$GetterClassTest() {
|
||||
final String fullFileName = getTestName(true).replace('$', '/') + ".java";
|
||||
final int lastIndexOf = fullFileName.lastIndexOf('/');
|
||||
final String subPath = fullFileName.substring(0, lastIndexOf);
|
||||
final String fileName = fullFileName.substring(lastIndexOf + 1);
|
||||
|
||||
DumbModeTestUtils.runInDumbModeSynchronously(
|
||||
getProject(),
|
||||
() -> {
|
||||
myFixture.copyFileToProject(subPath + "/before/lombok.config", subPath + "/before/lombok.config");
|
||||
doTest(subPath + "/before/inner/" + fileName, subPath + "/after/inner/" + fileName);
|
||||
}
|
||||
);
|
||||
}
|
||||
public void testDumbStopBubbling$GetterClassTest() {
|
||||
final String fullFileName = getTestName(true).replace('$', '/') + ".java";
|
||||
final int lastIndexOf = fullFileName.lastIndexOf('/');
|
||||
final String subPath = fullFileName.substring(0, lastIndexOf);
|
||||
final String fileName = fullFileName.substring(lastIndexOf + 1);
|
||||
|
||||
DumbModeTestUtils.runInDumbModeSynchronously(
|
||||
getProject(),
|
||||
() -> {
|
||||
myFixture.copyFileToProject(subPath + "/before/inner/lombok.config", subPath + "/before/inner/lombok.config");
|
||||
myFixture.copyFileToProject(subPath + "/before/lombok.config", subPath + "/before/lombok.config");
|
||||
doTest(subPath + "/before/inner/" + fileName, subPath + "/after/inner/" + fileName);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package de.plushnikov.intellij.plugin.lombokconfig;
|
||||
|
||||
import com.intellij.mock.MockDumbService;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiFile;
|
||||
@@ -64,6 +66,7 @@ public class ConfigDiscoveryTest {
|
||||
}
|
||||
};
|
||||
|
||||
when(project.getService(DumbService.class)).thenReturn(new MockDumbService(project));
|
||||
when(psiFile.getProject()).thenReturn(project);
|
||||
when(psiClass.getContainingFile()).thenReturn(psiFile);
|
||||
when(psiFile.getOriginalFile()).thenReturn(psiFile);
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
public class GetterClassTest {
|
||||
private int intProperty;
|
||||
private String stringProperty;
|
||||
private boolean booleanProperty;
|
||||
private Boolean booleanObjectProperty;
|
||||
|
||||
public static void main(String[] args) {
|
||||
final GetterClassTest test = new GetterClassTest();
|
||||
|
||||
test.getIntProperty();
|
||||
test.getStringProperty();
|
||||
test.getBooleanObjectProperty();
|
||||
|
||||
test.getBooleanProperty();
|
||||
}
|
||||
|
||||
public int getIntProperty() {
|
||||
return this.intProperty;
|
||||
}
|
||||
|
||||
public String getStringProperty() {
|
||||
return this.stringProperty;
|
||||
}
|
||||
|
||||
public boolean getBooleanProperty() {
|
||||
return this.booleanProperty;
|
||||
}
|
||||
|
||||
public Boolean getBooleanObjectProperty() {
|
||||
return this.booleanObjectProperty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class GetterClassTest {
|
||||
private int intProperty;
|
||||
private String stringProperty;
|
||||
private boolean booleanProperty;
|
||||
private Boolean booleanObjectProperty;
|
||||
|
||||
public static void main(String[] args) {
|
||||
final GetterClassTest test = new GetterClassTest();
|
||||
|
||||
test.getIntProperty();
|
||||
test.getStringProperty();
|
||||
test.getBooleanObjectProperty();
|
||||
|
||||
test.getBooleanProperty();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
lombok.getter.noIsPrefix = true
|
||||
|
||||
config.stopBubbling = true
|
||||
@@ -0,0 +1,32 @@
|
||||
public class GetterClassTest {
|
||||
private int intProperty;
|
||||
private String stringProperty;
|
||||
private boolean booleanProperty;
|
||||
private Boolean booleanObjectProperty;
|
||||
|
||||
public static void main(String[] args) {
|
||||
final GetterClassTest test = new GetterClassTest();
|
||||
|
||||
test.getIntProperty();
|
||||
test.getStringProperty();
|
||||
test.getBooleanObjectProperty();
|
||||
|
||||
test.isBooleanProperty();
|
||||
}
|
||||
|
||||
public int getIntProperty() {
|
||||
return this.intProperty;
|
||||
}
|
||||
|
||||
public String getStringProperty() {
|
||||
return this.stringProperty;
|
||||
}
|
||||
|
||||
public boolean isBooleanProperty() {
|
||||
return this.booleanProperty;
|
||||
}
|
||||
|
||||
public Boolean getBooleanObjectProperty() {
|
||||
return this.booleanObjectProperty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class GetterClassTest {
|
||||
private int intProperty;
|
||||
private String stringProperty;
|
||||
private boolean booleanProperty;
|
||||
private Boolean booleanObjectProperty;
|
||||
|
||||
public static void main(String[] args) {
|
||||
final GetterClassTest test = new GetterClassTest();
|
||||
|
||||
test.getIntProperty();
|
||||
test.getStringProperty();
|
||||
test.getBooleanObjectProperty();
|
||||
|
||||
test.isBooleanProperty();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
config.stopBubbling = true
|
||||
@@ -0,0 +1,2 @@
|
||||
lombok.getter.noIsPrefix = true
|
||||
config.stopBubbling = true
|
||||
Reference in New Issue
Block a user