summaryrefslogtreecommitdiff
path: root/Source/Dafny/RefinementTransformer.cs
diff options
context:
space:
mode:
authorGravatar Rustan Leino <leino@microsoft.com>2012-10-22 01:30:55 -0700
committerGravatar Rustan Leino <leino@microsoft.com>2012-10-22 01:30:55 -0700
commitaba7928452a9043ab1cc6f4fd2e0dda4e2273508 (patch)
tree501b905b63f7e369112dfd702d915cbfe067893c /Source/Dafny/RefinementTransformer.cs
parent066cd4f2a054dd9acfa917ab0d89eed7d9b36d92 (diff)
allow a refinement to introduce "return" statements, at the price of re-verifying the postcondition at that time
let refined classes inherit attributes
Diffstat (limited to 'Source/Dafny/RefinementTransformer.cs')
-rw-r--r--Source/Dafny/RefinementTransformer.cs19
1 files changed, 13 insertions, 6 deletions
diff --git a/Source/Dafny/RefinementTransformer.cs b/Source/Dafny/RefinementTransformer.cs
index 91f79a23..46cf156f 100644
--- a/Source/Dafny/RefinementTransformer.cs
+++ b/Source/Dafny/RefinementTransformer.cs
@@ -606,6 +606,8 @@ namespace Microsoft.Dafny
ClassDecl MergeClass(ClassDecl nw, ClassDecl prev) {
CheckAgreement_TypeParameters(nw.tok, prev.TypeArgs, nw.TypeArgs, nw.Name, "class");
+ nw.Attributes = refinementCloner.MergeAttributes(prev.Attributes, nw.Attributes);
+
// Create a simple name-to-member dictionary. Ignore any duplicates at this time.
var declaredNames = new Dictionary<string, int>();
for (int i = 0; i < nw.Members.Count; i++) {
@@ -619,7 +621,9 @@ namespace Microsoft.Dafny
foreach (var member in prev.Members) {
int index;
if (!declaredNames.TryGetValue(member.Name, out index)) {
- nw.Members.Add(refinementCloner.CloneMember(member));
+ var nwMember = refinementCloner.CloneMember(member);
+ nwMember.RefinementBase = member;
+ nw.Members.Add(nwMember);
} else {
var nwMember = nw.Members[index];
if (nwMember is Field) {
@@ -678,9 +682,9 @@ namespace Microsoft.Dafny
} else if (f.Body != null) {
reporter.Error(nwMember, "a refining function is not allowed to extend/change the body");
}
- var newFn = CloneFunction(f.tok, prevFunction, f.IsGhost, f.Ens, moreBody, replacementBody, prevFunction.Body == null, f.Attributes);
- newFn.RefinementBase = member;
- nw.Members[index] = newFn;
+ var newF = CloneFunction(f.tok, prevFunction, f.IsGhost, f.Ens, moreBody, replacementBody, prevFunction.Body == null, f.Attributes);
+ newF.RefinementBase = member;
+ nw.Members[index] = newF;
}
} else {
@@ -1285,8 +1289,11 @@ namespace Microsoft.Dafny
}
if (s is SkeletonStatement) {
reporter.Error(s, "skeleton statement may not be used here; it does not have a matching statement in what is being replaced");
- } else if (s is ProduceStmt) {
- reporter.Error(s, (s is YieldStmt ? "yield" : "return") + " statements are not allowed in skeletons");
+ } else if (s is ReturnStmt) {
+ // allow return statements, but make note of that this requires verifying the postcondition
+ ((ReturnStmt)s).ReverifyPost = true;
+ } else if (s is YieldStmt) {
+ reporter.Error(s, "yield statements are not allowed in skeletons");
} else if (s is BreakStmt) {
var b = (BreakStmt)s;
if (b.TargetLabel != null ? !labels.Contains(b.TargetLabel) : loopLevels < b.BreakCount) {