diff options
9 files changed, 271 insertions, 311 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index e438ac4bfb..bed446f8cb 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -12,7 +12,6 @@ import scala.collection.{ mutable, immutable } import io.{ SourceReader, AbstractFile, Path } import reporters.{ Reporter, ConsoleReporter } import util.{ ClassPath, MergedClassPath, StatisticsInfo, returning, stackTraceString, stackTraceHeadString } -import scala.reflect.internal.RangePositions import scala.reflect.internal.util.{ OffsetPosition, SourceFile, NoSourceFile, BatchSourceFile, ScriptSourceFile } import scala.reflect.internal.pickling.{ PickleBuffer, PickleFormat } import symtab.{ Flags, SymbolTable, SymbolLoaders, SymbolTrackers } @@ -43,6 +42,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) // the mirror -------------------------------------------------- override def isCompilerUniverse = true + override val useOffsetPositions = !currentSettings.Yrangepos.value class GlobalMirror extends Roots(NoSymbol) { val universe: self.type = self @@ -1695,10 +1695,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) def createJavadoc = false } -class RangePositionGlobal(settings0: Settings, reporter0: Reporter) extends Global(settings0, reporter0) with RangePositions - object Global { - def apply(settings: Settings, reporter: Reporter): Global = - if (settings.Yrangepos.value) new RangePositionGlobal(settings, reporter) - else new Global(settings, reporter) + def apply(settings: Settings, reporter: Reporter): Global = new Global(settings, reporter) } diff --git a/src/compiler/scala/tools/nsc/doc/DocParser.scala b/src/compiler/scala/tools/nsc/doc/DocParser.scala index 104178a832..b753e84426 100644 --- a/src/compiler/scala/tools/nsc/doc/DocParser.scala +++ b/src/compiler/scala/tools/nsc/doc/DocParser.scala @@ -15,7 +15,7 @@ import DocParser.Parsed * right after parsing so it can read `DocDefs` from source code which would * otherwise cause the compiler to go haywire. */ -class DocParser(settings: nsc.Settings, reporter: Reporter) extends RangePositionGlobal(settings, reporter) { +class DocParser(settings: nsc.Settings, reporter: Reporter) extends Global(settings, reporter) { def this(settings: Settings) = this(settings, new ConsoleReporter(settings)) def this() = this(new Settings(Console println _)) diff --git a/src/compiler/scala/tools/nsc/doc/ScaladocGlobal.scala b/src/compiler/scala/tools/nsc/doc/ScaladocGlobal.scala index d4777d7800..b8a0637b47 100644 --- a/src/compiler/scala/tools/nsc/doc/ScaladocGlobal.scala +++ b/src/compiler/scala/tools/nsc/doc/ScaladocGlobal.scala @@ -91,7 +91,9 @@ trait ScaladocAnalyzer extends Analyzer { } } -class ScaladocGlobal(settings: doc.Settings, reporter: Reporter) extends Global(settings, reporter) with interactive.RangePositions { +class ScaladocGlobal(settings: doc.Settings, reporter: Reporter) extends { + override val useOffsetPositions = false +} with Global(settings, reporter) { override protected def computeInternalPhases() { phasesSet += syntaxAnalyzer phasesSet += analyzer.namerFactory diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala index 82eafb4b09..2091c63d8e 100644 --- a/src/compiler/scala/tools/nsc/interactive/Global.scala +++ b/src/compiler/scala/tools/nsc/interactive/Global.scala @@ -11,7 +11,7 @@ import mutable.{LinkedHashMap, SynchronizedMap, HashSet, SynchronizedSet} import scala.util.control.ControlThrowable import scala.tools.nsc.io.{ AbstractFile, LogReplay, Logger, NullLogger, Replayer } import scala.tools.nsc.util.MultiHashMap -import scala.reflect.internal.util.{ SourceFile, BatchSourceFile, Position, RangePosition, NoPosition } +import scala.reflect.internal.util.{ SourceFile, BatchSourceFile, Position, NoPosition } import scala.tools.nsc.reporters._ import scala.tools.nsc.symtab._ import scala.tools.nsc.typechecker.DivergentImplicit @@ -26,9 +26,9 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") * execution of the super constructor. */ private var initializing = true -} with RangePositionGlobal(settings, _reporter) + override val useOffsetPositions = false +} with scala.tools.nsc.Global(settings, _reporter) with CompilerControl - with RangePositions with ContextTrees with RichCompilationUnits with ScratchPadMaker diff --git a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala index 0af62ad729..6288400629 100644 --- a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala +++ b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala @@ -6,8 +6,8 @@ package scala.tools.nsc package interactive -@deprecated("Use scala.reflect.internal.RangePositions", "2.11.0") -trait RangePositions extends scala.reflect.internal.RangePositions with ast.Trees with ast.Positions { +@deprecated("Use scala.reflect.internal.Positions", "2.11.0") +trait RangePositions extends scala.reflect.internal.Positions with ast.Trees with ast.Positions { self: scala.tools.nsc.Global => } diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index 4d1ceb2818..120761de4c 100644 --- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala +++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala @@ -242,10 +242,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends protected def newCompiler(settings: Settings, reporter: Reporter): ReplGlobal = { settings.outputDirs setSingleOutput replOutput.dir settings.exposeEmptyPackage.value = true - if (settings.Yrangepos.value) - new RangePositionGlobal(settings, reporter) with ReplGlobal { override def toString: String = "<global>" } - else - new Global(settings, reporter) with ReplGlobal { override def toString: String = "<global>" } + new Global(settings, reporter) with ReplGlobal { override def toString: String = "<global>" } } /** Parent classloader. Overridable. */ diff --git a/src/reflect/scala/reflect/internal/Positions.scala b/src/reflect/scala/reflect/internal/Positions.scala index 69f6d22538..f5aeec63e1 100644 --- a/src/reflect/scala/reflect/internal/Positions.scala +++ b/src/reflect/scala/reflect/internal/Positions.scala @@ -2,27 +2,59 @@ package scala.reflect package internal import util._ +import scala.collection.mutable.ListBuffer +/** Handling range positions + * atPos, the main method in this trait, will add positions to a tree, + * and will ensure the following properties: + * + * 1. All nodes between the root of the tree and nodes that already have positions + * will be assigned positions. + * 2. No node which already has a position will be assigned a different range; however + * a RangePosition might become a TransparentPosition. + * 3. The position of each assigned node includes the positions of each of its children. + * 4. The positions of all solid descendants of children of an assigned node + * are mutually non-overlapping. + * + * Here, the solid descendant of a node are: + * + * If the node has a TransparentPosition, the solid descendants of all its children + * Otherwise, the singleton consisting of the node itself. + */ trait Positions extends api.Positions { self: SymbolTable => type Position = scala.reflect.internal.util.Position val NoPosition = scala.reflect.internal.util.NoPosition implicit val PositionTag = ClassTag[Position](classOf[Position]) + def inform(msg: String): Unit + + def useOffsetPositions: Boolean = true + /** A position that wraps a set of trees. * The point of the wrapping position is the point of the default position. * If some of the trees are ranges, returns a range position enclosing all ranges * Otherwise returns default position that is either focused or not. */ def wrappingPos(default: Position, trees: List[Tree]): Position = wrappingPos(default, trees, true) - def wrappingPos(default: Position, trees: List[Tree], focus: Boolean): Position = default + def wrappingPos(default: Position, trees: List[Tree], focus: Boolean): Position = { + if (useOffsetPositions) default else { + val ranged = trees filter (_.pos.isRange) + if (ranged.isEmpty) if (focus) default.focus else default + else new RangePosition(default.source, (ranged map (_.pos.start)).min, default.point, (ranged map (_.pos.end)).max) + } + } /** A position that wraps the non-empty set of trees. * The point of the wrapping position is the point of the first trees' position. * If some of the trees are non-synthetic, returns a range position enclosing the non-synthetic trees * Otherwise returns a synthetic offset position to point. */ - def wrappingPos(trees: List[Tree]): Position = trees.head.pos + def wrappingPos(trees: List[Tree]): Position = { + val headpos = trees.head.pos + if (useOffsetPositions || !headpos.isDefined) headpos + else wrappingPos(headpos, trees) + } /** Ensure that given tree has no positions that overlap with * any of the positions of `others`. This is done by @@ -30,10 +62,212 @@ trait Positions extends api.Positions { self: SymbolTable => * to some of the nodes in `tree` or focusing on the position. */ def ensureNonOverlapping(tree: Tree, others: List[Tree]){ ensureNonOverlapping(tree, others, true) } - def ensureNonOverlapping(tree: Tree, others: List[Tree], focus: Boolean) {} + def ensureNonOverlapping(tree: Tree, others: List[Tree], focus: Boolean) { + if (useOffsetPositions) return + + def isOverlapping(pos: Position) = + pos.isRange && (others exists (pos overlaps _.pos)) + + if (isOverlapping(tree.pos)) { + val children = tree.children + children foreach (ensureNonOverlapping(_, others, focus)) + if (tree.pos.isOpaqueRange) { + val wpos = wrappingPos(tree.pos, children, focus) + tree setPos (if (isOverlapping(wpos)) tree.pos.makeTransparent else wpos) + } + } + } + + def rangePos(source: SourceFile, start: Int, point: Int, end: Int): Position = + if (useOffsetPositions) new OffsetPosition(source, point) + else new RangePosition(source, start, point, end) + + def validatePositions(tree: Tree) { + if (useOffsetPositions) return + + def reportTree(prefix : String, tree : Tree) { + val source = if (tree.pos.isDefined) tree.pos.source else "" + inform("== "+prefix+" tree ["+tree.id+"] of type "+tree.productPrefix+" at "+tree.pos.show+source) + inform("") + inform(treeStatus(tree)) + inform("") + } + + def positionError(msg: String)(body : => Unit) { + inform("======= Position error\n" + msg) + body + inform("\nWhile validating #" + tree.id) + inform(treeStatus(tree)) + inform("\nChildren:") + tree.children map (t => " " + treeStatus(t, tree)) foreach inform + inform("=======") + throw new ValidateException(msg) + } + + def validate(tree: Tree, encltree: Tree): Unit = { + + if (!tree.isEmpty && tree.canHaveAttrs) { + if (settings.Yposdebug.value && (settings.verbose.value || settings.Yrangepos.value)) + println("[%10s] %s".format("validate", treeStatus(tree, encltree))) + + if (!tree.pos.isDefined) + positionError("Unpositioned tree #"+tree.id) { + inform("%15s %s".format("unpositioned", treeStatus(tree, encltree))) + inform("%15s %s".format("enclosing", treeStatus(encltree))) + encltree.children foreach (t => inform("%15s %s".format("sibling", treeStatus(t, encltree)))) + } + if (tree.pos.isRange) { + if (!encltree.pos.isRange) + positionError("Synthetic tree ["+encltree.id+"] contains nonsynthetic tree ["+tree.id+"]") { + reportTree("Enclosing", encltree) + reportTree("Enclosed", tree) + } + if (!(encltree.pos includes tree.pos)) + positionError("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 => { + positionError("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) + } + } + } + } + } + for (ct <- tree.children flatMap solidDescendants) validate(ct, tree) + } + } + + if (!isPastTyper) + validate(tree, tree) + } + + def solidDescendants(tree: Tree): List[Tree] = + if (tree.pos.isTransparent) tree.children flatMap solidDescendants + else List(tree) + + /** A free range from `lo` to `hi` */ + private def free(lo: Int, hi: Int): Range = + Range(new RangePosition(null, lo, lo, hi), EmptyTree) + + /** The maximal free range */ + private lazy val maxFree: Range = free(0, Int.MaxValue) + + /** A singleton list of a non-empty range from `lo` to `hi`, or else the empty List */ + private def maybeFree(lo: Int, hi: Int) = + if (lo < hi) List(free(lo, hi)) + else List() + + /** Insert `pos` into ranges `rs` if possible; + * otherwise add conflicting trees to `conflicting`. + */ + private def insert(rs: List[Range], t: Tree, conflicting: ListBuffer[Tree]): List[Range] = rs match { + case List() => + assert(conflicting.nonEmpty) + rs + case r :: rs1 => + assert(!t.pos.isTransparent) + if (r.isFree && (r.pos includes t.pos)) { +// println("subdividing "+r+"/"+t.pos) + maybeFree(t.pos.end, r.pos.end) ::: List(Range(t.pos, t)) ::: maybeFree(r.pos.start, t.pos.start) ::: rs1 + } else { + if (!r.isFree && (r.pos overlaps t.pos)) conflicting += r.tree + r :: insert(rs1, t, conflicting) + } + } + + /** Replace elem `t` of `ts` by `replacement` list. */ + private def replace(ts: List[Tree], t: Tree, replacement: List[Tree]): List[Tree] = + if (ts.head == t) replacement ::: ts.tail + else ts.head :: replace(ts.tail, t, replacement) + + /** Does given list of trees have mutually non-overlapping positions? + * pre: None of the trees is transparent + */ + def findOverlapping(cts: List[Tree]): List[(Tree, Tree)] = { + var ranges = List(maxFree) + for (ct <- cts) { + if (ct.pos.isOpaqueRange) { + val conflicting = new ListBuffer[Tree] + ranges = insert(ranges, ct, conflicting) + if (conflicting.nonEmpty) return conflicting.toList map (t => (t, ct)) + } + } + List() + } + + /** Set position of all children of a node + * @param pos A target position. + * Uses the point of the position as the point of all positions it assigns. + * Uses the start of this position as an Offset position for unpositioed trees + * without children. + * @param trees The children to position. All children must be positionable. + */ + private def setChildrenPos(pos: Position, trees: List[Tree]): Unit = try { + for (tree <- trees) { + if (!tree.isEmpty && tree.canHaveAttrs && tree.pos == NoPosition) { + val children = tree.children + if (children.isEmpty) { + tree setPos pos.focus + } else { + setChildrenPos(pos, children) + tree setPos wrappingPos(pos, children) + } + } + } + } catch { + case ex: Exception => + println("error while set children pos "+pos+" of "+trees) + throw ex + } + + + class ValidateException(msg : String) extends Exception(msg) - def rangePos(source: SourceFile, start: Int, point: Int, end: Int): Position = new OffsetPosition(source, point) - def validatePositions(tree: Tree) {} + + /** A locator for trees with given positions. + * Given a position `pos`, locator.apply returns + * the smallest tree that encloses `pos`. + */ + class Locator(pos: Position) extends Traverser { + var last: Tree = _ + def locateIn(root: Tree): Tree = { + this.last = EmptyTree + traverse(root) + this.last + } + protected def isEligible(t: Tree) = !t.pos.isTransparent + override def traverse(t: Tree) { + t match { + case tt : TypeTree if tt.original != null && (tt.pos includes tt.original.pos) => + traverse(tt.original) + case _ => + if (t.pos includes pos) { + if (isEligible(t)) last = t + super.traverse(t) + } else t match { + case mdef: MemberDef => + traverseTrees(mdef.mods.annotations) + case _ => + } + } + } + } + + case class Range(pos: Position, tree: Tree) { + def isFree = tree == EmptyTree + } + + class TypedLocator(pos: Position) extends Locator(pos) { + override protected def isEligible(t: Tree) = super.isEligible(t) && t.tpe != null + } trait PosAssigner extends Traverser { var pos: Position @@ -62,9 +296,25 @@ trait Positions extends api.Positions { self: SymbolTable => } } + /** Position a tree. + * This means: Set position of a node and position all its unpositioned children. + */ def atPos[T <: Tree](pos: Position)(tree: T): T = { - posAssigner.pos = pos - posAssigner.traverse(tree) - tree + if (useOffsetPositions || !pos.isOpaqueRange) { + posAssigner.pos = pos + posAssigner.traverse(tree) + tree + } + else { + if (!tree.isEmpty && tree.canHaveAttrs && tree.pos == NoPosition) { + tree.setPos(pos) + val children = tree.children + if (children.nonEmpty) { + if (children.tail.isEmpty) atPos(pos)(children.head) + else setChildrenPos(pos, children) + } + } + tree + } } } diff --git a/src/reflect/scala/reflect/internal/RangePositions.scala b/src/reflect/scala/reflect/internal/RangePositions.scala deleted file mode 100644 index 85bbaf3364..0000000000 --- a/src/reflect/scala/reflect/internal/RangePositions.scala +++ /dev/null @@ -1,285 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2009-2013 Typesafe/Scala Solutions and LAMP/EPFL - * @author Martin Odersky - */ - -package scala.reflect -package internal - -import util._ -import scala.collection.mutable.ListBuffer - -/** Handling range positions - * atPos, the main method in this trait, will add positions to a tree, - * and will ensure the following properties: - * - * 1. All nodes between the root of the tree and nodes that already have positions - * will be assigned positions. - * 2. No node which already has a position will be assigned a different range; however - * a RangePosition might become a TransparentPosition. - * 3. The position of each assigned node includes the positions of each of its children. - * 4. The positions of all solid descendants of children of an assigned node - * are mutually non-overlapping. - * - * Here, the solid descendant of a node are: - * - * If the node has a TransparentPosition, the solid descendants of all its children - * Otherwise, the singleton consisting of the node itself. - */ -trait RangePositions extends Trees with Positions { - self: SymbolTable => - - def inform(msg: String): Unit - - case class Range(pos: Position, tree: Tree) { - def isFree = tree == EmptyTree - } - - override def rangePos(source: SourceFile, start: Int, point: Int, end: Int): RangePosition = - new RangePosition(source, start, point, end) - - /** A position that wraps a set of trees. - * The point of the wrapping position is the point of the default position. - * If some of the trees are ranges, returns a range position enclosing all ranges - * Otherwise returns default position that is either focused or not. - */ - override def wrappingPos(default: Position, trees: List[Tree], focus: Boolean): Position = { - val ranged = trees filter (_.pos.isRange) - if (ranged.isEmpty) if (focus) default.focus else default - else new RangePosition(default.source, (ranged map (_.pos.start)).min, default.point, (ranged map (_.pos.end)).max) - } - - /** A position that wraps a non-empty set of trees. - * The point of the wrapping position is the point of the first trees' position. - * If some of the trees are ranges, returns a range position enclosing all ranges - * Otherwise returns first tree's position. - */ - override def wrappingPos(trees: List[Tree]): Position = { - val headpos = trees.head.pos - if (headpos.isDefined) wrappingPos(headpos, trees) else headpos - } - - // -------------- ensuring no overlaps ------------------------------- - - /** Ensure that given tree has no positions that overlap with - * any of the positions of `others`. This is done by - * shortening the range, assigning TransparentPositions - * to some of the nodes in `tree` or focusing on the position. - */ - override def ensureNonOverlapping(tree: Tree, others: List[Tree], focus: Boolean) { - def isOverlapping(pos: Position) = - pos.isRange && (others exists (pos overlaps _.pos)) - if (isOverlapping(tree.pos)) { - val children = tree.children - children foreach (ensureNonOverlapping(_, others, focus)) - if (tree.pos.isOpaqueRange) { - val wpos = wrappingPos(tree.pos, children, focus) - tree setPos (if (isOverlapping(wpos)) tree.pos.makeTransparent else wpos) - } - } - } - - def solidDescendants(tree: Tree): List[Tree] = - if (tree.pos.isTransparent) tree.children flatMap solidDescendants - else List(tree) - - /** A free range from `lo` to `hi` */ - private def free(lo: Int, hi: Int): Range = - Range(new RangePosition(null, lo, lo, hi), EmptyTree) - - /** The maximal free range */ - private lazy val maxFree: Range = free(0, Int.MaxValue) - - /** A singleton list of a non-empty range from `lo` to `hi`, or else the empty List */ - private def maybeFree(lo: Int, hi: Int) = - if (lo < hi) List(free(lo, hi)) - else List() - - /** Insert `pos` into ranges `rs` if possible; - * otherwise add conflicting trees to `conflicting`. - */ - private def insert(rs: List[Range], t: Tree, conflicting: ListBuffer[Tree]): List[Range] = rs match { - case List() => - assert(conflicting.nonEmpty) - rs - case r :: rs1 => - assert(!t.pos.isTransparent) - if (r.isFree && (r.pos includes t.pos)) { -// println("subdividing "+r+"/"+t.pos) - maybeFree(t.pos.end, r.pos.end) ::: List(Range(t.pos, t)) ::: maybeFree(r.pos.start, t.pos.start) ::: rs1 - } else { - if (!r.isFree && (r.pos overlaps t.pos)) conflicting += r.tree - r :: insert(rs1, t, conflicting) - } - } - - /** Replace elem `t` of `ts` by `replacement` list. */ - private def replace(ts: List[Tree], t: Tree, replacement: List[Tree]): List[Tree] = - if (ts.head == t) replacement ::: ts.tail - else ts.head :: replace(ts.tail, t, replacement) - - /** Does given list of trees have mutually non-overlapping positions? - * pre: None of the trees is transparent - */ - def findOverlapping(cts: List[Tree]): List[(Tree, Tree)] = { - var ranges = List(maxFree) - for (ct <- cts) { - if (ct.pos.isOpaqueRange) { - val conflicting = new ListBuffer[Tree] - ranges = insert(ranges, ct, conflicting) - if (conflicting.nonEmpty) return conflicting.toList map (t => (t, ct)) - } - } - List() - } - - // -------------- setting positions ------------------------------- - - /** Set position of all children of a node - * @param pos A target position. - * Uses the point of the position as the point of all positions it assigns. - * Uses the start of this position as an Offset position for unpositioed trees - * without children. - * @param trees The children to position. All children must be positionable. - */ - private def setChildrenPos(pos: Position, trees: List[Tree]): Unit = try { - for (tree <- trees) { - if (!tree.isEmpty && tree.canHaveAttrs && tree.pos == NoPosition) { - val children = tree.children - if (children.isEmpty) { - tree setPos pos.focus - } else { - setChildrenPos(pos, children) - tree setPos wrappingPos(pos, children) - } - } - } - } catch { - case ex: Exception => - println("error while set children pos "+pos+" of "+trees) - throw ex - } - - /** Position a tree. - * This means: Set position of a node and position all its unpositioned children. - */ - override def atPos[T <: Tree](pos: Position)(tree: T): T = { - if (pos.isOpaqueRange) { - if (!tree.isEmpty && tree.canHaveAttrs && tree.pos == NoPosition) { - tree.setPos(pos) - val children = tree.children - if (children.nonEmpty) { - if (children.tail.isEmpty) atPos(pos)(children.head) - else setChildrenPos(pos, children) - } - } - tree - } else { - super.atPos(pos)(tree) - } - } - - // ---------------- Validating positions ---------------------------------- - - override def validatePositions(tree: Tree) { - def reportTree(prefix : String, tree : Tree) { - val source = if (tree.pos.isDefined) tree.pos.source else "" - inform("== "+prefix+" tree ["+tree.id+"] of type "+tree.productPrefix+" at "+tree.pos.show+source) - inform("") - inform(treeStatus(tree)) - inform("") - } - - def positionError(msg: String)(body : => Unit) { - inform("======= Position error\n" + msg) - body - inform("\nWhile validating #" + tree.id) - inform(treeStatus(tree)) - inform("\nChildren:") - tree.children map (t => " " + treeStatus(t, tree)) foreach inform - inform("=======") - throw new ValidateException(msg) - } - - def validate(tree: Tree, encltree: Tree): Unit = { - - if (!tree.isEmpty && tree.canHaveAttrs) { - if (settings.Yposdebug.value && (settings.verbose.value || settings.Yrangepos.value)) - println("[%10s] %s".format("validate", treeStatus(tree, encltree))) - - if (!tree.pos.isDefined) - positionError("Unpositioned tree #"+tree.id) { - inform("%15s %s".format("unpositioned", treeStatus(tree, encltree))) - inform("%15s %s".format("enclosing", treeStatus(encltree))) - encltree.children foreach (t => inform("%15s %s".format("sibling", treeStatus(t, encltree)))) - } - if (tree.pos.isRange) { - if (!encltree.pos.isRange) - positionError("Synthetic tree ["+encltree.id+"] contains nonsynthetic tree ["+tree.id+"]") { - reportTree("Enclosing", encltree) - reportTree("Enclosed", tree) - } - if (!(encltree.pos includes tree.pos)) - positionError("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 => { - positionError("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) - } - } - } - } - } - for (ct <- tree.children flatMap solidDescendants) validate(ct, tree) - } - } - - if (!isPastTyper) - validate(tree, tree) - } - - class ValidateException(msg : String) extends Exception(msg) - - // ---------------- Locating trees ---------------------------------- - - /** A locator for trees with given positions. - * Given a position `pos`, locator.apply returns - * the smallest tree that encloses `pos`. - */ - class Locator(pos: Position) extends Traverser { - var last: Tree = _ - def locateIn(root: Tree): Tree = { - this.last = EmptyTree - traverse(root) - this.last - } - protected def isEligible(t: Tree) = !t.pos.isTransparent - override def traverse(t: Tree) { - t match { - case tt : TypeTree if tt.original != null && (tt.pos includes tt.original.pos) => - traverse(tt.original) - case _ => - if (t.pos includes pos) { - if (isEligible(t)) last = t - super.traverse(t) - } else t match { - case mdef: MemberDef => - traverseTrees(mdef.mods.annotations) - case _ => - } - } - } - } - - class TypedLocator(pos: Position) extends Locator(pos) { - override protected def isEligible(t: Tree) = super.isEligible(t) && t.tpe != null - } -} diff --git a/src/reflect/scala/reflect/runtime/JavaUniverse.scala b/src/reflect/scala/reflect/runtime/JavaUniverse.scala index a12e7d43d4..5467d70cea 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverse.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverse.scala @@ -9,8 +9,8 @@ package runtime */ class JavaUniverse extends internal.SymbolTable with ReflectSetup with runtime.SymbolTable { self => + def inform(msg: String): Unit = log(msg) def picklerPhase = internal.SomePhase - def forInteractive = false def forScaladoc = false lazy val settings = new Settings |