summaryrefslogtreecommitdiff
path: root/src/reflect/scala/reflect/api/Types.scala
blob: fab4e5d0a9e4d156fc66e6782718de15cce993ad (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
package scala.reflect
package api

trait Types extends base.Types { self: Universe =>

  override type Type >: Null <: TypeApi

  /** The extended API of types
   */
  abstract class TypeApi extends TypeBase {
    /** The term symbol associated with the type, or `NoSymbol` for types
     *  that do not refer to a term symbol.
     */
    def termSymbol: Symbol

    /** The type symbol associated with the type, or `NoSymbol` for types
     *  that do not refer to a type symbol.
     */
    def typeSymbol: Symbol

    /** The defined or declared members with name `name` in this type;
     *  an OverloadedSymbol if several exist, NoSymbol if none exist.
     *  Alternatives of overloaded symbol appear in the order they are declared.
     */
    def declaration(name: Name): Symbol

    /** A `Scope` containing directly declared members of this type.
     *  Unlike `members` this method doesn't returns inherited members.
     *
     *  Members in the returned scope might appear in arbitrary order.
     *  Use `declarations.sorted` to get an ordered list of members.
     */
    def declarations: MemberScope

    /** The member with given name, either directly declared or inherited,
     *  an OverloadedSymbol if several exist, NoSymbol if none exist.
     */
    def member(name: Name): Symbol

    /** A `Scope` containing all members of this type (directly declared or inherited).
     *  Unlike `declarations` this method also returns inherited members.
     *
     *  Members in the returned scope might appear in arbitrary order.
     *  Use `declarations.sorted` to get an ordered list of members.
     */
    def members: MemberScope

    /** Is this type a type constructor that is missing its type arguments?
     */
    def takesTypeArgs: Boolean

    /** Returns the corresponding type constructor (e.g. List for List[T] or List[String])
     */
    def typeConstructor: Type

    /**
     *  Expands type aliases and converts higher-kinded TypeRefs to PolyTypes.
     *  Functions on types are also implemented as PolyTypes.
     *
     *  Example: (in the below, <List> is the type constructor of List)
     *    TypeRef(pre, <List>, List()) is replaced by
     *    PolyType(X, TypeRef(pre, <List>, List(X)))
     */
    def normalize: Type

    /** Does this type conform to given type argument `that`? */
    def <:< (that: Type): Boolean

    /** Is this type a weak subtype of that type? True also for numeric types, i.e. Int weak_<:< Long.
     */
    def weak_<:<(that: Type): Boolean

    /** Is this type equivalent to given type argument `that`? */
    def =:= (that: Type): Boolean

    /** The list of all base classes of this type (including its own typeSymbol)
     *  in reverse linearization order, starting with the class itself and ending
     *  in class Any.
     */
    def baseClasses: List[Symbol]

    /** The least type instance of given class which is a supertype
     *  of this type.  Example:
     *  {{{
     *    class D[T]
     *    class C extends p.D[Int]
     *    ThisType(C).baseType(D) = p.D[Int]
     * }}}
     */
    def baseType(clazz: Symbol): Type

    /** This type as seen from prefix `pre` and class `clazz`. This means:
     *  Replace all thistypes of `clazz` or one of its subclasses
     *  by `pre` and instantiate all parameters by arguments of `pre`.
     *  Proceed analogously for thistypes referring to outer classes.
     *
     *  Example:
     *  {{{
     *    class D[T] { def m: T }
     *    class C extends p.D[Int]
     *    T.asSeenFrom(ThisType(C), D)  (where D is owner of m)
     *      = Int
     *  }}}
     */
    def asSeenFrom(pre: Type, clazz: Symbol): Type

    /** The erased type corresponding to this type after
     *  all transformations from Scala to Java have been performed.
     */
    def erasure: Type

    /** If this is a singleton type, widen it to its nearest underlying non-singleton
     *  base type by applying one or more `underlying` dereferences.
     *  If this is not a singleton type, returns this type itself.
     *
     *  Example:
     *
     *  class Outer { class C ; val x: C }
     *  val o: Outer
     *  <o.x.type>.widen = o.C
     */
    def widen: Type

    /******************* helpers *******************/

    /** Substitute symbols in `to` for corresponding occurrences of references to
     *  symbols `from` in this type.
     */
    def substituteSymbols(from: List[Symbol], to: List[Symbol]): Type

    /** Substitute types in `to` for corresponding occurrences of references to
     *  symbols `from` in this type.
     */
    def substituteTypes(from: List[Symbol], to: List[Type]): Type

   /** Apply `f` to each part of this type, returning
    *  a new type. children get mapped before their parents */
    def map(f: Type => Type): Type

    /** Apply `f` to each part of this type, for side effects only */
    def foreach(f: Type => Unit)

    /** Returns optionally first type (in a preorder traversal) which satisfies predicate `p`,
     *  or None if none exists.
     */
    def find(p: Type => Boolean): Option[Type]

    /** Is there part of this type which satisfies predicate `p`? */
    def exists(p: Type => Boolean): Boolean

    /** Does this type contain a reference to given symbol? */
    def contains(sym: Symbol): Boolean
  }

  /** .. */
  override type ThisType >: Null <: SingletonType with ThisTypeApi

  /** The API that all this types support */
  trait ThisTypeApi extends TypeApi { this: ThisType =>
    val sym: Symbol
  }

  /** .. */
  override type SingleType >: Null <: SingletonType with SingleTypeApi

  /** The API that all single types support */
  trait SingleTypeApi extends TypeApi { this: SingleType =>
    val pre: Type
    val sym: Symbol
  }

  /** .. */
  override type SuperType >: Null <: SingletonType with SuperTypeApi

  /** The API that all super types support */
  trait SuperTypeApi extends TypeApi { this: SuperType =>
    val thistpe: Type
    val supertpe: Type
  }

  /** .. */
  override type ConstantType >: Null <: SingletonType with ConstantTypeApi

  /** The API that all constant types support */
  trait ConstantTypeApi extends TypeApi { this: ConstantType =>
    val value: Constant
  }

  /** .. */
  override type TypeRef >: Null <: Type with TypeRefApi

  /** The API that all type refs support */
  trait TypeRefApi extends TypeApi { this: TypeRef =>
    val pre: Type
    val sym: Symbol
    val args: List[Type]
  }

  /** .. */
  override type RefinedType >: Null <: CompoundType with RefinedTypeApi

  /** The API that all refined types support */
  trait RefinedTypeApi extends TypeApi { this: RefinedType =>
    val parents: List[Type]
    val decls: Scope
  }

  /** .. */
  override type ClassInfoType >: Null <: CompoundType with ClassInfoTypeApi

  /** The API that all class info types support */
  trait ClassInfoTypeApi extends TypeApi { this: ClassInfoType =>
    val parents: List[Type]
    val decls: Scope
    val typeSymbol: Symbol
  }

  /** .. */
  override type MethodType >: Null <: Type with MethodTypeApi

  /** The API that all method types support */
  trait MethodTypeApi extends TypeApi { this: MethodType =>
    val params: List[Symbol]
    val resultType: Type
  }

  /** .. */
  override type NullaryMethodType >: Null <: Type with NullaryMethodTypeApi

  /** The API that all nullary method types support */
  trait NullaryMethodTypeApi extends TypeApi { this: NullaryMethodType =>
    val resultType: Type
  }

  /** .. */
  override type PolyType >: Null <: Type with PolyTypeApi

  /** The API that all polymorphic types support */
  trait PolyTypeApi extends TypeApi { this: PolyType =>
    val typeParams: List[Symbol]
    val resultType: Type
  }

  /** .. */
  override type ExistentialType >: Null <: Type with ExistentialTypeApi

  /** The API that all existential types support */
  trait ExistentialTypeApi extends TypeApi { this: ExistentialType =>
    val quantified: List[Symbol]
    val underlying: Type
  }

  /** .. */
  override type AnnotatedType >: Null <: Type with AnnotatedTypeApi

  /** The API that all annotated types support */
  trait AnnotatedTypeApi extends TypeApi { this: AnnotatedType =>
    val annotations: List[AnnotationInfo]
    val underlying: Type
    val selfsym: Symbol
  }

  /** .. */
  override type TypeBounds >: Null <: Type with TypeBoundsApi

  /** The API that all type bounds support */
  trait TypeBoundsApi extends TypeApi { this: TypeBounds =>
    val lo: Type
    val hi: Type
  }

  /** .. */
  override type BoundedWildcardType >: Null <: Type with BoundedWildcardTypeApi

  /** The API that all this types support */
  trait BoundedWildcardTypeApi extends TypeApi { this: BoundedWildcardType =>
    val bounds: TypeBounds
  }

  /** The least upper bound of a list of types, as determined by `<:<`.  */
  def lub(xs: List[Type]): Type

    /** The greatest lower bound of a list of types, as determined by `<:<`. */
  def glb(ts: List[Type]): Type

  // Creators ---------------------------------------------------------------
  // too useful and too non-trivial to be left out of public API

  /** The canonical creator for single-types */
  def singleType(pre: Type, sym: Symbol): Type

  /** the canonical creator for a refined type with a given scope */
  def refinedType(parents: List[Type], owner: Symbol, decls: Scope, pos: Position): Type

  /** The canonical creator for a refined type with an initially empty scope.
   */
  def refinedType(parents: List[Type], owner: Symbol): Type

  /** The canonical creator for typerefs
   */
  def typeRef(pre: Type, sym: Symbol, args: List[Type]): Type

  /** A creator for intersection type where intersections of a single type are
   *  replaced by the type itself. */
  def intersectionType(tps: List[Type]): Type

  /** A creator for intersection type where intersections of a single type are
   *  replaced by the type itself, and repeated parent classes are merged.
   *
   *  !!! Repeated parent classes are not merged - is this a bug in the
   *  comment or in the code?
   */
  def intersectionType(tps: List[Type], owner: Symbol): Type

  /** A creator for type applications */
  def appliedType(tycon: Type, args: List[Type]): Type

  /** A creator for type parameterizations that strips empty type parameter lists.
   *  Use this factory method to indicate the type has kind * (it's a polymorphic value)
   *  until we start tracking explicit kinds equivalent to typeFun (except that the latter requires tparams nonEmpty).
   */
  def polyType(tparams: List[Symbol], tpe: Type): Type

  /** A creator for existential types. This generates:
   *
   *  {{{
   *    tpe1 where { tparams }
   *  }}}
   *
   *  where `tpe1` is the result of extrapolating `tpe` with regard to `tparams`.
   *  Extrapolating means that type variables in `tparams` occurring
   *  in covariant positions are replaced by upper bounds, (minus any
   *  SingletonClass markers), type variables in `tparams` occurring in
   *  contravariant positions are replaced by upper bounds, provided the
   *  resulting type is legal with regard to stability, and does not contain
   *  any type variable in `tparams`.
   *
   *  The abstraction drops all type parameters that are not directly or
   *  indirectly referenced by type `tpe1`. If there are no remaining type
   *  parameters, simply returns result type `tpe`.
   */
  def existentialAbstraction(tparams: List[Symbol], tpe0: Type): Type
}