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

- Removed paremetric types from class/trait declaration. This was used only...

- Removed paremetric types from class/trait declaration. This was used only for expressing the need of having the variable global (of type Global) in the scope.
- Moved some code from ScalaCheckIntegrator and FilterGeneratorAnnotations to trait ScalaCheck.
parent 8ab5055e
No related branches found
No related tags found
No related merge requests found
......@@ -6,7 +6,7 @@ import scalacheck._
class AnalysisComponent(val global: Global, val pluginInstance: FunCheckPlugin) extends PluginComponent
with CodeExtraction
with ScalaCheckIntegrator[AnalysisComponent]
with ScalaCheckIntegrator
{
import global._
......@@ -47,6 +47,7 @@ class AnalysisComponent(val global: Global, val pluginInstance: FunCheckPlugin)
val (genDef, arbDef) = createGeneratorDefDefs(unit)
injectGenDefDefs(genDef ::: arbDef, unit)
forAllTransform(unit)
// if(pluginInstance.stopAfterAnalysis) {
// println("Analysis complete. Now terminating the compiler process.")
......
package funcheck.scalacheck
import scala.tools.nsc.{Global, SubComponent}
import scala.tools.nsc.Global
/**
* A tree traverser which filter the trees elements that contain the
......@@ -20,7 +20,8 @@ import scala.tools.nsc.{Global, SubComponent}
*
* where <code>unit</code> is the current Compilation Unit.
*/
trait FilterGeneratorAnnotations[T <: SubComponent] { self: T =>
trait FilterGeneratorAnnotations {
val global: Global
// [[INFO]] "hasAttribute" is "hasAnnotation" in future compiler release 2.8
import global._
......
This diff is collapsed.
package funcheck.scalacheck
import scala.tools.nsc.{Global, SubComponent}
import funcheck.util.FreshNameCreator
trait ScalaCheckIntegrator[T <: SubComponent] extends ScalaCheck[T]
with FilterGeneratorAnnotations[T]
trait ScalaCheckIntegrator extends ScalaCheck
with FilterGeneratorAnnotations
with GeneratorDefDefInjector
with FreshNameCreator
with ForAllTransformer
{
self: T =>
val global: Global
import global._
......@@ -27,198 +27,5 @@ trait ScalaCheckIntegrator[T <: SubComponent] extends ScalaCheck[T]
(Gen.createGenDefDef(klasses.toList,defs.toList), Arbitrary.getArbitraryDefDefs)
}
object Gen extends Gen {
/**
* Map that stores for each @generator annotated ClassDef or DefDef the automatically
* generated DefDef for creating instances of the <code>org.scalacheck.Gen</code> class.
* The <code>Type</code> that is associated to the DefDef is either the type of the
* ClassDef or the returning type of the DefDef.
*/
private val tpe2listGen = scala.collection.mutable.Map.empty[Type, List[DefDef]]
private val tpe2listGenSym = scala.collection.mutable.Map.empty[Type, List[Symbol]]
/**
* Add the <code>gen</code> generator DefDef declaration to the list of
* generators for <code>tpe</code>.
*
* @param tpe The type of elements generated by the <code>gen</code>.
* @param gen The DefDef declaration for the generator method.
*/
def +[T](map: collection.mutable.Map[Type, List[T]], key: Type, value: T): Unit = map.get(key) match {
case None => map += key -> List(value)
case Some(values) => map += key -> (value :: values)
}
/** List of generator DefDef symbols for a given type <code>tpe</code>*/
def genSymbolsForType(tpe: Type): List[Symbol] = tpe2listGenSym.get(tpe) match {
case None => Nil
case Some(symbols) => symbols
}
/**
* Second Pass: Create symbols for the generator DefDef that will be created
* durind the Third Pass.
*/
def createGenDefDef(klasses: List[ClassDef], defs: List[DefDef]): List[DefDef] = {
val generable: List[(Symbol,Tree)] = createGenDefSyms(klasses, defs)
for { (genSym, genTree) <- generable } genTree match {
case cd: ClassDef =>
val tpe = cd.symbol.tpe
Gen + (tpe2listGen, tpe, Gen.createGenDef(cd, genSym))
case d: DefDef =>
val tpe = d.tpt.symbol.tpe
val generated = DefDef(genSym, Modifiers(0), List(), rhsGenDef(Ident(d.name))(d)(genSym))
Gen + (tpe2listGen, tpe, generated)
}
// flatten into single list values of Gen.tpe2listGen
(List[DefDef]() /: Gen.tpe2listGen.values) {
case (xs, xss) => xs ::: xss
}
}
/**
* Create method symbols for each <code>@generator</code> annotated ClassDef
* and DefDef.
*/
private def createGenDefSyms(klasses: List[ClassDef], defs: List[DefDef]): List[(Symbol, Tree)] = {
val genKlasses: List[(Symbol, ClassDef)] = for(klass <- klasses) yield {
val genName = fresh.newName("gen"+klass.name)
val tpe = klass.symbol.tpe
val genSym = createGenDefSymbol(klass.symbol.enclClass.owner, genName, tpe)
Gen + (tpe2listGenSym, tpe, genSym)
(genSym, klass)
}
val genDefs: List[(Symbol, DefDef)] = for(d <- defs) yield {
val genName = fresh.newName("gen"+d.name)
val tpe = d.tpt.symbol.tpe
val genSym = createGenDefSymbol(d.symbol.owner, genName, tpe)
Gen + (tpe2listGenSym, tpe, genSym)
(genSym, d)
}
genKlasses ::: genDefs
}
def createGenDef(cd: ClassDef, genDef: Symbol): DefDef = {
val d: DefDef = getConstructorOf(cd)
val DefDef(_,_,_,vparamss,retTpe,_) = d
assert(vparamss.size <= 1, "currying is not supported. Change signature of "+cd.symbol)
if(cd.symbol.hasFlag(scala.tools.nsc.symtab.Flags.ABSTRACT)) {
val generators = retTpe.symbol.children.toList.map(s => genSymbolsForType(s.tpe)).flatMap(v=>v)
DefDef(genDef, Modifiers(0), List(), Gen.oneOf(generators))
}
else {
val constrObj = resetAttrs(d.tpt.duplicate)
val instance = Select(New(constrObj), nme.CONSTRUCTOR)
assert(d.tpt.isInstanceOf[TypeTree])
val body = rhsGenDef(instance)(d)(genDef)
DefDef(genDef, Modifiers(0), List(), body)
}
}
/** <code>base</code> is either
* - Select(New(tpe),constructor) [constructor]
* - Ident(name) [method call]
*/
private def rhsGenDef(base: Tree)(d: DefDef)(extOwner: Symbol): Tree = {
val DefDef(_,name,_,vparamss,retTpe,_) = d
assert(vparamss.size <= 1, "currying is not supported. Change signature of "+d.symbol)
if(vparamss.head.isEmpty)
Gen.value(Apply(base, Nil))
else {
var owner = extOwner
val paramssTpe: List[ValDef] = vparamss.flatMap(v=>v).map(p =>
ValDef(Modifiers(0), fresh.newName("v"), resetAttrs(p.tpt.duplicate), EmptyTree))
var last = true
val z :Tree = Apply(base, paramssTpe.map(p => Ident(p.name)))
val body = (paramssTpe :\ z) {
case (param,apply) => {
val body = Function(List(param), apply)
body.symbol.owner = owner
owner = body.symbol
//XXX: it is not flatMap in general. fix this!!
if(last) {
last = false
Gen.map(Arbitrary.arbitrary(param.tpt.asInstanceOf[TypeTree]), body)
} else
Gen.flatMap(Arbitrary.arbitrary(param.tpt.asInstanceOf[TypeTree]), body)
}
}
body
}
}
private def getConstructorOf(cd: ClassDef): DefDef = {
val Template(parents, self, body) = cd.impl
var dd: DefDef = null
for { b <- body } b match {
case d @ DefDef(_, nme.CONSTRUCTOR, _, _, _, _) => dd = d
case _ => ;
}
dd
} ensuring (res => res != null)
}
object Arbitrary extends Arbitrary {
/** Map that stores not built-in <code>org.scalacheck.Arbitrary</code> DefDef definitions. */
private val tpe2arbDefDef = scala.collection.mutable.Map.empty[Type,DefDef]
def getArbitraryDefDefs: List[DefDef] = tpe2arbDefDef.values.toList
override protected def arbitrary(tpeSym: Symbol): Apply = {
require(tpe2arbApp.get(tpeSym.tpe).isEmpty, "Arbitrary.arbitrary["+tpeSym.tpe+"] is already in the map")
val owner = tpeSym.toplevelClass
val arbName = fresh.newName("arb"+tpeSym.name)
val tpe = tpeSym.tpe
val arbDef = createArbitraryDefSymbol(owner, arbName, tpe)
val genNames = Gen.genSymbolsForType(tpe)
val generated = DefDef(arbDef, Modifiers(0), List(), Arbitrary(Gen.oneOf(genNames)))
tpe2arbDefDef += tpe -> generated
val result = applyArbitrary(Ident(arbDef))
tpe2arbApp += tpe -> result
result
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment