Set<PsiField> (PsiCodeBlock body) { if (body == null) return Collections.emptySet(); return CachedValuesManager.getCachedValue(body, new CachedValueProvider<>() { @NotNull @Override public Result<Set<PsiField>> compute() { PsiClass containingClass = PsiTreeUtil.getContextOfType(body, PsiClass.class); LOG.assertTrue(containingClass != null); DfaValueFactory factory = new DfaValueFactory(body.getProject()); ControlFlow flow = ControlFlowAnalyzer.buildFlow(body, factory, true); if (flow == null) { return Result.create(Set.of(), body, PsiModificationTracker.MODIFICATION_COUNT); } var interpreter = new StandardDataFlowInterpreter(flow, DfaListener.EMPTY) { final Map<PsiField, Boolean> map = new HashMap<>(); private boolean isCallExposingNonInitializedFields(Instruction instruction) { if (!(instruction instanceof MethodCallInstruction)) { return false; } PsiCall call = ((MethodCallInstruction)instruction).getCallExpression(); if (call == null) return false; if (call instanceof PsiNewExpression && canAccessFields((PsiExpression)call)) { return true; } if (call instanceof PsiMethodCallExpression) { PsiExpression qualifier = ((PsiMethodCallExpression)call).getMethodExpression().getQualifierExpression(); if (qualifier == null || canAccessFields(qualifier)) { return true; } } PsiExpressionList argumentList = call.getArgumentList(); if (argumentList != null) { for (PsiExpression expression : argumentList.getExpressions()) { if (canAccessFields(expression)) return true; } } return false; } private boolean canAccessFields(PsiExpression expression) { PsiClass type = PsiUtil.resolveClassInClassTypeOnly(expression.getType()); JBIterable<PsiClass> typeContainers = JBIterable.generate(type, PsiClass::getContainingClass).takeWhile(c -> !c.hasModifierProperty(PsiModifier.STATIC)); return typeContainers.contains(containingClass); } @Override protected DfaInstructionState @NotNull [] acceptInstruction(@NotNull DfaInstructionState instructionState) { Instruction instruction = instructionState.getInstruction(); if (instruction instanceof FinishElementInstruction) { Set<DfaVariableValue> vars = ((FinishElementInstruction)instruction).getVarsToFlush(); vars.removeIf(v -> { PsiElement variable = v.getPsiVariable(); return variable instanceof PsiField && ((PsiField)variable).getContainingClass() == containingClass; }); } if ((isCallExposingNonInitializedFields(instruction) || instruction instanceof ReturnInstruction)) { for (PsiField field : containingClass.getFields()) { DfaVariableValue value = PlainDescriptor.createVariableValue(getFactory(), field); DfType dfType = instructionState.getMemoryState().getDfType(value); if (dfType.isSuperType(DfTypes.NULL)) { map.put(field, false); } else if (!map.containsKey(field)) { map.put(field, true); } } return DfaInstructionState.EMPTY_ARRAY; } return super.acceptInstruction(instructionState); } }; DfaMemoryState state = DfaUtil.createStateWithEnabledAssertions(factory); final RunnerResult rc = interpreter.interpret(state); Set<PsiField> notNullFields = new HashSet<>(); if (rc == RunnerResult.OK) { interpreter.map.forEach((key, value) -> { if (value) { notNullFields.add(key); } }); } return Result.create(notNullFields, body, PsiModificationTracker.MODIFICATION_COUNT); } }); }