@@ -12,6 +12,29 @@ import Flags._
12
12
import util .Positions .Position
13
13
import collection .mutable
14
14
15
+ object TypeApplications {
16
+
17
+ /** Assert type is not a TypeBounds instance and return it unchanged */
18
+ val noBounds = (tp : Type ) => tp match {
19
+ case tp : TypeBounds => throw new AssertionError (" no TypeBounds allowed" )
20
+ case _ => tp
21
+ }
22
+
23
+ /** If `tp` is a TypeBounds instance return its lower bound else return `tp` */
24
+ val boundsToLo = (tp : Type ) => tp match {
25
+ case tp : TypeBounds => tp.lo
26
+ case _ => tp
27
+ }
28
+
29
+ /** If `tp` is a TypeBounds instance return its upper bound else return `tp` */
30
+ val boundsToHi = (tp : Type ) => tp match {
31
+ case tp : TypeBounds => tp.hi
32
+ case _ => tp
33
+ }
34
+ }
35
+
36
+ import TypeApplications ._
37
+
15
38
/** A decorator that provides methods for modeling type application */
16
39
class TypeApplications (val self : Type ) extends AnyVal {
17
40
@@ -135,24 +158,43 @@ class TypeApplications(val self: Type) extends AnyVal {
135
158
else TypeAlias (self, v)
136
159
}
137
160
138
- /** The type arguments of the base type instance wrt `base` of this type */
139
- final def baseTypeArgs (base : Symbol )(implicit ctx : Context ): List [Type ] =
161
+ /** The type arguments of this type's base type instance wrt.`base`.
162
+ * Existential types in arguments are returned as TypeBounds instances.
163
+ */
164
+ final def baseArgInfos (base : Symbol )(implicit ctx : Context ): List [Type ] =
140
165
if (self derivesFrom base)
141
- base.typeParams map (param => self.member(param.name).info.argType (param))
166
+ base.typeParams map (param => self.member(param.name).info.argInfo (param))
142
167
else
143
168
Nil
144
169
170
+ /** The type arguments of this type's base type instance wrt.`base`.
171
+ * Existential types in arguments are disallowed.
172
+ */
173
+ final def baseArgTypes (base : Symbol )(implicit ctx : Context ): List [Type ] = baseArgInfos(base) mapConserve noBounds
174
+
175
+ /** The type arguments of this type's base type instance wrt.`base`.
176
+ * Existential types in arguments are approximanted by their lower bound.
177
+ */
178
+ final def baseArgTypesLo (base : Symbol )(implicit ctx : Context ): List [Type ] = baseArgInfos(base) mapConserve boundsToLo
179
+
180
+ /** The type arguments of this type's base type instance wrt.`base`.
181
+ * Existential types in arguments are approximanted by their upper bound.
182
+ */
183
+ final def baseArgTypesHi (base : Symbol )(implicit ctx : Context ): List [Type ] = baseArgInfos(base) mapConserve boundsToHi
184
+
145
185
/** The first type argument of the base type instance wrt `base` of this type */
146
- final def firstBaseTypeArg (base : Symbol )(implicit ctx : Context ): Type = base.typeParams match {
186
+ final def firstBaseArgInfo (base : Symbol )(implicit ctx : Context ): Type = base.typeParams match {
147
187
case param :: _ if self derivesFrom base =>
148
- self.member(param.name).info.argType (param)
188
+ self.member(param.name).info.argInfo (param)
149
189
case _ =>
150
190
NoType
151
191
}
152
192
153
- /** The base type including all type arguments of this type */
193
+ /** The base type including all type arguments of this type.
194
+ * Existential types in arguments are returned as TypeBounds instances.
195
+ */
154
196
final def baseTypeWithArgs (base : Symbol )(implicit ctx : Context ): Type =
155
- self.baseTypeRef(base).appliedTo(baseTypeArgs (base))
197
+ self.baseTypeRef(base).appliedTo(baseArgInfos (base))
156
198
157
199
/** Translate a type of the form From[T] to To[T], keep other types as they are.
158
200
* `from` and `to` must be static classes, both with one type parameter, and the same variance.
@@ -163,9 +205,10 @@ class TypeApplications(val self: Type) extends AnyVal {
163
205
else self
164
206
165
207
/** If this is an encoding of a (partially) applied type, return its arguments,
166
- * otherwise return Nil
208
+ * otherwise return Nil.
209
+ * Existential types in arguments are returned as TypeBounds instances.
167
210
*/
168
- final def typeArgs (implicit ctx : Context ): List [Type ] = {
211
+ final def argInfos (implicit ctx : Context ): List [Type ] = {
169
212
var tparams : List [TypeSymbol ] = null
170
213
def recur (tp : Type , refineCount : Int ): mutable.ListBuffer [Type ] = tp.stripTypeVar match {
171
214
case tp @ RefinedType (tycon, name) =>
@@ -175,7 +218,7 @@ class TypeApplications(val self: Type) extends AnyVal {
175
218
if (tparams == null ) tparams = tycon.typeParams
176
219
if (buf.size < tparams.length) {
177
220
val tparam = tparams(buf.size)
178
- if (name == tparam.name) buf += tp.refinedInfo.argType (tparam)
221
+ if (name == tparam.name) buf += tp.refinedInfo.argInfo (tparam)
179
222
else null
180
223
} else null
181
224
}
@@ -187,6 +230,15 @@ class TypeApplications(val self: Type) extends AnyVal {
187
230
if (buf == null ) Nil else buf.toList
188
231
}
189
232
233
+ /** Argument types where existential types in arguments are disallowed */
234
+ def argTypes (implicit ctx : Context ) = argInfos mapConserve noBounds
235
+
236
+ /** Argument types where existential types in arguments are approximated by their lower bound */
237
+ def argTypesLo (implicit ctx : Context ) = argInfos mapConserve boundsToLo
238
+
239
+ /** Argument types where existential types in arguments are approximated by their upper bound */
240
+ def argTypesHi (implicit ctx : Context ) = argInfos mapConserve boundsToHi
241
+
190
242
/** The core type without any type arguments.
191
243
* @param `typeArgs` must be the type arguments of this type.
192
244
*/
@@ -201,7 +253,7 @@ class TypeApplications(val self: Type) extends AnyVal {
201
253
/** If this is the image of a type argument to type parameter `tparam`,
202
254
* recover the type argument, otherwise NoType.
203
255
*/
204
- final def argType (tparam : Symbol )(implicit ctx : Context ): Type = self match {
256
+ final def argInfo (tparam : Symbol )(implicit ctx : Context ): Type = self match {
205
257
case TypeBounds (lo, hi) =>
206
258
if (lo eq hi) hi
207
259
else {
@@ -216,7 +268,7 @@ class TypeApplications(val self: Type) extends AnyVal {
216
268
217
269
/** The element type of a sequence or array */
218
270
def elemType (implicit ctx : Context ): Type =
219
- firstBaseTypeArg (defn.SeqClass ) orElse firstBaseTypeArg (defn.ArrayClass )
271
+ firstBaseArgInfo (defn.SeqClass ) orElse firstBaseArgInfo (defn.ArrayClass )
220
272
221
273
/** If this type is of the normalized form Array[...[Array[T]...]
222
274
* return the number of Array wrappers and T.
@@ -225,7 +277,7 @@ class TypeApplications(val self: Type) extends AnyVal {
225
277
final def splitArray (implicit ctx : Context ): (Int , Type ) = {
226
278
def recur (n : Int , tp : Type ): (Int , Type ) = tp.stripTypeVar match {
227
279
case RefinedType (tycon, _) if tycon isRef defn.ArrayClass =>
228
- tp.typeArgs match {
280
+ tp.argInfos match {
229
281
case arg :: Nil => recur(n + 1 , arg)
230
282
case _ => (n, tp)
231
283
}
@@ -274,7 +326,7 @@ class TypeApplications(val self: Type) extends AnyVal {
274
326
275
327
val correspondingParamName : Map [Symbol , TypeName ] = {
276
328
for {
277
- (tparam, targ : TypeRef ) <- cls.typeParams zip typeArgs
329
+ (tparam, targ : TypeRef ) <- cls.typeParams zip argInfos
278
330
if boundSyms contains targ.symbol
279
331
} yield targ.symbol -> tparam.name
280
332
}.toMap
0 commit comments