diff --git a/src/funcheck/CPComponent.scala b/src/funcheck/CPComponent.scala new file mode 100644 index 0000000000000000000000000000000000000000..175f57b373b072015661f18e0ac95fdb4daa93dd --- /dev/null +++ b/src/funcheck/CPComponent.scala @@ -0,0 +1,48 @@ +package funcheck + +import scala.tools.nsc._ +import scala.tools.nsc.plugins._ + +class CPComponent(val global: Global, val pluginInstance: FunCheckPlugin) + extends PluginComponent + with CodeExtraction + with Serialization + with CallTransformation +{ + import global._ + + // This is how it works from 2.8 on.. + override val runsRightAfter: Option[String] = None + override val runsAfter: List[String] = List("refchecks") + + val phaseName = "constraint-programming" + + /** this is initialized when the Funcheck phase starts*/ + var fresh: scala.tools.nsc.util.FreshNameCreator = null + + def newPhase(prev: Phase) = new CPPhase(prev) + + class CPPhase(prev: Phase) extends StdPhase(prev) { + def apply(unit: CompilationUnit): Unit = { + //global ref to freshName creator + fresh = unit.fresh + + val prog: purescala.Definitions.Program = extractCode(unit) + val fileName = writeProgram(prog) + println("Program extracted and written into: " + fileName) + + transformCalls(unit) + println("Finished transformation") + + /* + try { + val recovered = readProgram(fileName) + println + println("Recovered: " + recovered) + } catch { + case e => e.printStackTrace() + } + */ + } + } +} diff --git a/src/funcheck/CallTransformation.scala b/src/funcheck/CallTransformation.scala new file mode 100644 index 0000000000000000000000000000000000000000..795ae494423b805056c6970808de2ccbade056da --- /dev/null +++ b/src/funcheck/CallTransformation.scala @@ -0,0 +1,38 @@ +package funcheck + +import scala.tools.nsc.transform.TypingTransformers + +trait CallTransformation + extends TypingTransformers + with CodeExtraction +{ + import global._ + + private lazy val funcheckPackage = definitions.getModule("funcheck") + private lazy val cpDefinitionsModule = definitions.getModule("funcheck.CP") + + def transformCalls(unit: CompilationUnit) : Unit = + unit.body = new CallTransformer(unit).transform(unit.body) + + class CallTransformer(unit: CompilationUnit) extends TypingTransformer(unit) { + override def transform(tree: Tree) : Tree = { + tree match { + case a @ Apply(TypeApply(Select(s: Select, n), _), rhs @ List(predicate: Function)) if (cpDefinitionsModule == s.symbol && n.toString == "choose") => { + println("I'm inside a choose call!") + + val Function(funValDefs, funBody) = predicate + + val fd = extractPredicate(unit, funValDefs, funBody) + + println("Here is the extracted FunDef:") + println(fd) + + super.transform(a) + } + + case _ => super.transform(tree) + } + } + } + +} diff --git a/src/funcheck/Serialization.scala b/src/funcheck/Serialization.scala new file mode 100644 index 0000000000000000000000000000000000000000..198b666e0c807666d7fdb5d241e99e3f308b6ad4 --- /dev/null +++ b/src/funcheck/Serialization.scala @@ -0,0 +1,39 @@ +package funcheck + +import java.io.{FileInputStream,FileOutputStream,ObjectInputStream,ObjectOutputStream} +import purescala.Definitions.Program + +trait Serialization { + val fileSuffix = ".serialized" + val dirName = "serialized" + + def programFileName(prog : Program) : String = { + prog.mainObject.id.toString + } + + def writeProgram(prog : Program) : String = { + val directory = new java.io.File(dirName) + directory.mkdir() + + val file = java.io.File.createTempFile(programFileName(prog), fileSuffix, directory) + + val fos = new FileOutputStream(file) + val oos = new ObjectOutputStream(fos) + + oos.writeObject(prog) + oos.flush() + fos.close() + + file.getAbsolutePath() + } + + def readProgram(filename : String) : Program = { + val fis = new FileInputStream(filename) + val ois = new ObjectInputStream(fis) + + val recovered : Program = ois.readObject().asInstanceOf[Program] + fis.close() + + recovered + } +}