예제 #1
0
  ECR join(ECR e1, ECR e2) {
    if (e1.equals(e2)) return e1;

    checkStructCollapse(e1, e2);

    ValueType t1 = getType(e1);
    ValueType t2 = getType(e2);

    Collection<Pair<Size, ECR>> ccjoins1 = ImmutableList.copyOf(getCCjoins(e1));
    Collection<Pair<Size, ECR>> ccjoins2 = ImmutableList.copyOf(getCCjoins(e2));

    Collection<ECR> cjoins1 = ImmutableList.copyOf(getCjoins(e1));
    Collection<ECR> cjoins2 = ImmutableList.copyOf(getCjoins(e2));

    ECR root = union(e1, e2);

    switch (t1.getKind()) {
      case BOTTOM:
        {
          switch (t2.getKind()) {
            case BOTTOM:
              {
                Collection<ECR> cjoins = Sets.newHashSet();
                cjoins.addAll(cjoins1);
                cjoins.addAll(cjoins2);
                root.addCjoins(cjoins);

                Collection<Pair<Size, ECR>> ccjoins = Sets.newHashSet();
                ccjoins.addAll(ccjoins1);
                ccjoins.addAll(ccjoins2);
                root.addCCjoins(ccjoins);

                break;
              }
            default:
              {
                root.setType(t2);

                root.clearCCjoins(ccjoins1);
                for (Pair<Size, ECR> pair : ccjoins1) ccjoin(pair.fst(), root, pair.snd());

                root.clearCjoins(cjoins1);
                for (ECR cjoin : cjoins1) cjoin(root, cjoin);

                break;
              }
          }
          break;
        }
      default:
        {
          switch (t2.getKind()) {
            case BOTTOM:
              {
                root.setType(t1);

                root.clearCCjoins(ccjoins2);
                for (Pair<Size, ECR> pair : ccjoins2) ccjoin(pair.fst(), root, pair.snd());

                root.clearCjoins(cjoins2);
                for (ECR cjoin : cjoins2) cjoin(root, cjoin);

                break;
              }
            default:
              {
                root.setType(t1);
                ValueType unionType = unify(t1, t2);

                ValueType freshType = getType(root);
                if (!freshType.equals(t1)) {
                  unionType = resolveType(root, unionType, freshType);
                }

                root.setType(unionType);

                root.clearCCjoins(ccjoins1);
                root.clearCCjoins(ccjoins2);

                for (Pair<Size, ECR> pair : ccjoins1) ccjoin(pair.fst(), root, pair.snd());
                for (Pair<Size, ECR> pair : ccjoins2) ccjoin(pair.fst(), root, pair.snd());
                break;
              }
          }
          break;
        }
    }

    return root;
  }