Skip to content
Snippets Groups Projects
Commit a50cf05c authored by Mirco Dotta's avatar Mirco Dotta
Browse files

Fixed bug for handling any arbitrary number of input parameters.

parent 921788db
No related branches found
No related tags found
No related merge requests found
......@@ -33,101 +33,98 @@ trait ForAllTransformer extends TypingTransformers
// println(lhs.symbol + " and "+lhs.symbol.tpe)
// tree
case Apply(TypeApply(s: Select, partpes), rhs @ List(f @ Function(vparams,body))) if isForall(s) =>
case Apply(TypeApply(s: Select, _), rhs @ List(f @ Function(vparams,body))) if isForall(s) =>
atOwner(currentOwner) {
assert(vparams.size == 1, "funcheck.Specs.forAll properties are expected to take a single (tuple) parameter")
val v @ ValDef(mods,name,vtpt,vinit) = vparams.head
partpes.head.tpe match {
case tpe @ TypeRef(_,_,ptpes) =>
vtpt.tpe match {
case TypeRef(_,value,vtpes) =>
var fun: Function = {
if(vtpes.size <= 1) {
f
} else {
vtpt.tpe match {
case tpe @ TypeRef(_,value,vtpes) =>
var fun: Function = {
if(vtpes.size <= 1) {
f
} else {
// create a fresh name for each parameter declared parametric type
val freshNames = vtpes.map(i => fresh.newName("v"))
// create a fresh name for each parameter declared parametric type
val freshNames = vtpes.map(i => fresh.newName("v"))
val funSym = tree.symbol
val funSym = tree.symbol
val subst = for { i <- 0 to vtpes.size-1} yield {
val toSym = funSym.newValueParameter(funSym.pos, freshNames(i)).setInfo(vtpes(i))
val subst = for { i <- 0 to vtpes.size-1} yield {
val toSym = funSym.newValueParameter(funSym.pos, freshNames(i)).setInfo(vtpes(i))
val from = Select(v, v.symbol.tpe.decl("_"+(i+1)))
val to = ValDef(toSym, EmptyTree) setPos (tree.pos)
val from = Select(v, v.symbol.tpe.decl("_"+(i+1)))
val to = ValDef(toSym, EmptyTree) setPos (tree.pos)
(from, to)
}
(from, to)
}
val valdefs = subst.map(_._2).toList
val fun = localTyper.typed {
val newBody = new MyTreeSubstituter(subst.map(p => p._1.symbol).toList, valdefs.map(v => Ident(v.symbol)).toList).transform(resetAttrs(body))
Function(valdefs, newBody)
}.asInstanceOf[Function]
val valdefs = subst.map(_._2).toList
val fun = localTyper.typed {
val newBody = new MyTreeSubstituter(subst.map(p => p._1.symbol).toList, valdefs.map(v => Ident(v.symbol)).toList).transform(resetAttrs(body))
Function(valdefs, newBody)
}.asInstanceOf[Function]
new ChangeOwnerTraverser(funSym, fun.symbol).traverse(fun);
new ForeachTreeTraverser({t: Tree => t setPos tree.pos}).traverse(fun)
fun
}
}
new ChangeOwnerTraverser(funSym, fun.symbol).traverse(fun);
new ForeachTreeTraverser({t: Tree => t setPos tree.pos}).traverse(fun)
fun
}
}
val prop = Prop.forAll(List(fun))
val prop = Prop.forAll(List(fun))
var buf = new collection.mutable.ListBuffer[Tree]()
var buf = new collection.mutable.ListBuffer[Tree]()
val blockValSym = newSyntheticValueParam(fun.symbol, definitions.BooleanClass.typeConstructor)
val blockValSym = newSyntheticValueParam(fun.symbol, definitions.BooleanClass.typeConstructor)
val fun2 = localTyper.typed {
val body = Prop.propBoolean(resetAttrs(Ident(blockValSym)))
Function(List(ValDef(blockValSym, EmptyTree)), body)
}.asInstanceOf[Function]
val fun2 = localTyper.typed {
val body = Prop.propBoolean(resetAttrs(Ident(blockValSym)))
Function(List(ValDef(blockValSym, EmptyTree)), body)
}.asInstanceOf[Function]
new ChangeOwnerTraverser(fun.symbol, fun2.symbol).traverse(fun2);
new ForeachTreeTraverser({t: Tree => t setPos tree.pos}).traverse(fun2)
new ChangeOwnerTraverser(fun.symbol, fun2.symbol).traverse(fun2);
new ForeachTreeTraverser({t: Tree => t setPos tree.pos}).traverse(fun2)
buf += Block(Nil,fun2)
if(vtpes.isEmpty) {
buf += resetAttrs(Arbitrary.arbitrary(value.tpe))
buf += resetAttrs(Shrink.shrinker(value.tpe))
} else {
for {tpe <- vtpes} {
buf += resetAttrs(Arbitrary.arbitrary(tpe))
buf += resetAttrs(Shrink.shrinker(tpe))
}
}
buf += Block(Nil,fun2)
if(vtpes.size <= 1) {
buf += resetAttrs(Arbitrary.arbitrary(tpe))
buf += resetAttrs(Shrink.shrinker(tpe))
} else {
for { tpe <- vtpes } {
buf += resetAttrs(Arbitrary.arbitrary(tpe))
buf += resetAttrs(Shrink.shrinker(tpe))
}
}
import posAssigner.atPos // for filling in tree positions
import posAssigner.atPos // for filling in tree positions
val property = localTyper.typed {
atPos(tree.pos) {
Apply(prop, buf.toList)
}
}
val property = localTyper.typed {
atPos(tree.pos) {
Apply(prop, buf.toList)
}
}
localTyper.typed {
atPos(tree.pos) {
ConsoleReporter.testStatsEx(Test.check(property))
}
}
case t =>
assert(false, "expected ValDef of type TypeRef, found "+t)
tree
localTyper.typed {
atPos(tree.pos) {
ConsoleReporter.testStatsEx(Test.check(property))
}
case t => tree
}
}
case t =>
assert(false, "expected ValDef of type TypeRef, found "+t)
tree
}
}
/** Delegates the recursive traversal of the tree. */
case _ => super.transform(tree)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment