From ac779096c1c2c6e3e1d563855bfc20fb76b04746 Mon Sep 17 00:00:00 2001 From: Miles Sabin Date: Tue, 14 Jul 2009 12:49:35 +0000 Subject: Fixed a couple of position bugs; made validatio... Fixed a couple of position bugs; made validation output a bit more informative and readable. --- src/compiler/scala/tools/nsc/Main.scala | 21 ++++---- .../scala/tools/nsc/ast/parser/Parsers.scala | 3 +- .../scala/tools/nsc/ast/parser/TreeBuilder.scala | 8 +-- .../tools/nsc/interactive/RangePositions.scala | 59 ++++++++++++++-------- 4 files changed, 57 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/Main.scala b/src/compiler/scala/tools/nsc/Main.scala index dcccf8724a..8a26fb2626 100644 --- a/src/compiler/scala/tools/nsc/Main.scala +++ b/src/compiler/scala/tools/nsc/Main.scala @@ -49,18 +49,19 @@ object Main extends AnyRef with EvalLoop { if (command.settings.version.value) reporter.info(null, versionMsg, true) else if (command.settings.Yidedebug.value) { + command.settings.Xprintpos.value = true val compiler = new interactive.Global(command.settings, reporter) import compiler._ - for (file <- command.files) { - val sf = getSourceFile(file) - var cu = unitOf(sf) - val reloaded = new SyncVar[Either[Unit, Throwable]] - askReload(List(sf), reloaded) - reloaded.get.right.toOption match { - case Some(thr) => logError("Failure in presentation compiler", thr) - case _ => - } - cu = unitOf(sf) + + val sfs = command.files.map(getSourceFile(_)) + val reloaded = new SyncVar[Either[Unit, Throwable]] + askReload(sfs, reloaded) + reloaded.get.right.toOption match { + case Some(thr) => logError("Failure in presentation compiler", thr) + case _ => + } + for (sf <- sfs) { + val cu = unitOf(sf) val tree = cu.body treePrinters.create(System.out).print(tree) } diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 8378d4ba8f..abb9f5214c 100755 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -2291,7 +2291,8 @@ self => if (parents.isEmpty) parents = List(scalaAnyRefConstr) if (mods.hasFlag(Flags.CASE)) parents = parents ::: List(productConstr) - atPos(tstart) { + val tstart0 = if (body.isEmpty && in.lastOffset < tstart) in.lastOffset else tstart + atPos(tstart0) { Template(parents, self, constrMods, vparamss, argss, body, o2p(tstart).toSynthetic) } } diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index bef5ed0412..e13b76239b 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -169,9 +169,11 @@ abstract class TreeBuilder { Modifiers(FINAL), x, Nil, Template(parents, self, NoMods, List(Nil), argss, stats, cpos.toSynthetic)) }), - New( - Ident(x) setPos npos.toSynthetic, - List(Nil)) setPos npos + atPos(npos) { + New( + Ident(x) setPos npos.toSynthetic, + List(Nil)) + } ) } } diff --git a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala index 5dbce2418a..00db6de9dd 100755 --- a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala +++ b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala @@ -229,44 +229,63 @@ self: nsc.Global => // ---------------- Validating positions ---------------------------------- override def validatePositions(tree: Tree) { - def error(msg: String) { - inform("**** bad positions:") - inform(msg) - inform("================= in =================") + def reportTree(prefix : String, tree : Tree) { + val source = tree.pos.source match { + case Some(sf) => " in file "+sf + case None => "" + } + + inform("== "+prefix+" tree ["+tree.id+"] of type "+tree.productPrefix+" at "+tree.pos.show+source) + inform("") + inform(tree.toString) + inform("") + } + + def error(msg: String)(body : => Unit) { + inform("======= Bad positions: "+msg) + inform("") + body + inform("=== While validating") + inform("") inform(tree.toString) + inform("") + inform("=======") throw new ValidateError(msg) } - def validate(tree: Tree, encltree: Tree): Unit = try { + + def validate(tree: Tree, encltree: Tree): Unit = { if (!tree.isEmpty) { if (!tree.pos.isDefined) - error("tree without position["+tree.id+"]:"+tree) + error("Unpositioned tree ["+tree.id+"]") { reportTree("Unpositioned", tree) } if (!tree.pos.isSynthetic) { if (encltree.pos.isSynthetic) - error("synthetic "+encltree+" contains nonsynthetic["+tree.id+"] " + tree) + error("Synthetic tree ["+encltree.id+"] contains nonsynthetic tree ["+tree.id+"]") { + reportTree("Enclosing", encltree) + reportTree("Enclosed", tree) + } if (!(encltree.pos includes tree.pos)) - error(encltree+" does not include "+tree) + error("Enclosing tree ["+encltree.id+"] does not include tree ["+tree.id+"]") { + reportTree("Enclosing", encltree) + reportTree("Enclosed", tree) + } + findOverlapping(tree.children flatMap solidDescendants) match { case List() => ; case xs => { - for((x, y) <- xs) { - println("Overlapping tree x: "+x.pos+" "+x.getClass.getName) - println(x) - println("Overlapping tree y: "+y.pos+" "+y.getClass.getName) - println(y) + error("Overlapping trees "+xs.map { case (x, y) => (x.id, y.id) }.mkString("", ", ", "")) { + reportTree("Ancestor", tree) + for((x, y) <- xs) { + reportTree("First overlapping", x) + reportTree("Second overlapping", y) + } } - println("Ancestor: "+tree.getClass.getName) - - error("overlapping trees: "+xs) } } } for (ct <- tree.children flatMap solidDescendants) validate(ct, tree) } - } catch { - case ex: ValidateError => - println("error while validating "+tree) - throw ex } + validate(tree, tree) } -- cgit v1.2.3