@@ -6,12 +6,16 @@ import Contexts._, Types._, Symbols._, TypeApplications._, Decorators._
6
6
import util .Positions ._
7
7
import ast ._
8
8
import Trees ._ , Names ._ , StdNames ._
9
+ import collection .mutable
10
+ import Annotations .Annotation
9
11
10
12
object TypePositions {
11
13
import tpd ._
12
14
13
15
/** Encapsulates a type and the position of a corresponding tree */
14
- case class Positioned (tp : Type , pos : Position ) extends UncachedGroundType
16
+ case class PosAnnot (pos : Position ) extends Annotation {
17
+ def tree (implicit ctx : Context ) = EmptyTree
18
+ }
15
19
16
20
/** An object to handle the point positions of definitions */
17
21
private object PointPos {
@@ -20,10 +24,10 @@ object TypePositions {
20
24
* the position.
21
25
*/
22
26
def add (tree : Tree , tpe : Type ) = tpe match {
23
- case Positioned (tpe1, pos) if ! tree.pos.isSynthetic =>
27
+ case AnnotatedType (tpe1, PosAnnot ( pos)) if ! tree.pos.isSynthetic && false =>
24
28
val pointDelta = pos.start - tree.pos.point
25
- assert(pointDelta > 0 )
26
- Positioned (tpe1, pos.withPoint(pos.start + pointDelta))
29
+ assert(pointDelta >= 0 , s " $pos / ${tree.pos} / $tpe " )
30
+ AnnotatedType (tpe1, PosAnnot ( pos.withPoint(pos.start + pointDelta) ))
27
31
case _ => tpe
28
32
}
29
33
@@ -43,35 +47,37 @@ object TypePositions {
43
47
def unapply [T ](xs : List [T ]) =
44
48
if (xs.isEmpty) None else Some ((xs.init, xs.last))
45
49
}
46
-
50
+
51
+ private def stripPos (tpe : Type ) = tpe match {
52
+ case AnnotatedType (tpe1, _ : PosAnnot ) => tpe1
53
+ case _ => tpe
54
+ }
55
+
47
56
/** Given a type tree, produce the corresponding type with positions added */
48
57
def toType (tree : Tree )(implicit ctx : Context ): Type = {
49
58
50
- def stripPos (tpe : Type ) = tpe match {
51
- case Positioned (tpe1, _) => tpe1
52
- case _ => tpe
53
- }
54
-
55
59
def convertList (trees : List [Tree ], tpes : List [Type ]): List [Type ] =
56
60
tpes.zipWithConserve(trees)((tpe, tree) => convert(tree, tpe))
57
61
58
62
def convert (tree : Tree , tpe : Type ): Type = {
59
- val tpe1 = (tree, tpe) match {
63
+ val tpe1 : Type = (tree, tpe.stripTypeVar ) match {
60
64
case (Select (qual, name), tpe : NamedType ) if tpe.name == name =>
61
65
tpe.derivedSelect(convert(qual, tpe.prefix))
62
- case (SingletonTypeTree (ref), _ ) =>
66
+ case (SingletonTypeTree (ref), tpe ) =>
63
67
convert(ref, tpe)
64
68
case (AndTypeTree (ltree, rtree), tpe @ AndType (ltpe, rtpe)) =>
65
69
tpe.derivedAndType(convert(ltree, ltpe), convert(rtree, rtpe))
66
70
case (OrTypeTree (ltree, rtree), tpe @ OrType (ltpe, rtpe)) =>
67
71
tpe.derivedOrType(convert(ltree, ltpe), convert(rtree, rtpe))
72
+ case (rtree : RefinedTypeTree , tpe : RecType ) =>
73
+ tpe.derivedRecType(convert(rtree, tpe.parent))
68
74
case (RefinedTypeTree (ptree, Append (refinements, refinement : MemberDef )),
69
75
tpe @ RefinedType (ptpe, rname, rinfo)) if rname == refinement.name =>
70
76
val parent =
71
77
if (refinements.isEmpty) ptree
72
78
else cpy.RefinedTypeTree (tree)(ptree, refinements).withPos(NoPosition )
73
79
tpe.derivedRefinedType(convert(parent, ptpe), rname, convert(refinement, rinfo))
74
- case (AppliedTypeTree (ftree, argtrees), AppliedType (ftpe, argtpes)) =>
80
+ case (AppliedTypeTree (ftree, argtrees), AppliedType (ftpe, argtpes)) if argtrees.length == argtpes.length =>
75
81
val ftpe1 = convert(ftree, ftpe)
76
82
val argtpes1 = convertList(argtrees, argtpes)
77
83
if ((ftpe1 eq ftpe) && (argtpes1 eq argtpes)) tpe
@@ -89,11 +95,15 @@ object TypePositions {
89
95
tpe.paramNames,
90
96
convertList(tparams, tpe.paramBounds).map(t => stripPos(t).bounds),
91
97
convert(body, tpe.resultType))
92
- case (TypeDef (name, rhs), _) =>
98
+ case (TypeDef (name, rhs), tpe @ TypeAlias (alias)) =>
99
+ PointPos .add(tree, tpe.derivedTypeAlias(convert(rhs, alias)))
100
+ case (TypeDef (name, rhs), tpe) =>
93
101
PointPos .add(tree, convert(rhs, tpe))
94
- case (ValDef (name, tpt, _), _ ) =>
102
+ case (ValDef (name, tpt, _), tpe ) =>
95
103
PointPos .add(tree, convert(tpt, tpe))
96
- case (DefDef (name, Nil , Nil , tpt, _), _) =>
104
+ case (DefDef (name, Nil , Nil , tpt, _), tpe @ ExprType (rtpe)) =>
105
+ PointPos .add(tree, tpe.derivedExprType(convert(tpt, rtpe)))
106
+ case (DefDef (name, Nil , Nil , tpt, _), tpe) =>
97
107
PointPos .add(tree, convert(tpt, tpe))
98
108
case (tree @ DefDef (name, Nil , vparams :: vparamss1, tpt, _), tpe : MethodType ) =>
99
109
PointPos .add(tree,
@@ -107,12 +117,12 @@ object TypePositions {
107
117
tpe.paramNames,
108
118
convertList(tparams, tpe.paramBounds).map(t => stripPos(t).bounds),
109
119
convert(cpy.DefDef (tree)(tparams = Nil ).withPos(NoPosition ), tpe.resultType)))
110
- case _ =>
120
+ case (_, tpe) =>
111
121
tpe
112
122
}
113
123
tpe1 match {
114
- case tpe1 : Positioned => tpe1
115
- case _ => if (tree.pos.exists) Positioned (tpe1, tree.pos) else tpe1
124
+ case AnnotatedType (_, _ : PosAnnot ) => tpe1
125
+ case _ => if (! tree.pos.isSynthetic) AnnotatedType (tpe1, PosAnnot ( tree.pos) ) else tpe1
116
126
}
117
127
}
118
128
convert(tree, tree.tpe)
@@ -124,18 +134,18 @@ object TypePositions {
124
134
def typeTree = toTree(tpe)
125
135
def untpdDef (tpe : Type ): untpd.MemberDef = {
126
136
import untpd ._
127
- tpe match {
137
+ stripPos( tpe) match {
128
138
case tpe : PolyType =>
129
139
def tparamTrees = (tpe.paramNames, tpe.paramBounds).zipped.map(toDef).asInstanceOf [List [TypeDef ]]
130
- untpdDef( tpe.resultType) match {
140
+ toDef(name, tpe.resultType) match {
131
141
case mdef1 : DefDef =>
132
142
cpy.DefDef (mdef1)(tparams = tparamTrees)
133
143
case mdef1 : ValDef =>
134
144
DefDef (mdef1.name, tparamTrees, Nil , mdef1.tpt, EmptyTree )
135
145
}
136
146
case tpe : MethodType =>
137
147
def vparamTrees = (tpe.paramNames, tpe.paramTypes).zipped.map(toDef).asInstanceOf [List [ValDef ]]
138
- untpdDef( tpe.resultType) match {
148
+ toDef(name, tpe.resultType) match {
139
149
case mdef1 : DefDef =>
140
150
cpy.DefDef (mdef1)(vparamss = vparamTrees :: mdef1.vparamss)
141
151
case mdef1 : ValDef =>
@@ -148,9 +158,9 @@ object TypePositions {
148
158
}
149
159
}
150
160
}
151
- val tpdDef = untpdDef(tpe).withType(defn. AnyType )
161
+ val tpdDef = untpdDef(tpe).withType(NoPrefix )
152
162
tpe match {
153
- case Positioned (tpe1, pos) => tpdDef.withPos(PointPos .defPos(pos))
163
+ case AnnotatedType (tpe1, PosAnnot ( pos) ) => tpdDef.withPos(PointPos .defPos(pos))
154
164
case _ => tpdDef
155
165
}
156
166
}
@@ -173,8 +183,13 @@ object TypePositions {
173
183
* In each case, the tree's type is `tpe`.
174
184
*/
175
185
def toTree (tpe : Type , hasPos : Boolean = false )(implicit ctx : Context ): Tree = tpe match {
176
- case Positioned (tpe1, pos) =>
177
- toTree(tpe1, hasPos = true ).withPos(pos.toSynthetic)
186
+ case AnnotatedType (tpe1, PosAnnot (pos)) =>
187
+ val tree = toTree(tpe1, hasPos = true ) match {
188
+ case t @ Select (qual, name) if name.length == pos.end - pos.start =>
189
+ untpd.Ident (name).withType(t.tpe)
190
+ case t => t
191
+ }
192
+ tree.withPos(pos.toSynthetic)
178
193
case tpe =>
179
194
val utree : untpd.Tree = {
180
195
import untpd ._
@@ -200,6 +215,8 @@ object TypePositions {
200
215
This (tpnme.EMPTY )
201
216
case tpe : ParamType if hasPos =>
202
217
Ident (tpe.paramName)
218
+ case tpe : RecType =>
219
+ toTree(tpe.parent, hasPos)
203
220
case AppliedType (tycon, args) =>
204
221
mkTree(tycon) { AppliedTypeTree (_, args.map(toTree(_))) }
205
222
case RefinedType (parent, rname, rinfo) =>
@@ -210,10 +227,20 @@ object TypePositions {
210
227
case tpt =>
211
228
RefinedTypeTree (tpt, toRefinement(rname, rinfo) :: Nil )
212
229
}
213
- case tpe : RecType =>
214
- toTree(tpe.parent, hasPos)
215
230
case TypeBounds (lo, hi) =>
216
- mkTree(lo) { TypeBoundsTree (_, toTree(hi)) }
231
+ def toTreeOrEmpty (tpe : Type , cls : Symbol ): Tree = {
232
+ val tree = toTree(tpe)
233
+ tpe match {
234
+ case AnnotatedType (_, PosAnnot (pos)) if pos.start == pos.end && tree.tpe.isRef(cls) =>
235
+ EmptyTree .withPos(pos)
236
+ case _ =>
237
+ tree
238
+ }
239
+ }
240
+ toTreeOrEmpty(lo, defn.NothingClass ) match {
241
+ case tpt : TypeTree => tpt
242
+ case lotree => TypeBoundsTree (lotree, toTreeOrEmpty(hi, defn.AnyClass ))
243
+ }
217
244
case tpe : ExprType =>
218
245
mkTree(tpe.resType) { ByNameTypeTree (_) }
219
246
case tpe : PolyType =>
@@ -235,4 +262,13 @@ object TypePositions {
235
262
}
236
263
utree.withType(tpe)
237
264
}
265
+
266
+ def refPositions (tree : Tree )(implicit ctx : Context ): List [(Name , Position )] = {
267
+ val b = new mutable.ListBuffer [(Name , Position )]
268
+ tree foreachSubTree {
269
+ case t : RefTree => b += ((t.name, t.pos.toSynthetic))
270
+ case _ =>
271
+ }
272
+ b.toList
273
+ }
238
274
}
0 commit comments