Usage of checkBases-consuming methods reduced

This commit is contained in:
Tagir Valeev
2018-06-09 14:29:27 +07:00
parent ee554a876c
commit c8384a57e1
5 changed files with 78 additions and 56 deletions
@@ -127,7 +127,6 @@ public class MethodChainLookupRangingHelper {
@NotNull
private static Couple<Integer> calculateParameterInfo(@NotNull PsiMethod method,
@NotNull ChainCompletionContext context) {
NullableNotNullManager nullableNotNullManager = NullableNotNullManager.getInstance(method.getProject());
int unreachableParametersCount = 0;
int matchedParametersInContext = 0;
for (PsiParameter parameter : method.getParameterList().getParameters()) {
@@ -139,7 +138,7 @@ public class MethodChainLookupRangingHelper {
matchedParametersInContext++;
continue;
}
if (!nullableNotNullManager.isNullable(parameter, true)) {
if (!NullableNotNullManager.isNullable(parameter)) {
unreachableParametersCount++;
}
}
@@ -416,12 +416,12 @@ public class DataFlowInspectionBase extends AbstractBaseJavaLocalInspectionTool
PsiMethod method = (PsiMethod)scope.getParent();
if (PsiUtil.canBeOverridden(method)) return;
PsiAnnotation nullableAnno = NullableNotNullManager.getInstance(scope.getProject()).getNullableAnnotation(method, false);
if (nullableAnno == null || !nullableAnno.isPhysical()) return;
NullabilityAnnotationInfo info = NullableNotNullManager.getInstance(scope.getProject()).findOwnNullabilityAnnotationInfo(method);
if (info == null || info.getNullability() != Nullability.NULLABLE || !info.getAnnotation().isPhysical()) return;
PsiJavaCodeReferenceElement annoName = nullableAnno.getNameReferenceElement();
PsiJavaCodeReferenceElement annoName = info.getAnnotation().getNameReferenceElement();
assert annoName != null;
String msg = "@" + NullableStuffInspectionBase.getPresentableAnnoName(nullableAnno) +
String msg = "@" + NullableStuffInspectionBase.getPresentableAnnoName(info.getAnnotation()) +
" method '" + method.getName() + "' always returns a non-null value";
LocalQuickFix[] fixes = {AddAnnotationPsiFix.createAddNotNullFix(method)};
if (holder.isOnTheFly()) {
@@ -1,10 +1,7 @@
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.codeInspection.nullable;
import com.intellij.codeInsight.AnnotationTargetUtil;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.NullabilityAnnotationInfo;
import com.intellij.codeInsight.NullableNotNullManager;
import com.intellij.codeInsight.*;
import com.intellij.codeInsight.daemon.GroupNames;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightControlFlowUtil;
import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil;
@@ -515,7 +512,11 @@ public class NullableStuffInspectionBase extends AbstractBaseJavaLocalInspection
private static void checkNotNullFieldsInitialized(PsiField field, NullableNotNullManager manager, @NotNull ProblemsHolder holder) {
NullabilityAnnotationInfo info = manager.findEffectiveNullabilityAnnotationInfo(field);
if (info == null || HighlightControlFlowUtil.isFieldInitializedAfterObjectConstruction(field)) return;
if (info == null ||
info.getNullability() != Nullability.NOT_NULL ||
HighlightControlFlowUtil.isFieldInitializedAfterObjectConstruction(field)) {
return;
}
boolean byDefault = info.isContainer();
PsiAnnotation annotation = info.getAnnotation();
@@ -820,16 +821,24 @@ public class NullableStuffInspectionBase extends AbstractBaseJavaLocalInspection
boolean isOnFly,
int parameterIdx,
PsiParameter parameter) {
if (REPORT_NULLS_PASSED_TO_NOT_NULL_PARAMETER && isOnFly && isNotNullNotInferred(parameter, false, false)) {
PsiAnnotation notNullAnnotation = nullableManager.getNotNullAnnotation(parameter, false);
if (JavaNullMethodArgumentUtil.hasNullArgument(method, parameterIdx)) {
boolean physical = PsiTreeUtil.isAncestor(parameter, notNullAnnotation, true);
holder.registerProblem(physical ? notNullAnnotation : parameter.getNameIdentifier(),
InspectionsBundle.message("inspection.nullable.problems.NotNull.parameter.receives.null.literal", getPresentableAnnoName(parameter)),
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
createNavigateToNullParameterUsagesFix(parameter));
}
if (!REPORT_NULLS_PASSED_TO_NOT_NULL_PARAMETER || !isOnFly) return;
PsiElement elementToHighlight;
if (DfaPsiUtil.getTypeNullability(getMemberType(parameter)) == Nullness.NOT_NULL) {
elementToHighlight = parameter.getNameIdentifier();
} else {
NullabilityAnnotationInfo info = nullableManager.findOwnNullabilityAnnotationInfo(parameter);
if (info == null || info.isInferred()) return;
PsiAnnotation notNullAnnotation = info.getAnnotation();
boolean physical = PsiTreeUtil.isAncestor(parameter, notNullAnnotation, true);
elementToHighlight = physical ? notNullAnnotation : parameter.getNameIdentifier();
}
if (elementToHighlight == null || !JavaNullMethodArgumentUtil.hasNullArgument(method, parameterIdx)) return;
holder.registerProblem(elementToHighlight,
InspectionsBundle.message("inspection.nullable.problems.NotNull.parameter.receives.null.literal",
getPresentableAnnoName(parameter)),
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
createNavigateToNullParameterUsagesFix(parameter));
}
private void checkOverriders(@NotNull PsiMethod method,
@@ -79,17 +79,6 @@ public abstract class NullableNotNullManager {
@NotNull
public abstract String getDefaultNullable();
private String checkContainer(PsiAnnotation annotation) {
if (annotation == null) {
return null;
}
PsiAnnotation.TargetType[] acceptAnyTarget = PsiAnnotation.TargetType.values();
if (checkNullityDefault(annotation, acceptAnyTarget, false) != null) {
return null;
}
return annotation.getQualifiedName();
}
@Nullable
public PsiAnnotation getNullableAnnotation(@NotNull PsiModifierListOwner owner, boolean checkBases) {
return findNullityAnnotationWithDefault(owner, checkBases, true);
@@ -107,26 +96,30 @@ public abstract class NullableNotNullManager {
@Nullable
public PsiAnnotation copyNotNullAnnotation(@NotNull PsiModifierListOwner original, @NotNull PsiModifierListOwner generated) {
return copyAnnotation(getNotNullAnnotation(original, false), generated);
NullabilityAnnotationInfo info = findOwnNullabilityAnnotationInfo(original);
if (info == null || info.getNullability() != Nullability.NOT_NULL) return null;
return copyAnnotation(info.getAnnotation(), generated);
}
@Nullable
public PsiAnnotation copyNullableAnnotation(@NotNull PsiModifierListOwner original, @NotNull PsiModifierListOwner generated) {
return copyAnnotation(getNullableAnnotation(original, false), generated);
NullabilityAnnotationInfo info = findOwnNullabilityAnnotationInfo(original);
if (info == null || info.getNullability() != Nullability.NULLABLE) return null;
return copyAnnotation(info.getAnnotation(), generated);
}
@Nullable
public PsiAnnotation copyNullableOrNotNullAnnotation(@NotNull PsiModifierListOwner original, @NotNull PsiModifierListOwner generated) {
PsiAnnotation annotation = getNullableAnnotation(original, false);
if (annotation == null) annotation = getNotNullAnnotation(original, false);
return copyAnnotation(annotation, generated);
NullabilityAnnotationInfo info = findOwnNullabilityAnnotationInfo(original);
if (info == null) return null;
return copyAnnotation(info.getAnnotation(), generated);
}
@Nullable
private PsiAnnotation copyAnnotation(PsiAnnotation annotation, PsiModifierListOwner target) {
private static PsiAnnotation copyAnnotation(@NotNull PsiAnnotation annotation, PsiModifierListOwner target) {
// type annotations are part of target's type and should not to be copied explicitly to avoid duplication
if (annotation != null && !AnnotationTargetUtil.isTypeAnnotation(annotation)) {
String qualifiedName = checkContainer(annotation);
if (!AnnotationTargetUtil.isTypeAnnotation(annotation)) {
String qualifiedName = annotation.getQualifiedName();
if (qualifiedName != null) {
PsiModifierList modifierList = target.getModifierList();
if (modifierList != null && !modifierList.hasAnnotation(qualifiedName)) {
@@ -140,17 +133,16 @@ public abstract class NullableNotNullManager {
/** @deprecated use {@link #copyNotNullAnnotation(PsiModifierListOwner, PsiModifierListOwner)} (to be removed in IDEA 17) */
public PsiAnnotation copyNotNullAnnotation(PsiModifierListOwner owner) {
return copyAnnotation(owner, getNotNullAnnotation(owner, false));
NullabilityAnnotationInfo info = findOwnNullabilityAnnotationInfo(owner);
if (info == null || info.getNullability() != Nullability.NOT_NULL) return null;
return copyAnnotation(owner, info.getAnnotation());
}
/** @deprecated use {@link #copyNullableOrNotNullAnnotation(PsiModifierListOwner, PsiModifierListOwner)} (to be removed in IDEA 17) */
public PsiAnnotation copyNullableAnnotation(PsiModifierListOwner owner) {
return copyAnnotation(owner, getNullableAnnotation(owner, false));
}
private PsiAnnotation copyAnnotation(PsiModifierListOwner owner, PsiAnnotation annotation) {
String notNull = checkContainer(annotation);
return notNull != null ? JavaPsiFacade.getElementFactory(owner.getProject()).createAnnotationFromText("@" + notNull, owner) : null;
private static PsiAnnotation copyAnnotation(PsiModifierListOwner owner, @NotNull PsiAnnotation annotation) {
String qualifiedName = annotation.getQualifiedName();
return qualifiedName != null
? JavaPsiFacade.getElementFactory(owner.getProject()).createAnnotationFromText("@" + qualifiedName, owner)
: null;
}
public abstract void setDefaultNotNull(@NotNull String defaultNotNull);
@@ -194,6 +186,30 @@ public abstract class NullableNotNullManager {
return nullityDefault != null && nullityDefault.getNullability() == wantedNullability ? nullityDefault.getAnnotation() : null;
}
/**
* Returns own nullability annotation info for given element. Returned annotation is not inherited and
* not container annotation for class/package. Still it could be inferred or external.
*
* @param owner element to find a nullability info for
* @return own nullability annotation info.
*/
@Nullable
public NullabilityAnnotationInfo findOwnNullabilityAnnotationInfo(@NotNull PsiModifierListOwner owner) {
PsiType type = getOwnerType(owner);
if (type == null || TypeConversionUtil.isPrimitiveAndNotNull(type)) return null;
List<String> nullables = getNullablesWithNickNames();
Set<String> annotationNames = ContainerUtil.newHashSet(nullables);
annotationNames.addAll(getNotNullsWithNickNames());
PsiAnnotation annotation = findPlainNullityAnnotation(owner, false);
if (annotation != null) {
return new NullabilityAnnotationInfo(annotation,
nullables.contains(annotation.getQualifiedName()) ? Nullability.NULLABLE : Nullability.NOT_NULL,
false);
}
return null;
}
/**
* Returns effective nullability derived from annotations for given element.
*
@@ -407,11 +423,11 @@ public abstract class NullableNotNullManager {
public abstract List<String> getNotNulls();
public static boolean isNullable(@NotNull PsiModifierListOwner owner) {
return getInstance(owner.getProject()).isNullable(owner, true);
return getInstance(owner.getProject()).findEffectiveNullability(owner) == Nullability.NULLABLE;
}
public static boolean isNotNull(@NotNull PsiModifierListOwner owner) {
return getInstance(owner.getProject()).isNotNull(owner, true);
return getInstance(owner.getProject()).findEffectiveNullability(owner) == Nullability.NOT_NULL;
}
@NotNull
@@ -2,6 +2,7 @@
package com.intellij.psi.util;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.Nullability;
import com.intellij.codeInsight.NullableNotNullManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
@@ -293,12 +294,9 @@ public class RedundantCastUtil {
final PsiMethod newTargetMethod) {
// the cast may be for the @NotNull which newTargetMethod has whereas the oldTargetMethod doesn't
NullableNotNullManager nnm = NullableNotNullManager.getInstance(project);
boolean oldNotNull = nnm.isNotNull(oldTargetMethod, true);
boolean newNotNull = nnm.isNotNull(newTargetMethod, true);
if (oldNotNull != newNotNull) return false;
boolean oldNullable = nnm.isNullable(oldTargetMethod, true);
boolean newNullable = nnm.isNullable(newTargetMethod, true);
return oldNullable == newNullable;
Nullability oldNullability = nnm.findEffectiveNullability(oldTargetMethod);
Nullability newNullability = nnm.findEffectiveNullability(newTargetMethod);
return oldNullability == newNullability;
}
private static boolean areThrownExceptionsCompatible(final PsiMethod targetMethod, final PsiMethod newTargetMethod) {