Пример #1
0
  @Override
  public boolean checkNotNullable(DfaValue value) {
    if (value == myFactory.getConstFactory().getNull()) return false;
    if (value instanceof DfaTypeValue && ((DfaTypeValue) value).isNullable()) return false;

    if (value instanceof DfaVariableValue) {
      DfaVariableValue varValue = (DfaVariableValue) value;
      if (varValue.getVariableType() instanceof PsiPrimitiveType) return true;
      if (isNotNull(varValue)) return true;
      if (getVariableState(varValue).isNullable()) return false;
    }
    return true;
  }
Пример #2
0
 @Override
 public void flushFields() {
   Set<DfaVariableValue> vars = ContainerUtil.newLinkedHashSet(getChangedVariables());
   for (EqClass aClass : myEqClasses) {
     if (aClass != null) {
       vars.addAll(aClass.getVariables(true));
     }
   }
   for (DfaVariableValue value : vars) {
     if (value.isFlushableByCalls()) {
       doFlush(value, shouldMarkUnknown(value));
     }
   }
 }
Пример #3
0
  private boolean applyBoxedRelation(
      @NotNull DfaVariableValue dfaLeft, DfaValue dfaRight, boolean negated) {
    if (!TypeConversionUtil.isPrimitiveAndNotNull(dfaLeft.getVariableType())) return true;

    DfaBoxedValue.Factory boxedFactory = myFactory.getBoxedFactory();
    DfaValue boxedLeft = boxedFactory.createBoxed(dfaLeft);
    DfaValue boxedRight = boxedFactory.createBoxed(dfaRight);
    return boxedLeft == null || boxedRight == null || applyRelation(boxedLeft, boxedRight, negated);
  }
Пример #4
0
  @Override
  public boolean applyCondition(DfaValue dfaCond) {
    if (dfaCond instanceof DfaUnknownValue) return true;
    if (dfaCond instanceof DfaUnboxedValue) {
      DfaVariableValue dfaVar = ((DfaUnboxedValue) dfaCond).getVariable();
      boolean isNegated = dfaVar.isNegated();
      DfaVariableValue dfaNormalVar = isNegated ? dfaVar.createNegated() : dfaVar;
      final DfaValue boxedTrue =
          myFactory.getBoxedFactory().createBoxed(myFactory.getConstFactory().getTrue());
      return applyRelationCondition(
          myFactory
              .getRelationFactory()
              .createRelation(dfaNormalVar, boxedTrue, JavaTokenType.EQEQ, isNegated));
    }
    if (dfaCond instanceof DfaVariableValue) {
      DfaVariableValue dfaVar = (DfaVariableValue) dfaCond;
      boolean isNegated = dfaVar.isNegated();
      DfaVariableValue dfaNormalVar = isNegated ? dfaVar.createNegated() : dfaVar;
      DfaConstValue dfaTrue = myFactory.getConstFactory().getTrue();
      return applyRelationCondition(
          myFactory
              .getRelationFactory()
              .createRelation(dfaNormalVar, dfaTrue, JavaTokenType.EQEQ, isNegated));
    }

    if (dfaCond instanceof DfaConstValue) {
      return dfaCond == myFactory.getConstFactory().getTrue()
          || dfaCond != myFactory.getConstFactory().getFalse();
    }

    if (!(dfaCond instanceof DfaRelationValue)) return true;

    return applyRelationCondition((DfaRelationValue) dfaCond);
  }
Пример #5
0
  private boolean applyUnboxedRelation(
      @NotNull DfaVariableValue dfaLeft, DfaValue dfaRight, boolean negated) {
    PsiType type = dfaLeft.getVariableType();
    if (!TypeConversionUtil.isPrimitiveWrapper(type)) {
      return true;
    }
    if (negated) {
      // from the fact "wrappers are not the same" it does not follow that "unboxed values are not
      // equal"
      return true;
    }

    DfaBoxedValue.Factory boxedFactory = myFactory.getBoxedFactory();
    DfaValue unboxedLeft = boxedFactory.createUnboxed(dfaLeft);
    DfaValue unboxedRight = boxedFactory.createUnboxed(dfaRight);
    return applyRelation(unboxedLeft, unboxedRight, false)
        && checkCompareWithBooleanLiteral(unboxedLeft, unboxedRight, false);
  }
Пример #6
0
  DfaVariableState getVariableState(DfaVariableValue dfaVar) {
    DfaVariableState state = myVariableStates.get(dfaVar);

    if (state == null) {
      state = myDefaultVariableStates.get(dfaVar);
      if (state == null) {
        state = createVariableState(dfaVar);
        DfaTypeValue initialType = dfaVar.getTypeValue();
        if (initialType != null) {
          state = state.withInstanceofValue(initialType);
          assert state != null;
        }
        myDefaultVariableStates.put(dfaVar, state);
      }

      if (isUnknownState(dfaVar)) {
        return state.withNullable(false);
      }
    }

    return state;
  }
