diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/Trees.scala | 13 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/interactive/RangePositions.scala | 48 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Positions.scala | 14 |
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 |