예제 #1
0
  /**
   * During the join process, there might be cycle. It means the ECR <code>
   * root</code> might be set to <code>freshType</code>. The type-union should take care of it --
   * union <code>freshType</code> to <code>unionType</code>. In particular, <code>freshType</code>
   * is an object type, while <code>
   * unionType</code> is a struct type, then <code>unionType</code> should be collapsed before union
   * with <code>freshType</code>.
   *
   * @param root
   * @param unionType
   * @param freshType
   * @return unified type
   */
  private ValueType resolveType(ECR root, ValueType unionType, ValueType freshType) {
    Preconditions.checkArgument(!unionType.isLambda());
    Preconditions.checkArgument(!freshType.isLambda());

    Pair<ValueType, ValueType> pair = swap(unionType, freshType);
    ValueType t1 = pair.fst(), t2 = pair.snd();

    if (t1.isSimple() && t2.isStruct()) {
      Collection<ECR> elems = t2.asStruct().getFieldMap().asMapOfRanges().values();
      ValueType resType = t1;
      for (ECR elem : elems) {
        ECR elemLoc = getLoc(elem);
        ValueType elemLocType = getType(elemLoc);
        Parent parent = elemLocType.getParent().removeECR(root);
        elemLocType.setParent(parent);
        if (elemLocType.isStruct()) {
          elemLocType = collapseStruct(elemLoc, elemLocType.asStruct());
        }

        union(root, elemLoc);
        resType = unify(resType, elemLocType);
      }
      return resType;
    }

    return unify(t1, t2);
  }
예제 #2
0
  /**
   * Check if one of <code>e1</code> or <code>e2</code> is a struct, and the other is either object
   * or simple, collapse the one with struct type
   *
   * @param e1
   * @param e2
   */
  private void checkStructCollapse(ECR e1, ECR e2) {
    ValueType t1 = getType(e1);
    ValueType t2 = getType(e2);

    if (t2.isStruct() && t1.isSimple()) {
      collapseStruct(e2, t2.asStruct());
      return;
    }

    if (t1.isStruct() && t2.isSimple()) {
      collapseStruct(e1, t1.asStruct());
      return;
    }

    return;
  }