From 862b45fe27fef4239df6da6a9061d0c57cd7f7d6 Mon Sep 17 00:00:00 2001 From: "Emmanouil (Manos) Koukoutos" <emmanouil.koukoutos@epfl.ch> Date: Thu, 4 Sep 2014 17:18:25 +0200 Subject: [PATCH] Print full paths --- .../scala/leon/purescala/PrettyPrinter.scala | 103 ++++++++++++------ .../scala/leon/synthesis/FileInterface.scala | 8 +- .../test/synthesis/StablePrintingSuite.scala | 2 +- 3 files changed, 77 insertions(+), 36 deletions(-) diff --git a/src/main/scala/leon/purescala/PrettyPrinter.scala b/src/main/scala/leon/purescala/PrettyPrinter.scala index e9f3cdf6a..123ab89fe 100644 --- a/src/main/scala/leon/purescala/PrettyPrinter.scala +++ b/src/main/scala/leon/purescala/PrettyPrinter.scala @@ -7,6 +7,7 @@ import Common._ import Trees._ import TypeTrees._ import Definitions._ +import DefOps._ import utils._ @@ -16,6 +17,7 @@ import PrinterHelpers._ case class PrinterContext( current: Tree, parent: Option[Tree], + scope : Option[Definition], lvl: Int, printer: PrettyPrinter ) @@ -66,9 +68,13 @@ object PrinterHelpers { case ts: Seq[Any] => nary(ts).print(nctx) - + case t: Tree => - nctx = nctx.copy(current = t, parent = Some(nctx.current)) + val newScope = nctx.current match { + case d : Definition => Some(d) + case _ => nctx.scope + } + nctx = nctx.copy(current = t, parent = Some(nctx.current), scope = newScope) printer.pp(t)(nctx) case p: Printable => @@ -91,7 +97,7 @@ object PrinterHelpers { def typed(t: Tree with Typed): Printable = { implicit pctx: PrinterContext => - p"$t: ${t.getType}" + p"$t : ${t.getType}" } def typed(ts: Seq[Tree with Typed]): Printable = { @@ -124,10 +130,28 @@ class PrettyPrinter(opts: PrinterOptions, val sb: StringBuffer = new StringBuffe body } } - + + def printWithPath(df: Definition)(implicit ctx : PrinterContext) { + ctx.scope match { + case Some(scope) => + try { + val (pack, defPath) = pathAsVisibleFrom(scope, df) + val toPrint = pack ++ (defPath collect { case df if !df.isInstanceOf[UnitDef] => df.id}) + p"${nary(toPrint, ".")}" + } catch { + // If we did not manage to find the path, just print the id + case _ : NoSuchElementException => p"${df.id}" + } + case None => + p"${df.id}" + } + + } + def pp(tree: Tree)(implicit ctx: PrinterContext): Unit = tree match { - case id: Identifier => + case id: Identifier => + val name = if (opts.printUniqueIds) { id.uniqueName } else { @@ -230,7 +254,7 @@ class PrettyPrinter(opts: PrinterOptions, val sb: StringBuffer = new StringBuffe case e @ Error(err) => p"""error[${e.getType}]("$err")""" case CaseClassInstanceOf(cct, e) => if (cct.classDef.isCaseObject) { - p"($e == ${cct.id})" + p"($e == $cct)" } else { p"$e.isInstanceOf[$cct]" } @@ -245,7 +269,7 @@ class PrettyPrinter(opts: PrinterOptions, val sb: StringBuffer = new StringBuffe if (tfd.fd.isRealFunction) p"($args)" case FunctionInvocation(tfd, args) => - p"${tfd.id}" + printWithPath(tfd.fd) if (tfd.tps.nonEmpty) { p"[${tfd.tps}]" @@ -334,20 +358,19 @@ class PrettyPrinter(opts: PrinterOptions, val sb: StringBuffer = new StringBuffe case CaseClassPattern(ob, cct, subps) => ob.foreach { b => p"$b @ " } - if (cct.classDef.isCaseObject) { - p"${cct.id}" - } else { - p"${cct.id}($subps)" - } + // Print only the classDef because we don't want type parameters in patterns + printWithPath(cct.classDef) + if (!cct.classDef.isCaseObject) p"($subps)" case InstanceOfPattern(ob, cct) => if (cct.classDef.isCaseObject) { ob.foreach { b => p"$b @ " } - p"${cct.id}" } else { ob.foreach { b => p"$b : " } - p"$cct" } + // It's ok to print the whole type because there are no type parameters for case objects + p"$cct" + case TuplePattern(ob, subps) => ob.foreach { b => p"$b @ " } @@ -365,35 +388,47 @@ class PrettyPrinter(opts: PrinterOptions, val sb: StringBuffer = new StringBuffe case TupleType(tpes) => p"($tpes)" case FunctionType(fts, tt) => p"($fts) => $tt" case c: ClassType => - p"${c.classDef.id}" + printWithPath(c.classDef) if (c.tps.nonEmpty) { p"[${c.tps}]" } - // Definitions case Program(id, units) => p"""${nary(units, "\n\n")}""" - - // FIXME : this is not the whole path. - case PackageImport(pack) => - p"${nary(pack,".")}." - - case SingleImport(df) => - p"$df" - - case WildcardImport(df) => - p"$df._" - + case UnitDef(id,modules,pack,imports,isBasic) => if (isBasic) { if (!pack.isEmpty){ - p"package ${pack mkString "."}" + p"""|package ${pack mkString "."} + |""" } p"""|${nary(imports,"\n")} |${nary(modules,"\n\n")} |""" } + + case PackageImport(pack) => + import DefOps._ + val newPack = ( for ( + scope <- ctx.scope; + unit <- inUnit(scope); + currentPack = unit.pack + ) yield { + if (isSuperPackageOf(currentPack,pack)) + pack drop currentPack.length + else + pack + }).getOrElse(pack) + p"import ${nary(newPack,".")}._" + + case SingleImport(df) => + p"import "; printWithPath(df) + + + case WildcardImport(df) => + p"import "; printWithPath(df); p"._" + case ModuleDef(id, defs, _) => p"""|object $id { | ${nary(defs, "\n\n")} @@ -452,7 +487,7 @@ class PrettyPrinter(opts: PrinterOptions, val sb: StringBuffer = new StringBuffe } if (fd.canBeField) { - p"""|${fd.defType} ${fd.id}: ${fd.returnType} = { + p"""|${fd.defType} ${fd.id} : ${fd.returnType} = { |""" } else if (!fd.tparams.isEmpty) { p"""|def ${fd.id}[${nary(fd.tparams, ",")}](${fd.params}): ${fd.returnType} = { @@ -556,9 +591,14 @@ class EquivalencePrettyPrinter(opts: PrinterOptions) extends PrettyPrinter(opts) abstract class PrettyPrinterFactory { def create(opts: PrinterOptions): PrettyPrinter - def apply(tree: Tree, opts: PrinterOptions = PrinterOptions()): String = { + def apply(tree: Tree, opts: PrinterOptions = PrinterOptions(), scope : Option[Definition] = None): String = { val printer = create(opts) - val ctx = PrinterContext(tree, None, opts.baseIndent, printer) + val scope_ = (tree, scope) match { + // Try to find a scope, if we are given none. + case (df : Definition, None) => df.owner + case _ => None + } + val ctx = PrinterContext(tree, None, scope_, opts.baseIndent, printer) printer.pp(tree)(ctx) printer.toString } @@ -567,6 +607,7 @@ abstract class PrettyPrinterFactory { val opts = PrinterOptions.fromContext(ctx) apply(tree, opts) } + } object PrettyPrinter extends PrettyPrinterFactory { diff --git a/src/main/scala/leon/synthesis/FileInterface.scala b/src/main/scala/leon/synthesis/FileInterface.scala index 26d1229f4..cdabf6eb6 100644 --- a/src/main/scala/leon/synthesis/FileInterface.scala +++ b/src/main/scala/leon/synthesis/FileInterface.scala @@ -5,7 +5,7 @@ package synthesis import purescala.Trees._ import purescala.Common.Tree -import purescala.Definitions.FunDef +import purescala.Definitions.{Definition,FunDef} import purescala.ScalaPrinter import purescala.PrinterOptions import purescala.PrinterContext @@ -35,7 +35,7 @@ class FileInterface(reporter: Reporter) { var newCode = origCode for ( (ci, e) <- solutions) { - newCode = substitute(newCode, ci.ch, e) + newCode = substitute(newCode, ci.ch, e, ci.fd ) } val out = new BufferedWriter(new FileWriter(newFile)) @@ -70,10 +70,10 @@ class FileInterface(reporter: Reporter) { } - def substitute(str: String, fromTree: Tree, toTree: Tree): String = { + def substitute(str: String, fromTree: Tree, toTree: Tree, scope : Definition): String = { substitute(str, fromTree, (indent: Int) => { val p = new ScalaPrinter(PrinterOptions()) - p.pp(toTree)(PrinterContext(toTree, None, indent, p)) + p.pp(toTree)(PrinterContext(toTree, None, Some(scope), indent, p)) p.toString }) } diff --git a/src/test/scala/leon/test/synthesis/StablePrintingSuite.scala b/src/test/scala/leon/test/synthesis/StablePrintingSuite.scala index 6b9bf910c..bf0279bea 100644 --- a/src/test/scala/leon/test/synthesis/StablePrintingSuite.scala +++ b/src/test/scala/leon/test/synthesis/StablePrintingSuite.scala @@ -99,7 +99,7 @@ class StablePrintingSuite extends LeonTestSuite { val newContent = new FileInterface(ctx.reporter).substitute(j.content, ci.ch, (indent: Int) => { val p = new ScalaPrinter(PrinterOptions()) - p.pp(result)(PrinterContext(result, Some(ci.fd), indent, p)) + p.pp(result)(PrinterContext(result, Some(ci.fd), Some(ci.fd), indent, p)) p.toString }) -- GitLab