private Nullness calcInherentNullability() { PsiModifierListOwner var = getPsiVariable(); Nullness nullability = DfaPsiUtil.getElementNullability(getVariableType(), var); if (nullability != Nullness.UNKNOWN) { return nullability; } Nullness defaultNullability = myFactory.isUnknownMembersAreNullable() && MEMBER_OR_METHOD_PARAMETER.accepts(var) ? Nullness.NULLABLE : Nullness.UNKNOWN; if (var instanceof PsiParameter && var.getParent() instanceof PsiForeachStatement) { PsiExpression iteratedValue = ((PsiForeachStatement) var.getParent()).getIteratedValue(); if (iteratedValue != null) { PsiType itemType = JavaGenericsUtil.getCollectionItemType(iteratedValue); if (itemType != null) { return DfaPsiUtil.getElementNullability(itemType, var); } } } if (var instanceof PsiField && DfaPsiUtil.isFinalField((PsiVariable) var) && myFactory.isHonorFieldInitializers()) { List<PsiExpression> initializers = DfaPsiUtil.findAllConstructorInitializers((PsiField) var); if (initializers.isEmpty()) { return defaultNullability; } boolean hasUnknowns = false; for (PsiExpression expression : initializers) { Nullness nullness = getFieldInitializerNullness(expression); if (nullness == Nullness.NULLABLE) { return Nullness.NULLABLE; } if (nullness == Nullness.UNKNOWN) { hasUnknowns = true; } } if (hasUnknowns) { if (DfaPsiUtil.isInitializedNotNull((PsiField) var)) { return Nullness.NOT_NULL; } return defaultNullability; } return Nullness.NOT_NULL; } return defaultNullability; }
private static Nullness getFieldInitializerNullness(@NotNull PsiExpression expression) { if (expression.textMatches(PsiKeyword.NULL)) return Nullness.NULLABLE; if (expression instanceof PsiNewExpression || expression instanceof PsiLiteralExpression || expression instanceof PsiPolyadicExpression) return Nullness.NOT_NULL; if (expression instanceof PsiReferenceExpression) { PsiElement target = ((PsiReferenceExpression) expression).resolve(); return DfaPsiUtil.getElementNullability(null, (PsiModifierListOwner) target); } if (expression instanceof PsiMethodCallExpression) { PsiMethod method = ((PsiMethodCallExpression) expression).resolveMethod(); return method != null ? DfaPsiUtil.getElementNullability(null, method) : Nullness.UNKNOWN; } return Nullness.UNKNOWN; }
@Nullable private static Map<PsiExpression, PsiType> buildDataflowTypeMap(PsiExpression forPlace) { PsiElement scope = DfaPsiUtil.getTopmostBlockInSameClass(forPlace); if (scope == null) { PsiFile file = forPlace.getContainingFile(); if (!(file instanceof PsiCodeFragment)) { return Collections.emptyMap(); } scope = file; } DataFlowRunner runner = new DataFlowRunner() { @NotNull @Override protected DfaMemoryState createMemoryState() { return new ExpressionTypeMemoryState(getFactory()); } }; final ExpressionTypeInstructionVisitor visitor = new ExpressionTypeInstructionVisitor(forPlace); if (runner.analyzeMethod(scope, visitor) == RunnerResult.OK) { return visitor.getResult(); } return null; }