[java] IDEA-341622 Better cache NullableNotNullManager#findEffectiveNullabilityInfo for library methods

GitOrigin-RevId: ecc23faa48a12ae14ad91be62d0a2216eca74e7a
This commit is contained in:
Yuriy Artamonov
2024-04-21 17:09:22 +02:00
committed by intellij-monorepo-bot
parent 5357928adb
commit ed4b509b66
3 changed files with 46 additions and 21 deletions

View File

@@ -2,11 +2,13 @@
package com.intellij.codeInspection.dataFlow;
import com.intellij.codeInsight.*;
import com.intellij.java.library.JavaLibraryModificationTracker;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.light.LightRecordMethod;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValueProvider.Result;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.psi.util.PsiUtil;
@@ -145,7 +147,7 @@ public final class JavaMethodContractUtil {
return ContractInfo.PURE;
}
return CachedValuesManager.getCachedValue(method, () -> {
final PsiAnnotation contractAnno = findContractAnnotation(method);
PsiAnnotation contractAnno = findContractAnnotation(method);
ContractInfo info = ContractInfo.EMPTY;
if (contractAnno != null) {
List<StandardMethodContract> contracts = parseContracts(method, contractAnno);
@@ -166,7 +168,16 @@ public final class JavaMethodContractUtil {
boolean explicit = !AnnotationUtil.isInferredAnnotation(contractAnno);
info = new ContractInfo(contracts, pure, explicit, mutationSignature);
}
return CachedValueProvider.Result.create(info, method, PsiModificationTracker.MODIFICATION_COUNT);
PsiFile file = method.getContainingFile();
if (file != null
&& file.getVirtualFile() != null
&& ProjectFileIndex.getInstance(method.getProject()).isInLibrary(file.getVirtualFile())) {
// there is no need to recompute info on changes in the project code
return Result.create(info, JavaLibraryModificationTracker.getInstance(method.getProject()));
}
return Result.create(info, method, PsiModificationTracker.MODIFICATION_COUNT);
});
}

View File

@@ -12,6 +12,7 @@ import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.ide.plugins.DynamicPluginListener;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.java.JavaBundle;
import com.intellij.java.library.JavaLibraryModificationTracker;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.fileTypes.FileTypeRegistry;
@@ -26,10 +27,8 @@ import com.intellij.psi.*;
import com.intellij.psi.impl.java.stubs.index.JavaAnnotationIndex;
import com.intellij.psi.search.DelegatingGlobalSearchScope;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.psi.util.CachedValueProvider.Result;
import com.intellij.psi.util.*;
import com.intellij.util.containers.ContainerUtil;
import one.util.streamex.StreamEx;
import org.jdom.Element;
@@ -278,7 +277,7 @@ public class NullableNotNullManagerImpl extends NullableNotNullManager implement
for (PsiClass tqNick : nickDeclarations) {
result.addAll(ContainerUtil.findAll(MetaAnnotationUtil.getChildren(tqNick, scope), Jsr305Support::isNullabilityNickName));
}
return CachedValueProvider.Result.create(new ArrayList<>(result), PsiModificationTracker.MODIFICATION_COUNT);
return Result.create(new ArrayList<>(result), PsiModificationTracker.MODIFICATION_COUNT);
});
}
@@ -345,14 +344,14 @@ public class NullableNotNullManagerImpl extends NullableNotNullManager implement
@Override
protected @NotNull List<String> getNullablesWithNickNames() {
return CachedValuesManager.getManager(myProject).getCachedValue(myProject, () ->
CachedValueProvider.Result.create(StreamEx.of(getNullables(), filterNickNames(Nullability.NULLABLE)).toFlatList(Function.identity()),
Result.create(StreamEx.of(getNullables(), filterNickNames(Nullability.NULLABLE)).toFlatList(Function.identity()),
PsiModificationTracker.MODIFICATION_COUNT));
}
@Override
protected @NotNull List<String> getNotNullsWithNickNames() {
return CachedValuesManager.getManager(myProject).getCachedValue(myProject, () ->
CachedValueProvider.Result.create(StreamEx.of(getNotNulls(), filterNickNames(Nullability.NOT_NULL)).toFlatList(Function.identity()),
Result.create(StreamEx.of(getNotNulls(), filterNickNames(Nullability.NOT_NULL)).toFlatList(Function.identity()),
PsiModificationTracker.MODIFICATION_COUNT));
}
@@ -389,7 +388,7 @@ public class NullableNotNullManagerImpl extends NullableNotNullManager implement
return result.get(annotation);
}
};
return CachedValueProvider.Result.create(holder, PsiModificationTracker.MODIFICATION_COUNT);
return Result.create(holder, PsiModificationTracker.MODIFICATION_COUNT);
});
}
@@ -434,6 +433,26 @@ public class NullableNotNullManagerImpl extends NullableNotNullManager implement
))));
}
@Override
public final @Nullable NullabilityAnnotationInfo findEffectiveNullabilityInfo(@NotNull PsiModifierListOwner owner) {
PsiType type = PsiUtil.getTypeByPsiElement(owner);
if (type == null || TypeConversionUtil.isPrimitiveAndNotNull(type)) return null;
return CachedValuesManager.getCachedValue(owner, () -> {
NullabilityAnnotationInfo info = doFindEffectiveNullabilityAnnotation(owner);
PsiFile file = owner.getContainingFile();
if (file != null
&& file.getVirtualFile() != null
&& ProjectFileIndex.getInstance(owner.getProject()).isInLibrary(file.getVirtualFile())) {
// there is no need to recompute info on changes in the project code
return Result.create(info, JavaLibraryModificationTracker.getInstance(owner.getProject()));
}
return Result.create(info, PsiModificationTracker.MODIFICATION_COUNT);
});
}
/**
* Provides options to setup nullability annotations:
* <ul>

View File

@@ -5,7 +5,8 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.*;
import com.intellij.psi.util.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -131,20 +132,14 @@ public abstract class NullableNotNullManager {
}
/**
* Returns nullability annotation info which has effect for given element.
* Returns nullability annotation info which has effect for a given element.
*
* @param owner element to find an annotation for
* @return effective nullability annotation info, or null if not found.
*/
public @Nullable NullabilityAnnotationInfo findEffectiveNullabilityInfo(@NotNull PsiModifierListOwner owner) {
PsiType type = PsiUtil.getTypeByPsiElement(owner);
if (type == null || TypeConversionUtil.isPrimitiveAndNotNull(type)) return null;
public abstract @Nullable NullabilityAnnotationInfo findEffectiveNullabilityInfo(@NotNull PsiModifierListOwner owner);
return CachedValuesManager.getCachedValue(owner, () -> CachedValueProvider.Result
.create(doFindEffectiveNullabilityAnnotation(owner), PsiModificationTracker.MODIFICATION_COUNT));
}
private @Nullable NullabilityAnnotationInfo doFindEffectiveNullabilityAnnotation(@NotNull PsiModifierListOwner owner) {
protected final @Nullable NullabilityAnnotationInfo doFindEffectiveNullabilityAnnotation(@NotNull PsiModifierListOwner owner) {
@Nullable NullabilityAnnotationInfo result = findPlainAnnotation(owner, true, false, getAllNullabilityAnnotationsWithNickNames());
if (result != null) {
return result;