public TCDefinitionList getTypeParamDefinitions() {
    TCDefinitionList defs = new TCDefinitionList();

    for (TCNameToken pname : typeParams) {
      TCDefinition p =
          new TCLocalDefinition(pname.getLocation(), pname, new TCParameterType(pname));

      p.markUsed();
      defs.add(p);
    }

    return defs;
  }
Beispiel #2
0
  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();

    for (PODefinition d : this) {
      for (TCNameToken name : d.getVariableNames()) {
        sb.append(name.getExplicit(true) + ":" + d.getType());
        sb.append("\n");
      }
    }

    return sb.toString();
  }
  public TCExplicitFunctionDefinition(
      TCAccessSpecifier accessSpecifier,
      TCNameToken name,
      TCNameList typeParams,
      TCFunctionType type,
      TCPatternListList parameters,
      TCExpression body,
      TCExpression precondition,
      TCExpression postcondition,
      boolean typeInvariant,
      TCNameToken measure) {
    super(Pass.DEFS, name.getLocation(), name, NameScope.GLOBAL);

    this.accessSpecifier = accessSpecifier;
    this.typeParams = typeParams;
    this.type = type;
    this.paramPatternList = parameters;
    this.precondition = precondition;
    this.postcondition = postcondition;
    this.body = body;
    this.isTypeInvariant = typeInvariant;
    this.measure = measure;
    this.isCurried = parameters.size() > 1;

    type.definitions = new TCDefinitionList(this);
    type.instantiated = typeParams == null ? null : false;
  }
Beispiel #4
0
  @Override
  public boolean equals(Object other) {
    other = deBracket(other);

    if (other instanceof TCClassType) {
      TCClassType oc = (TCClassType) other;
      return name.equals(oc.name); // NB. name only
    }

    return false;
  }
  @Override
  public void typeCheck(Environment base, NameScope scope) {
    TCDefinitionList defs = new TCDefinitionList();

    if (typeParams != null) {
      defs.addAll(getTypeParamDefinitions());
    }

    TypeComparator.checkComposeTypes(type, base, false);

    expectedResult = checkParams(paramPatternList.listIterator(), type);

    paramDefinitionList = getParamDefinitions();

    for (TCDefinitionList pdef : paramDefinitionList) {
      defs.addAll(pdef); // All definitions of all parameter lists
    }

    FlatEnvironment local = new FlatCheckedEnvironment(defs, base, scope);
    FlatCheckedEnvironment checked = (FlatCheckedEnvironment) local;
    checked.setStatic(accessSpecifier);
    checked.setEnclosingDefinition(this);
    checked.setFunctional(true);

    defs.typeCheck(local, scope);

    if (base.isVDMPP() && !accessSpecifier.isStatic) {
      local.add(getSelfDefinition());
    }

    if (predef != null) {
      TCBooleanType expected = new TCBooleanType(location);
      TCType b = predef.body.typeCheck(local, null, NameScope.NAMES, expected);

      if (!b.isType(TCBooleanType.class, location)) {
        report(3018, "Precondition returns unexpected type");
        detail2("Actual", b, "Expected", expected);
      }

      TCDefinitionList qualified = predef.body.getQualifiedDefs(local);

      if (!qualified.isEmpty()) {
        local = new FlatEnvironment(qualified, local); // NB Not checked!
      }
    }

    if (postdef != null) {
      TCPattern rp = new TCIdentifierPattern(name.getResultName(location));
      TCDefinitionList rdefs = rp.getDefinitions(expectedResult, NameScope.NAMES);
      FlatCheckedEnvironment post = new FlatCheckedEnvironment(rdefs, local, NameScope.NAMES);

      TCBooleanType expected = new TCBooleanType(location);
      TCType b = postdef.body.typeCheck(post, null, NameScope.NAMES, expected);

      if (!b.isType(TCBooleanType.class, location)) {
        report(3018, "Postcondition returns unexpected type");
        detail2("Actual", b, "Expected", expected);
      }
    }

    // This check returns the type of the function body in the case where
    // all of the curried parameter sets are provided.

    actualResult = body.typeCheck(local, null, scope, expectedResult);

    if (!TypeComparator.compatible(expectedResult, actualResult)) {
      report(3018, "Function returns unexpected type");
      detail2("Actual", actualResult, "Expected", expectedResult);
    }

    if (type.narrowerThan(accessSpecifier)) {
      report(3019, "Function parameter visibility less than function definition");
    }

    if (base.isVDMPP()
        && accessSpecifier.access == Token.PRIVATE
        && body instanceof TCSubclassResponsibilityExpression) {
      report(3329, "Abstract function/operation must be public or protected");
    }

    if (measure == null && recursive) {
      warning(5012, "Recursive function has no measure");
    } else if (measure != null) {
      if (base.isVDMPP()) measure.setTypeQualifier(getMeasureParams());
      measuredef = base.findName(measure, scope);

      if (measuredef == null) {
        measure.report(3270, "Measure " + measure + " is not in scope");
      } else if (!(measuredef instanceof TCExplicitFunctionDefinition)) {
        measure.report(3271, "Measure " + measure + " is not an explicit function");
      } else if (measuredef == this) {
        measure.report(3304, "Recursive function cannot be its own measure");
      } else {
        TCExplicitFunctionDefinition efd = (TCExplicitFunctionDefinition) measuredef;

        if (this.typeParams == null && efd.typeParams != null) {
          measure.report(3309, "Measure must not be polymorphic");
        } else if (this.typeParams != null && efd.typeParams == null) {
          measure.report(3310, "Measure must also be polymorphic");
        } else if (this.typeParams != null
            && efd.typeParams != null
            && !this.typeParams.equals(efd.typeParams)) {
          measure.report(3318, "Measure's type parameters must match function's");
          detail2("Actual", efd.typeParams, "Expected", typeParams);
        }

        TCFunctionType mtype = (TCFunctionType) measuredef.getType();

        if (typeParams != null) // Polymorphic, so compare "shape" of param signature
        {
          if (!mtype.parameters.toString().equals(getMeasureParams().toString())) {
            measure.report(3303, "Measure parameters different to function");
            detail2(measure.getName(), mtype.parameters, "Expected", getMeasureParams());
          }
        } else if (!TypeComparator.compatible(mtype.parameters, getMeasureParams())) {
          measure.report(3303, "Measure parameters different to function");
          detail2(measure.getName(), mtype.parameters, "Expected", getMeasureParams());
        }

        if (!(mtype.result instanceof TCNaturalType)) {
          if (mtype.result.isProduct(location)) {
            TCProductType pt = mtype.result.getProduct();

            for (TCType t : pt.types) {
              if (!(t instanceof TCNaturalType)) {
                measure.report(3272, "Measure range is not a nat, or a nat tuple");
                measure.detail("Actual", mtype.result);
                break;
              }
            }

            measureLexical = pt.types.size();
          } else {
            measure.report(3272, "Measure range is not a nat, or a nat tuple");
            measure.detail("Actual", mtype.result);
          }
        }
      }
    }

    if (!(body instanceof TCNotYetSpecifiedExpression)
        && !(body instanceof TCSubclassResponsibilityExpression)) {
      local.unusedCheck();
    }
  }
 public INRenamedDefinition(TCNameToken name, INDefinition def) {
   super(name.getLocation(), null, name);
   this.def = def;
 }
Beispiel #7
0
 @Override
 public int hashCode() {
   return name.hashCode();
 }