Beispiel #1
0
  @Override
  public Map<String, TypedAST> getChildren() {
    Map<String, TypedAST> children = new HashMap<>();

    for (Case c : cases) {
      // is there a proper convention for names in children?
      children.put("match case: " + c.getTaggedTypeMatch(), c.getAST());
    }

    if (defaultCase != null) {
      children.put("match default-case: " + defaultCase.getTaggedTypeMatch(), defaultCase.getAST());
    }

    return children;
  }
Beispiel #2
0
  /**
   * Helper method to simplify checking for a tag. Returns true if the given binding tag is present
   * in the list of cases.
   *
   * @param cases
   * @param binding
   * @return
   */
  private boolean containsTagBinding(List<Case> cases, Type tagName) {
    for (Case c : cases) {
      // Found a match, this tag is present
      if (c.getTaggedTypeMatch().equals(tagName)) return true;
    }

    return false;
  }
Beispiel #3
0
  private void checkAllCasesAreUnique() {
    // All tagged types must be unique
    Set<Type> caseSet = new HashSet<Type>();

    for (Case c : cases) {
      if (c.isTyped()) caseSet.add(c.getTaggedTypeMatch());
    }

    if (caseSet.size() != cases.size()) {
      ToolError.reportError(ErrorMessage.DUPLICATE_TAG, matchingOver);
    }
  }
Beispiel #4
0
  /**
   * Checks that the tag we are matching over is a supertag of every tag in the case-list.
   *
   * <p>This ensures that each tag could actually have a match and that case is not unreachable
   * code.
   *
   * @param matchingOverTag
   */
  private void checkStaticSubtags(TaggedInfo matchingOver) {
    for (Case c : cases) {
      TaggedInfo matchTarget = TaggedInfo.lookupTagByType(c.getTaggedTypeMatch()); // FIXME:

      if (!isSubtag(matchTarget, matchingOver)) {
        ToolError.reportError(
            ErrorMessage.UNMATCHABLE_CASE,
            this.matchingOver,
            matchingOver.getTagName(),
            matchTarget.getTagName());
      }
    }
  }
Beispiel #5
0
  private void checkSubtagsPreceedSupertags() {
    // A tag cannot be earlier than one of its subtags
    for (int i = 0; i < cases.size() - 1; i++) {
      Case beforeCase = cases.get(i);
      TaggedInfo beforeTag = TaggedInfo.lookupTagByType(beforeCase.getTaggedTypeMatch()); // FIXME:

      for (int j = i + 1; j < cases.size(); j++) {
        Case afterCase = cases.get(j);

        if (afterCase.isDefault()) break;

        TaggedInfo afterTag = TaggedInfo.lookupTagByType(afterCase.getTaggedTypeMatch()); // FIXME:
        // TagBinding afterBinding = TagBinding.get(afterCase.getTaggedTypeMatch());

        if (afterTag != null && beforeTag != null && isSubtag(afterTag, beforeTag)) {
          ToolError.reportError(
              ErrorMessage.SUPERTAG_PRECEEDS_SUBTAG,
              matchingOver,
              beforeTag.getTagName(),
              afterTag.getTagName());
        }
      }
    }
  }
Beispiel #6
0
  private void checkAllCasesAreTagged(Environment env) {
    // All things we match over must be tagged types
    for (Case c : cases) {
      if (c.isDefault()) continue;

      Type tagName = c.getTaggedTypeMatch();

      if (tagName instanceof UnresolvedType) {
        UnresolvedType ut = (UnresolvedType) tagName;
        // System.out.println("ut = " + ut.resolve(env));
      }

      if (tagName instanceof TypeInv) {
        // TypeInv ti = (TypeInv) tagName;
        // System.out.println("ti = " + ti.resolve(env));
        // tagName = ti.resolve(env);
        // if (tagName instanceof UnresolvedType) {
        // tagName = ((UnresolvedType) tagName).resolve(env);
        // } DO NOT UNCOMMENT THIS AS BREAKS CASES
        return; // FIXME: Assume TypeInv will sort itself out during runtime.
      }

      // System.out.println(tagName);

      // check type exists
      // TypeBinding type = env.lookupType(tagName.toString()); // FIXME:

      // if (type == null) {
      //	ToolError.reportError(ErrorMessage.TYPE_NOT_DECLARED, this, tagName.toString());
      // }

      // check it is tagged
      TaggedInfo info = TaggedInfo.lookupTagByType(tagName); // FIXME:

      if (info == null) {
        ToolError.reportError(ErrorMessage.TYPE_NOT_TAGGED, matchingOver, tagName.toString());
      }
    }
  }
