make it explicit that nullity/contract inference from source works only with PsiMethodImpl

inspired by https://github.com/JetBrains/intellij-community/pull/511
This commit is contained in:
peter
2017-02-14 10:22:39 +01:00
parent 526aba013a
commit cc237c0a58
9 changed files with 33 additions and 31 deletions
@@ -20,6 +20,7 @@ import com.intellij.codeInspection.dataFlow.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiMethodImpl;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
@@ -57,13 +58,13 @@ public class InferredAnnotationsManagerImpl extends InferredAnnotationsManager {
return fromBytecode;
}
if (listOwner instanceof PsiMethod) {
if (listOwner instanceof PsiMethodImpl) {
if (ORG_JETBRAINS_ANNOTATIONS_CONTRACT.equals(annotationFQN)) {
return getInferredContractAnnotation((PsiMethod)listOwner);
return getInferredContractAnnotation((PsiMethodImpl)listOwner);
}
if ((AnnotationUtil.NOT_NULL.equals(annotationFQN) || AnnotationUtil.NULLABLE.equals(annotationFQN))) {
PsiAnnotation anno = getInferredNullityAnnotation((PsiMethod)listOwner);
PsiAnnotation anno = getInferredNullityAnnotation((PsiMethodImpl)listOwner);
return anno == null ? null : annotationFQN.equals(anno.getQualifiedName()) ? anno : null;
}
}
@@ -97,7 +98,7 @@ public class InferredAnnotationsManagerImpl extends InferredAnnotationsManager {
}
@Nullable
private PsiAnnotation getInferredContractAnnotation(PsiMethod method) {
private PsiAnnotation getInferredContractAnnotation(PsiMethodImpl method) {
if (method.getModifierList().findAnnotation(ORG_JETBRAINS_ANNOTATIONS_CONTRACT) != null) {
return null;
}
@@ -106,7 +107,7 @@ public class InferredAnnotationsManagerImpl extends InferredAnnotationsManager {
}
@Nullable
private PsiAnnotation getInferredNullityAnnotation(PsiMethod method) {
private PsiAnnotation getInferredNullityAnnotation(PsiMethodImpl method) {
NullableNotNullManager manager = NullableNotNullManager.getInstance(myProject);
if (AnnotationUtil.findAnnotation(method, manager.getNotNulls(), true) != null || AnnotationUtil.findAnnotation(method, manager.getNullables(), true) != null) {
return null;
@@ -159,16 +160,16 @@ public class InferredAnnotationsManagerImpl extends InferredAnnotationsManager {
}
}
if (listOwner instanceof PsiMethod) {
if (listOwner instanceof PsiMethodImpl) {
PsiAnnotation hardcoded = getHardcodedContractAnnotation((PsiMethod)listOwner);
if (hardcoded != null) {
result.add(hardcoded);
} else if (!ignoreInference(listOwner, ORG_JETBRAINS_ANNOTATIONS_CONTRACT)) {
ContainerUtil.addIfNotNull(result, getInferredContractAnnotation((PsiMethod)listOwner));
ContainerUtil.addIfNotNull(result, getInferredContractAnnotation((PsiMethodImpl)listOwner));
}
if (!ignoreInference(listOwner, AnnotationUtil.NOT_NULL) || !ignoreInference(listOwner, AnnotationUtil.NULLABLE)) {
PsiAnnotation annotation = getInferredNullityAnnotation((PsiMethod)listOwner);
PsiAnnotation annotation = getInferredNullityAnnotation((PsiMethodImpl)listOwner);
if (annotation != null && !ignoreInference(listOwner, annotation.getQualifiedName())) {
result.add(annotation);
}
@@ -21,6 +21,7 @@ import com.intellij.openapi.util.RecursionManager;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiPrimitiveType;
import com.intellij.psi.PsiType;
import com.intellij.psi.impl.source.PsiMethodImpl;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
@@ -42,7 +43,7 @@ public class ContractInference {
public static final int MAX_CONTRACT_COUNT = 10;
@NotNull
public static List<MethodContract> inferContracts(@NotNull final PsiMethod method) {
public static List<MethodContract> inferContracts(@NotNull PsiMethodImpl method) {
if (!InferenceFromSourceUtil.shouldInferFromSource(method)) {
return Collections.emptyList();
}
@@ -57,7 +58,7 @@ public class ContractInference {
}
@NotNull
private static List<MethodContract> postProcessContracts(@NotNull PsiMethod method, MethodData data, List<PreContract> rawContracts) {
private static List<MethodContract> postProcessContracts(@NotNull PsiMethodImpl method, MethodData data, List<PreContract> rawContracts) {
List<MethodContract> contracts = ContainerUtil.concat(rawContracts, c -> c.toContracts(method, data.methodBody(method)));
if (contracts.isEmpty()) return Collections.emptyList();
@@ -17,7 +17,6 @@ package com.intellij.codeInspection.dataFlow
import com.intellij.lang.LighterAST
import com.intellij.lang.LighterASTNode
import com.intellij.psi.PsiMethod
import com.intellij.psi.impl.source.JavaLightStubBuilder
import com.intellij.psi.impl.source.PsiFileImpl
import com.intellij.psi.impl.source.PsiMethodImpl
@@ -93,11 +92,7 @@ private fun createData(body: LighterASTNode,
return MethodData(nullity, purity, contracts, body.startOffset, body.endOffset)
}
fun getIndexedData(method: PsiMethod): MethodData? {
if (method !is PsiMethodImpl || !InferenceFromSourceUtil.shouldInferFromSource(method)) return null
return gist.getFileData(method.containingFile)?.get(methodIndex(method))
}
fun getIndexedData(method: PsiMethodImpl): MethodData? = gist.getFileData(method.containingFile)?.get(methodIndex(method))
private fun methodIndex(method: PsiMethodImpl): Int {
val file = method.containingFile as PsiFileImpl
@@ -18,7 +18,7 @@ package com.intellij.codeInspection.dataFlow;
import com.intellij.openapi.roots.FileIndexFacade;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.light.LightElement;
import com.intellij.psi.impl.source.PsiMethodImpl;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.searches.MethodReferencesSearch;
import com.intellij.psi.util.*;
@@ -29,9 +29,7 @@ import org.jetbrains.annotations.Nullable;
* @author peter
*/
public class InferenceFromSourceUtil {
static boolean shouldInferFromSource(@NotNull final PsiMethod method) {
if (method instanceof SyntheticElement || method instanceof LightElement) return false;
static boolean shouldInferFromSource(@NotNull PsiMethodImpl method) {
return CachedValuesManager.getCachedValue(method, () -> CachedValueProvider.Result
.create(calcShouldInferFromSource(method), method, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT));
}
@@ -18,8 +18,12 @@ package com.intellij.codeInspection.dataFlow;
import com.intellij.lang.LighterAST;
import com.intellij.lang.LighterASTNode;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.psi.*;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.PsiPrimitiveType;
import com.intellij.psi.PsiType;
import com.intellij.psi.TokenType;
import com.intellij.psi.impl.source.JavaLightTreeUtil;
import com.intellij.psi.impl.source.PsiMethodImpl;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
@@ -38,7 +42,7 @@ import static com.intellij.psi.impl.source.tree.JavaElementType.*;
*/
public class NullityInference {
public static Nullness inferNullity(final PsiMethod method) {
public static Nullness inferNullity(PsiMethodImpl method) {
if (!InferenceFromSourceUtil.shouldInferFromSource(method)) {
return Nullness.UNKNOWN;
}
@@ -19,9 +19,9 @@ import com.intellij.lang.LighterAST;
import com.intellij.lang.LighterASTNode;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiType;
import com.intellij.psi.impl.source.JavaLightTreeUtil;
import com.intellij.psi.impl.source.PsiMethodImpl;
import com.intellij.psi.impl.source.tree.LightTreeUtil;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.CachedValueProvider;
@@ -40,7 +40,7 @@ import static com.intellij.psi.impl.source.tree.JavaElementType.*;
*/
public class PurityInference {
public static boolean inferPurity(@NotNull final PsiMethod method) {
public static boolean inferPurity(@NotNull PsiMethodImpl method) {
if (!InferenceFromSourceUtil.shouldInferFromSource(method) ||
PsiType.VOID.equals(method.getReturnType()) ||
method.isConstructor()) {
@@ -18,6 +18,7 @@ package com.intellij.codeInspection.dataFlow
import com.intellij.codeInsight.NullableNotNullManager
import com.intellij.lang.LighterASTNode
import com.intellij.psi.*
import com.intellij.psi.impl.source.PsiMethodImpl
import com.intellij.psi.search.LocalSearchScope
import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.psi.util.CachedValueProvider
@@ -122,8 +123,8 @@ data class MethodData(
internal val bodyStart: Int,
internal val bodyEnd: Int
) {
fun methodBody(method: PsiMethod): () -> PsiCodeBlock = {
if ((method as StubBasedPsiElement<*>?)?.stub != null)
fun methodBody(method: PsiMethodImpl): () -> PsiCodeBlock = {
if (method.stub != null)
CachedValuesManager.getCachedValue(method) { CachedValueProvider.Result(getDetachedBody(method), method) }
else
method.body!!