Skip to content

Commit cd2f99c

Browse files
committed
Factored out Positioned into separate file.
1 parent 02f329c commit cd2f99c

File tree

4 files changed

+136
-131
lines changed

4 files changed

+136
-131
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package dotty.tools.dotc
2+
package ast
3+
4+
import util.Positions._
5+
import util.DotClass
6+
7+
/** A base class for things that have positions (currently: modifiers and trees)
8+
*/
9+
abstract class Positioned extends DotClass with Product {
10+
11+
private[this] var curPos: Position = _
12+
13+
setPos(initialPos)
14+
15+
/** The item's position.
16+
*/
17+
def pos: Position = curPos
18+
19+
/** Destructively update `curPos` to given position. Also, set any missing
20+
* positions in children.
21+
*/
22+
protected def setPos(pos: Position): Unit = {
23+
curPos = pos
24+
if (pos.exists) setChildPositions(pos.toSynthetic)
25+
}
26+
27+
/** The envelope containing the item in its entirety. Envelope is different from
28+
* `pos` for definitions (instances of MemberDef).
29+
*/
30+
def envelope: Position = pos.toSynthetic
31+
32+
/** A positioned item like this one with the position set to `pos`.
33+
* if the positioned item is source-derived, a clone is returned.
34+
* If the positioned item is synthetic, the position is updated
35+
* destructively and the item itself is returned.
36+
*/
37+
def withPos(pos: Position): this.type = {
38+
val newpd = (if (pos == curPos || curPos.isSynthetic) this else clone).asInstanceOf[Positioned]
39+
newpd.setPos(pos)
40+
newpd.asInstanceOf[this.type]
41+
}
42+
43+
def withPos(posd: Positioned): this.type =
44+
if (posd == null) this else withPos(posd.pos)
45+
46+
/** This item with a position that's the union of the given `pos` and the
47+
* current position.
48+
*/
49+
def addPos(pos: Position): this.type = withPos(pos union this.pos)
50+
51+
/** If any children of this node do not have positions, set them to the given position,
52+
* and transitively visit their children.
53+
*/
54+
private def setChildPositions(pos: Position): Unit = {
55+
def deepSetPos(x: Any): Unit = x match {
56+
case p: Positioned =>
57+
if (!p.pos.exists) p.setPos(pos)
58+
case xs: List[_] =>
59+
xs foreach deepSetPos
60+
case _ =>
61+
}
62+
var n = productArity
63+
while (n > 0) {
64+
n -= 1
65+
deepSetPos(productElement(n))
66+
}
67+
}
68+
69+
/** The initial, synthetic position. This is usually the union of all positioned children's
70+
* envelopes.
71+
*/
72+
protected def initialPos: Position = {
73+
var n = productArity
74+
var pos = NoPosition
75+
while (n > 0) {
76+
n -= 1
77+
productElement(n) match {
78+
case p: Positioned => pos = pos union p.envelope
79+
case xs: List[_] => pos = unionPos(pos, xs)
80+
case _ =>
81+
}
82+
}
83+
pos.toSynthetic
84+
}
85+
86+
private def unionPos(pos: Position, xs: List[_]): Position = xs match {
87+
case (p: Positioned) :: xs1 => unionPos(pos union p.envelope, xs1)
88+
case _ => pos
89+
}
90+
91+
def contains(that: Positioned): Boolean = {
92+
def isParent(x: Any): Boolean = x match {
93+
case x: Positioned =>
94+
x contains that
95+
case xs: List[_] =>
96+
xs exists isParent
97+
case _ =>
98+
false
99+
}
100+
(this eq that) ||
101+
(this.envelope contains that.pos) && {
102+
var n = productArity
103+
var found = false
104+
while (n > 0 && !found) {
105+
n -= 1
106+
found = isParent(productElement(n))
107+
}
108+
found
109+
}
110+
}
111+
112+
/** The path from this node to `that` node, represented
113+
* as a list starting with `this`, ending with`that` where
114+
* every node is a child of its predecessor.
115+
* Nil if no such path exists.
116+
*/
117+
def pathTo(that: Positioned): List[Positioned] = {
118+
def childPath(it: Iterator[Any]): List[Positioned] =
119+
if (it.hasNext) {
120+
val cpath = it.next match {
121+
case x: Positioned => x.pathTo(that)
122+
case xs: List[_] => childPath(xs.iterator)
123+
case _ => Nil
124+
}
125+
if (cpath.nonEmpty) cpath else childPath(it)
126+
} else Nil
127+
if (this eq that) this :: Nil
128+
else if (this.envelope contains that.pos) {
129+
val cpath = childPath(productIterator)
130+
if (cpath.nonEmpty) this :: cpath else Nil
131+
} else Nil
132+
}
133+
}

src/dotty/tools/dotc/ast/Trees.scala

