@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)
   };
 }
Example #3
0
    @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)};
    }