Пример #7
0
  private boolean uniteClasses(int c1Index, int c2Index) {
    EqClass c1 = myEqClasses.get(c1Index);
    EqClass c2 = myEqClasses.get(c2Index);

    Set<DfaVariableValue> vars = ContainerUtil.newTroveSet();
    Set<DfaVariableValue> negatedVars = ContainerUtil.newTroveSet();
    int[] cs = new int[c1.size() + c2.size()];
    c1.set(0, cs, 0, c1.size());
    c2.set(0, cs, c1.size(), c2.size());

    int nConst = 0;
    for (int c : cs) {
      DfaValue dfaValue = unwrap(myFactory.getValue(c));
      if (dfaValue instanceof DfaConstValue) nConst++;
      if (dfaValue instanceof DfaVariableValue) {
        DfaVariableValue variableValue = (DfaVariableValue) dfaValue;
        if (variableValue.isNegated()) {
          negatedVars.add(variableValue.createNegated());
        } else {
          vars.add(variableValue);
        }
      }
      if (nConst > 1) return false;
    }
    if (ContainerUtil.intersects(vars, negatedVars)) return false;

    TLongArrayList c2Pairs = new TLongArrayList();
    long[] distincts = myDistinctClasses.toArray();
    for (long distinct : distincts) {
      int pc1 = low(distinct);
      int pc2 = high(distinct);
      boolean addedToC1 = false;

      if (pc1 == c1Index || pc2 == c1Index) {
        addedToC1 = true;
      }

      if (pc1 == c2Index || pc2 == c2Index) {
        if (addedToC1) return false;
        c2Pairs.add(distinct);
      }
    }

    EqClass newClass = new EqClass(c1);

    myEqClasses.set(c1Index, newClass);
    for (int i = 0; i < c2.size(); i++) {
      int c = c2.get(i);
      newClass.add(c);
      removeFromMap(c, c2Index);
      addToMap(c, c1Index);
    }

    for (int i = 0; i < c2Pairs.size(); i++) {
      long c = c2Pairs.get(i);
      myDistinctClasses.remove(c);
      myDistinctClasses.add(createPair(c1Index, low(c) == c2Index ? high(c) : low(c)));
    }
    myEqClasses.set(c2Index, null);

    return true;
  }
Пример #8
0
  void doFlush(@NotNull DfaVariableValue varPlain, boolean markUnknown) {
    DfaVariableValue varNegated = varPlain.getNegatedValue();

    final int idPlain = varPlain.getID();
    final int idNegated = varNegated == null ? -1 : varNegated.getID();

    int[] classes = myIdToEqClassesIndices.get(idPlain);
    int[] negatedClasses = myIdToEqClassesIndices.get(idNegated);
    int[] result =
        ArrayUtil.mergeArrays(
            ObjectUtils.notNull(classes, ArrayUtil.EMPTY_INT_ARRAY),
            ObjectUtils.notNull(negatedClasses, ArrayUtil.EMPTY_INT_ARRAY));

    int interruptCount = 0;

    for (int varClassIndex : result) {
      EqClass varClass = myEqClasses.get(varClassIndex);
      if ((++interruptCount & 0xf) == 0) {
        ProgressManager.checkCanceled();
      }

      varClass = new EqClass(varClass);
      myEqClasses.set(varClassIndex, varClass);
      for (int id : varClass.toNativeArray()) {
        int idUnwrapped;
        if (id == idPlain
            || id == idNegated
            || (idUnwrapped = unwrap(myFactory.getValue(id)).getID()) == idPlain
            || idUnwrapped == idNegated) {
          varClass.removeValue(id);
        }
      }

      if (varClass.isEmpty()) {
        myEqClasses.set(varClassIndex, null);

        for (TLongIterator iterator = myDistinctClasses.iterator(); iterator.hasNext(); ) {
          long pair = iterator.next();
          if (low(pair) == varClassIndex || high(pair) == varClassIndex) {
            iterator.remove();
          }
        }
      } else if (varClass.containsConstantsOnly()) {
        for (TLongIterator iterator = myDistinctClasses.iterator(); iterator.hasNext(); ) {
          long pair = iterator.next();
          if (low(pair) == varClassIndex && myEqClasses.get(high(pair)).containsConstantsOnly()
              || high(pair) == varClassIndex
                  && myEqClasses.get(low(pair)).containsConstantsOnly()) {
            iterator.remove();
          }
        }
      }
    }

    removeAllFromMap(idPlain);
    removeAllFromMap(idNegated);
    myVariableStates.remove(varPlain);
    if (varNegated != null) {
      myVariableStates.remove(varNegated);
    }
    if (markUnknown) {
      myUnknownVariables.add(varPlain);
    }
    myCachedNonTrivialEqClasses = null;
    myCachedDistinctClassPairs = null;
    myCachedHash = null;
  }