@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; }
@Override public DfaInstructionState[] visitInstanceof( InstanceofInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) { memState.pop(); memState.pop(); memState.push( new DfaInstanceofValue( runner.getFactory(), instruction.getLeft(), instruction.getCastType())); return new DfaInstructionState[] { new DfaInstructionState(runner.getInstruction(instruction.getIndex() + 1), memState) }; }
@Override public DfaInstructionState[] visitAssign( AssignInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) { final Instruction nextInstruction = runner.getInstruction(instruction.getIndex() + 1); final DfaValue dfaSource = memState.pop(); final DfaValue dfaDest = memState.pop(); if (dfaDest instanceof DfaVariableValue) { DfaVariableValue var = (DfaVariableValue) dfaDest; final PsiExpression rightValue = instruction.getRExpression(); final PsiElement parent = rightValue == null ? null : rightValue.getParent(); final IElementType type = parent instanceof PsiAssignmentExpression ? ((PsiAssignmentExpression) parent).getOperationTokenType() : JavaTokenType.EQ; // store current value - to use in case of '+=' final PsiExpression prevValue = ((ValuableDataFlowRunner.ValuableDfaVariableState) ((ValuableDataFlowRunner.MyDfaMemoryState) memState).getVariableState(var)) .myExpression; memState.setVarValue(var, dfaSource); // state may have been changed so re-retrieve it final ValuableDataFlowRunner.ValuableDfaVariableState curState = (ValuableDataFlowRunner.ValuableDfaVariableState) ((ValuableDataFlowRunner.MyDfaMemoryState) memState).getVariableState(var); final PsiExpression curValue = curState.myExpression; final PsiExpression nextValue; if (type == JavaTokenType.PLUSEQ && prevValue != null) { PsiExpression tmpExpression; try { tmpExpression = JavaPsiFacade.getElementFactory(myContext.getProject()) .createExpressionFromText( prevValue.getText() + "+" + rightValue.getText(), rightValue); } catch (Exception e) { tmpExpression = curValue == null ? rightValue : curValue; } nextValue = tmpExpression; } else { nextValue = curValue == null ? rightValue : curValue; } curState.myExpression = nextValue; } memState.push(dfaDest); return new DfaInstructionState[] {new DfaInstructionState(nextInstruction, memState)}; }