Lines changed: 1 addition & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -28,135 +28,6 @@ object Trees {
2828
/** The total number of created tree nodes, maintained if Stats.enabled */
2929
var ntrees = 0
3030

31-
/** A base class for things that have positions (currently: modifiers and trees)
32-
*/
33-
abstract class Positioned extends DotClass with Product {
34-
35-
private[this] var curPos: Position = _
36-
37-
setPos(initialPos)
38-
39-
/** The item's position.
40-
*/
41-
def pos: Position = curPos
42-
43-
/** Destructively update `curPos` to given position. Also, set any missing
44-
* positions in children.
45-
*/
46-
protected def setPos(pos: Position): Unit = {
47-
curPos = pos
48-
if (pos.exists) setChildPositions(pos.toSynthetic)
49-
}
50-
51-
/** The envelope containing the item in its entirety. Envelope is different from
52-
* `pos` for definitions (instances of MemberDef).
53-
*/
54-
def envelope: Position = pos.toSynthetic
55-
56-
/** A positioned item like this one with the position set to `pos`.
57-
* if the positioned item is source-derived, a clone is returned.
58-
* If the positioned item is synthetic, the position is updated
59-
* destructively and the item itself is returned.
60-
*/
61-
def withPos(pos: Position): this.type = {
62-
val newpd = (if (pos == curPos || curPos.isSynthetic) this else clone).asInstanceOf[Positioned]
63-
newpd.setPos(pos)
64-
newpd.asInstanceOf[this.type]
65-
}
66-
67-
def withPos(posd: Positioned): this.type =
68-
if (posd == null) this else withPos(posd.pos)
69-
70-
/** This item with a position that's the union of the given `pos` and the
71-
* current position.
72-
*/
73-
def addPos(pos: Position): this.type = withPos(pos union this.pos)
74-
75-
/** If any children of this node do not have positions, set them to the given position,
76-
* and transitively visit their children.
77-
*/
78-
private def setChildPositions(pos: Position): Unit = {
79-
def deepSetPos(x: Any): Unit = x match {
80-
case p: Positioned =>
81-
if (!p.pos.exists) p.setPos(pos)
82-
case xs: List[_] =>
83-
xs foreach deepSetPos
84-
case _ =>
85-
}
86-
var n = productArity
87-
while (n > 0) {
88-
n -= 1
89-
deepSetPos(productElement(n))
90-
}
91-
}
92-
93-
/** The initial, synthetic position. This is usually the union of all positioned children's
94-
* envelopes.
95-
*/
96-
protected def initialPos: Position = {
97-
var n = productArity
98-
var pos = NoPosition
99-
while (n > 0) {
100-
n -= 1
101-
productElement(n) match {
102-
case p: Positioned => pos = pos union p.envelope
103-
case xs: List[_] => pos = unionPos(pos, xs)
104-
case _ =>
105-
}
106-
}
107-
pos.toSynthetic
108-
}
109-
110-
private def unionPos(pos: Position, xs: List[_]): Position = xs match {
111-
case (t: Tree[_]) :: xs1 => unionPos(pos union t.envelope, xs1)
112-
case _ => pos
113-
}
114-
115-
def contains(that: Positioned): Boolean = {
116-
def isParent(x: Any): Boolean = x match {
117-
case x: Positioned =>
118-
x contains that
119-
case xs: List[_] =>
120-
xs exists isParent
121-
case _ =>
122-
false
123-
}
124-
(this eq that) ||
125-
(this.envelope contains that.pos) && {
126-
var n = productArity
127-
var found = false
128-
while (n > 0 && !found) {
129-
n -= 1
130-
found = isParent(productElement(n))
131-
}
132-
found
133-
}
134-
}
135-
136-
/** The path from this node to `that` node, represented
137-
* as a list starting with `this`, ending with`that` where
138-
* every node is a child of its predecessor.
139-
* Nil if no such path exists.
140-
*/
141-
def pathTo(that: Positioned): List[Positioned] = {
142-
def childPath(it: Iterator[Any]): List[Positioned] =
143-
if (it.hasNext) {
144-
val cpath = it.next match {
145-
case x: Positioned => x.pathTo(that)
146-
case xs: List[_] => childPath(xs.iterator)
147-
case _ => Nil
148-
}
149-
if (cpath.nonEmpty) cpath else childPath(it)
150-
} else Nil
151-
if (this eq that) this :: Nil
152-
else if (this.envelope contains that.pos) {
153-
val cpath = childPath(productIterator)
154-
if (cpath.nonEmpty) this :: cpath else Nil
155-
}
156-
else Nil
157-
}
158-
}
159-
16031
/** Modifiers and annotations for definitions
16132
* @param flags The set flags
16233
* @param privateWithin If a private or protected has is followed by a
@@ -204,7 +75,7 @@ object Trees {
20475
def tokenPos: Seq[(Token, Position)] = ???
20576
}
20677

207-
private var nextId = 0
78+
private var nextId = 0 // for debugging
20879

20980
/** Trees take a parameter indicating what the type of their `tpe` field
21081
* is. Two choices: `Type` or `Untyped`.

src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import core._
1212
import Flags._
1313
import Contexts._
1414
import Names._
15+
import ast.Positioned
1516
import ast.Trees._
1617
import Decorators._
1718
import StdNames._

src/dotty/tools/dotc/printing/PlainPrinter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import core._
55
import Texts._, Types._, Flags._, Names._, Symbols._, NameOps._, Constants._, Denotations._
66
import Contexts.Context, Scopes.Scope, Denotations.Denotation, Annotations.Annotation
77
import StdNames.nme
8-
import ast.Trees._, ast.untpd
8+
import ast.Trees._, ast._
99
import java.lang.Integer.toOctalString
1010
import config.Config.summarizeDepth
1111
import scala.annotation.switch

0 commit comments

Comments
 (0)