StandardDataFlowInterpreter (@NotNull DfaListener listener, @NotNull ControlFlow flow) { return new StandardDataFlowInterpreter(flow, listener) { @Override public int getComplexityLimit() { // Limit analysis complexity for completion as it could be relaunched many times return DEFAULT_MAX_STATES_PER_BRANCH / 3; } @Override protected void afterInstruction(Instruction instruction) { super.afterInstruction(instruction); if (myPlaceVisited && flow.getLoopNumbers()[instruction.getIndex()] == 0) { // We cancel the analysis first time we exit all the loops // after the target expression is visited (in this case, // we can be sure we'll not reach it again) cancel(); } } @Override protected DfaInstructionState @NotNull [] acceptInstruction(@NotNull DfaInstructionState instructionState) { Instruction instruction = instructionState.getInstruction(); DfaMemoryState memState = instructionState.getMemoryState(); if (instruction instanceof TypeCastInstruction typeCast) { DfaValue value = memState.pop(); memState.push(adjustValue(value, typeCast.getCasted())); } else if (instruction instanceof InstanceofInstruction instanceOf) { DfaValue dfaRight = memState.pop(); DfaValue dfaLeft = memState.pop(); memState.push(adjustValue(dfaLeft, getInstanceOfOperand(instanceOf))); memState.push(dfaRight); } return super.acceptInstruction(instructionState); } @Nullable private static PsiExpression getInstanceOfOperand(InstanceofInstruction instruction) { if (instruction.getDfaAnchor() instanceof JavaExpressionAnchor anchor && anchor.getExpression() instanceof PsiInstanceOfExpression instanceOf) { return instanceOf.getOperand(); } return null; } private DfaValue adjustValue(@NotNull DfaValue value, @Nullable PsiExpression expression) { if (expression != null && isInteresting(value, expression)) { return getFactory().getVarFactory().createVariableValue(new ExpressionVariableDescriptor(expression)); } return value; } private boolean isInteresting(@NotNull DfaValue value, @NotNull PsiExpression expression) { if (myPlace == null) return true; return (!(value instanceof DfaVariableValue var) || var.isFlushableByCalls()) && ExpressionVariableDescriptor.EXPRESSION_HASHING_STRATEGY.equals(expression, myPlace); } }; }