summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHubert Plociniczak <hubert.plociniczak@gmail.com>2012-05-15 09:40:23 +0200
committerHubert Plociniczak <hubert.plociniczak@gmail.com>2012-07-30 10:17:47 +0200
commit0152dbe969520914ce1730c4a81597bc362c9c5b (patch)
tree7142b8f05d68cbe678b03afd669abdd997786b87 /src
parent1ad6e501997d332e2bc0ccc8dd40e3909e728930 (diff)
downloadscala-0152dbe969520914ce1730c4a81597bc362c9c5b.tar.gz
scala-0152dbe969520914ce1730c4a81597bc362c9c5b.tar.bz2
scala-0152dbe969520914ce1730c4a81597bc362c9c5b.zip
Fixed SI-5603. Early definitions now get transparent positions.
This includes a fix for a minor problem described in #594 - ensureNonOverlapping still focuses on default position when outside of early defs. Review by @dragos, @odersky.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala13
-rw-r--r--src/compiler/scala/tools/nsc/interactive/RangePositions.scala48
-rw-r--r--src/reflect/scala/reflect/internal/Positions.scala14
3 files changed, 36 insertions, 39 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 1d29e33c50..9a6d32be01 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -95,11 +95,12 @@ trait Trees extends reflect.internal.Trees { self: Global =>
val (edefs, rest) = body span treeInfo.isEarlyDef
val (evdefs, etdefs) = edefs partition treeInfo.isEarlyValDef
val gvdefs = evdefs map {
- case vdef @ ValDef(_, _, tpt, _) => copyValDef(vdef)(
- // !!! I know "atPos in case" wasn't intentionally planted to
- // add an air of mystery to this file, but it is the sort of
- // comment which only its author could love.
- tpt = atPos(vdef.pos.focus)(TypeTree() setOriginal tpt setPos tpt.pos.focus), // atPos in case
+ case vdef @ ValDef(_, _, tpt, _) =>
+ copyValDef(vdef)(
+ // atPos for the new tpt is necessary, since the original tpt might have no position
+ // (when missing type annotation for ValDef for example), so even though setOriginal modifies the
+ // position of TypeTree, it would still be NoPosition. That's what the author meant.
+ tpt = atPos(vdef.pos.focus)(TypeTree() setOriginal tpt setPos tpt.pos.focus),
rhs = EmptyTree
)
}
@@ -125,7 +126,7 @@ trait Trees extends reflect.internal.Trees { self: Global =>
DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(Constant())))))
}
}
- constrs foreach (ensureNonOverlapping(_, parents ::: gvdefs))
+ constrs foreach (ensureNonOverlapping(_, parents ::: gvdefs, focus=false))
// Field definitions for the class - remove defaults.
val fieldDefs = vparamss.flatten map (vd => copyValDef(vd)(mods = vd.mods &~ DEFAULTPARAM, rhs = EmptyTree))
diff --git a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
index 06828f3a3a..b702d2787c 100644
--- a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
+++ b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
@@ -41,11 +41,11 @@ self: scala.tools.nsc.Global =>
/** 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.
+ * Otherwise returns default position that is either focused or not.
*/
- override def wrappingPos(default: Position, trees: List[Tree]): Position = {
+ override def wrappingPos(default: Position, trees: List[Tree], focus: Boolean): Position = {
val ranged = trees filter (_.pos.isRange)
- if (ranged.isEmpty) default.focus
+ 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)
}
@@ -59,13 +59,25 @@ self: scala.tools.nsc.Global =>
if (headpos.isDefined) wrappingPos(headpos, trees) else headpos
}
-/*
- override def integratePos(tree: Tree, pos: Position) =
- if (pos.isSynthetic && !tree.pos.isSynthetic) tree.syntheticDuplicate
- else tree
-*/
-
// -------------- 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
@@ -106,24 +118,6 @@ self: scala.tools.nsc.Global =>
if (ts.head == t) replacement ::: ts.tail
else ts.head :: replace(ts.tail, t, replacement)
- /** Ensure that given tree has no positions that overlap with
- * any of the positions of `others`. This is done by
- * shortening the range or assigning TransparentPositions
- * to some of the nodes in `tree`.
- */
- override def ensureNonOverlapping(tree: Tree, others: List[Tree]) {
- def isOverlapping(pos: Position) =
- pos.isRange && (others exists (pos overlaps _.pos))
- if (isOverlapping(tree.pos)) {
- val children = tree.children
- children foreach (ensureNonOverlapping(_, others))
- if (tree.pos.isOpaqueRange) {
- val wpos = wrappingPos(tree.pos.focus, children)
- tree setPos (if (isOverlapping(wpos)) tree.pos.makeTransparent else wpos)
- }
- }
- }
-
/** Does given list of trees have mutually non-overlapping positions?
* pre: None of the trees is transparent
*/
diff --git a/src/reflect/scala/reflect/internal/Positions.scala b/src/reflect/scala/reflect/internal/Positions.scala
index 6ae9b40fcb..faa161d6b1 100644
--- a/src/reflect/scala/reflect/internal/Positions.scala
+++ b/src/reflect/scala/reflect/internal/Positions.scala
@@ -10,23 +10,25 @@ trait Positions extends api.Positions { self: SymbolTable =>
/** 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.
+ * Otherwise returns default position that is either focused or not.
*/
- def wrappingPos(default: Position, trees: List[Tree]): Position = default
+ def wrappingPos(default: Position, trees: List[Tree]) = wrappingPos(default, trees, true)
+ def wrappingPos(default: Position, trees: List[Tree], focus: Boolean): Position = default
/** 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 all some the trees are non-synthetic, returns a range position enclosing the non-synthetic trees
+ * 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
/** Ensure that given tree has no positions that overlap with
* any of the positions of `others`. This is done by
- * shortening the range or assigning TransparentPositions
- * to some of the nodes in `tree`.
+ * shortening the range, assigning TransparentPositions
+ * to some of the nodes in `tree` or focusing on the position.
*/
- def ensureNonOverlapping(tree: Tree, others: List[Tree]) {}
+ def ensureNonOverlapping(tree: Tree, others: List[Tree]){ ensureNonOverlapping(tree, others, true) }
+ def ensureNonOverlapping(tree: Tree, others: List[Tree], focus: Boolean) {}
trait PosAssigner extends Traverser {
var pos: Position