예제 #1
0
  /**
   * Collapse <code>structECR</code> by merge it with all its element ECRs, and set its type as the
   * cell type (simple type might with top size)
   *
   * @param structECR
   * @param structT
   * @param ECRCache avoid structure cycle
   * @return
   */
  private ValueType collapseStruct(ECR structECR, StructType structT, Collection<ECR> ECRCache) {
    // Ensure collapsed type to be simple
    ValueType unionType = null;

    // join components
    Collection<ECR> elems = structT.getFieldMap().asMapOfRanges().values();
    Collection<ECR> cjoins = Sets.newHashSet();
    Collection<Pair<Size, ECR>> ccjoins = Sets.newHashSet();

    for (ECR elem : elems) {
      ECR elemLoc = getLoc(elem);
      ValueType elemLocType = getType(elemLoc);
      Parent parent = elemLocType.getParent().removeECR(structECR);
      elemLocType.setParent(parent);

      if (!ECRCache.add(elemLoc)) continue; // ECRCache has elemLoc

      cjoins.addAll(getCjoins(elemLoc));
      elemLoc.clearCCjoins(ccjoins);
      ccjoins.addAll(getCCjoins(elemLoc));
      elemLoc.clearCCjoins(ccjoins);

      if (elemLocType.isStruct()) {
        elemLocType = collapseStruct(elemLoc, elemLocType.asStruct(), ECRCache);
      }

      union(structECR, elemLoc);
      unionType = unionType == null ? elemLocType : unify(unionType, elemLocType);
    }
    unionType = unionType == null ? ValueType.bottom() : unionType;

    setType(structECR, unionType);
    ECR root = findRoot(structECR);

    for (Pair<Size, ECR> cjoinPair : ccjoins) ccjoin(cjoinPair.fst(), root, cjoinPair.snd());

    for (ECR joinECR : cjoins) cjoin(root, joinECR);

    return unionType;
  }