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; }
@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; }
@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; }
@Override public int hashCode() { return name.hashCode(); }