CauseItem (MemoryStateChange factUse, DfaNullability nullability) { PsiExpression expression = factUse.getExpression(); if (expression instanceof PsiTypeCastExpression) { MemoryStateChange operandPush = factUse.findSubExpressionPush(((PsiTypeCastExpression)expression).getOperand()); if (operandPush != null) { return findNullabilityCause(operandPush, nullability); } } if (expression instanceof PsiMethodCallExpression call) { PsiMethod method = call.resolveMethod(); CauseItem causeItem = fromMemberNullability(nullability, method, JavaElementKind.METHOD, call.getMethodExpression().getReferenceNameElement()); if (causeItem == null) { causeItem = switch (nullability) { case NULL, NULLABLE -> fromCallContract(factUse, call, ContractReturnValue.returnNull()); case NOT_NULL -> fromCallContract(factUse, call, ContractReturnValue.returnNotNull()); default -> null; }; } if (causeItem != null) { return causeItem; } } if (expression instanceof PsiReferenceExpression) { PsiVariable variable = ObjectUtils.tryCast(((PsiReferenceExpression)expression).resolve(), PsiVariable.class); if (variable != null) { CauseItem causeItem = fromMemberNullability(nullability, variable, JavaElementKind.fromElement(variable), expression); if (causeItem != null) { return causeItem; } } } FactDefinition<DfaNullability> info = factUse.findFact(factUse.myTopOfStack, FactExtractor.nullability()); MemoryStateChange factDef = info.myFact == nullability ? info.myChange : null; if (nullability == DfaNullability.NOT_NULL) { String explanation = getObviouslyNonNullExplanation(expression); if (explanation != null) { return new CauseItem(JavaAnalysisBundle.message("dfa.find.cause.obviously.non.null.expression", explanation), expression); } if (factDef != null) { if (factDef.myInstruction instanceof CheckNotNullInstruction) { NullabilityProblemKind.NullabilityProblem<?> problem = ((CheckNotNullInstruction)factDef.myInstruction).getProblem(); PsiExpression dereferenced = problem.getDereferencedExpression(); String text = dereferenced == null ? factUse.myTopOfStack.toString() : dereferenced.getText(); if (dereferenced != null && problem.getKind() == NullabilityProblemKind.passingToNotNullParameter) { PsiExpression arg = dereferenced; while (arg.getParent() instanceof PsiParenthesizedExpression) { arg = (PsiExpression)arg.getParent(); } PsiParameter parameter = MethodCallUtils.getParameterForArgument(dereferenced); if (parameter != null) { CauseItem item = new CauseItem(JavaAnalysisBundle.message("dfa.find.cause.was.passed.as.non.null.parameter", text), dereferenced); item.addChildren(fromMemberNullability(DfaNullability.NOT_NULL, parameter, JavaElementKind.PARAMETER, dereferenced)); return item; } } return new CauseItem(JavaAnalysisBundle.message("dfa.find.cause.was.dereferenced", text), dereferenced); } if (factDef.myInstruction instanceof InstanceofInstruction) { DfaAnchor anchor = ((InstanceofInstruction)factDef.myInstruction).getDfaAnchor(); if (anchor instanceof JavaExpressionAnchor) { PsiExpression operand = ((JavaExpressionAnchor)anchor).getExpression(); return new CauseItem(JavaAnalysisBundle.message("dfa.find.cause.instanceof.implies.non.nullity"), operand); } } } } if (factDef != null && expression != null) { DfaValue value = factUse.myTopOfStack; if (factDef.myInstruction instanceof AssignInstruction && factDef.myTopOfStack == value) { PsiExpression rExpression = ((AssignInstruction)factDef.myInstruction).getRExpression(); if (rExpression != null) { MemoryStateChange rValuePush = factDef.findSubExpressionPush(rExpression); if (rValuePush != null) { CauseItem assignmentItem = createAssignmentCause((AssignInstruction)factDef.myInstruction, value); MemoryStateChange previous = factDef.getPrevious(); if (previous != null && previous.myInstruction instanceof WrapDerivedVariableInstruction instruction) { DerivedVariableDescriptor descriptor = instruction.getDerivedVariableDescriptor(); if (descriptor == SpecialField.UNBOX) { DfaAnchor anchor = instruction.getDfaAnchor(); assignmentItem.addChildren( new CauseItem(JavaAnalysisBundle.message("dfa.find.cause.primitive.boxed"), anchor instanceof JavaExpressionAnchor ? ((JavaExpressionAnchor)anchor).getExpression() : rExpression)); } } assignmentItem.addChildren(findNullabilityCause(rValuePush, nullability)); return assignmentItem; } } } PsiExpression defExpression = factDef.getExpression(); if (defExpression != null) { return new CauseItem( JavaAnalysisBundle.message("dfa.find.cause.value.is.known.from.place", expression.getText(), nullability.getPresentationName()), defExpression); } } return null; }