Beispiel #7
0
  @Override
  public Value evaluate(EvaluationEnvironment env) {
    // TaggedInfo.resolveAll(env, this);

    Type mo = matchingOver.getType();

    TaggedInfo matchingOverTag = TaggedInfo.lookupTagByType(mo); // FIXME:

    if (matchingOver instanceof Variable) {
      Variable w = (Variable) matchingOver;
      // ClassType wType = (ClassType) env.lookup(w.getName()).getType();
      // System.out.println("wType = " + wType);
      // System.out.println("looked up = " + TaggedInfo.lookupTagByType(wType));
      // System.out.println("but mot = " + matchingOverTag);
      matchingOverTag =
          ((Obj)
                  env.lookup(w.getName())
                      .map(ib -> ib.getValue(env))
                      .orElseThrow(() -> new RuntimeException("Invalid matching over tag")))
              .getTaggedInfo();
    }

    // System.out.println("Evaluating match with matchingOver = " + matchingOver + " its class " +
    // matchingOver.getClass());
    /*
    Variable v = (Variable) matchingOver;
    System.out.println("v.getType() = " + v.getType());
    System.out.println("v.getName() = " + v.getName());
    System.out.println(env);
    System.out.println(env.lookup(v.getName()));

    System.out.println("mo = " + mo + " and its class is " + mo.getClass());
    System.out.println(env.lookup(v.getName()).getUse());
    System.out.println(env.lookup(v.getName()).getValue(env));

    TypeType ttmo = (TypeType) mo;
    System.out.println("ttmo.getName() is declared but not actual type = " + ttmo.getName());
    TypeType tttmo = (TypeType) ((MetadataWrapper) v.typecheck(env, Optional.empty())).getInner();
    System.out.println("v.type = " + tttmo.getName());

    TaggedInfo.dumpall(env);
    */

    // System.out.println("Evaluating match over tag: " + matchingOverTag + " with matchingOver = "
    // + matchingOver.getType());
    if (matchingOver.getType() instanceof ClassType) {
      ClassType ct = (ClassType) matchingOver.getType();
      // System.out.println("hmm = " + this.matchingOver.typecheck(env, Optional.empty()));
      // System.out.println("ct = " + ct.getName());
    }

    // System.out.println("matchingOverTag (latest) = " + matchingOverTag);
    int cnt = 0;

    for (Case c : cases) {
      cnt++;

      // String caseTypeName = getTypeName(c.getAST());

      // System.out.println("case "+ cnt + " = " + c);

      Type tt = c.getTaggedTypeMatch();

      TaggedInfo caseTag;
      if (tt instanceof TypeInv) {
        TypeInv ti = (TypeInv) tt;

        // System.out.println("Processing TypeInv case: " + ti);

        // FIXME: In ECOOP2015Artifact, I am trying to tell the difference between winMod.Win and
        // bigWinMod.Win...

        Type ttti = ti.getInnerType();
        String mbr = ti.getInvName();

        if (ttti instanceof UnresolvedType) {
          Value objVal = env.lookup(((UnresolvedType) ttti).getName()).get().getValue(env);
          caseTag =
              ((Obj) objVal)
                  .getIntEnv()
                  .lookupBinding(mbr, HackForArtifactTaggedInfoBinding.class)
                  .map(b -> b.getTaggedInfo())
                  .orElseThrow(() -> new RuntimeException("Invalid tag invocation"));

        } else {
          // tt = ti.resolve(env); TODO: is this valid?
          caseTag = TaggedInfo.lookupTagByType(tt); // FIXME:
        }
      } else {
        caseTag = TaggedInfo.lookupTagByType(tt); // FIXME:
      }

      // System.out.println("case " + cnt + " type = " + tt);

      // System.out.println("caseTag = " + caseTag);

      if (caseTag != null && isSubtag(matchingOverTag, caseTag)) {
        // We've got a match, evaluate this case
        // System.out.println("MAAAAATTTCH!");
        return c.getAST().evaluate(env);
      }
    }

    // No match, evaluate the default case
    // System.out.println("DEFAULT: " + defaultCase.getAST().evaluate(env));
    return defaultCase.getAST().evaluate(env);
  }