summaryrefslogtreecommitdiff
path: root/src/reflect/scala/reflect/api/FlagSets.scala
blob: d3294dad9b2ba670b264c91b691c79f6e8423a8f (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
package scala
package reflect
package api

import scala.language.implicitConversions

/**
 * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
 *
 * The trait that defines flag sets and operations on them.
 *
 * `Flag`s are used to provide modifiers for abstract syntax trees that represent definitions
 * via the `flags` field of [[scala.reflect.api.Trees#Modifiers]]. Trees that accept modifiers are:
 *
 *   - '''[[scala.reflect.api.Trees#ClassDef]]'''. Classes and traits.
 *   - '''[[scala.reflect.api.Trees#ModuleDef]]'''. Objects.
 *   - '''[[scala.reflect.api.Trees#ValDef]]'''. Vals, vars, parameters and self-type annotations.
 *   - '''[[scala.reflect.api.Trees#DefDef]]'''. Methods and constructors.
 *   - '''[[scala.reflect.api.Trees#TypeDef]]'''. Type aliases, abstract type members and type parameters.
 *
 * For example, to create a class named `C` one would write something like:
 * {{{
 *  ClassDef(Modifiers(NoFlags), TypeName("C"), Nil, ...)
 * }}}
 *
 * Here, the flag set is empty.
 *
 * To make `C` private, one would write something like:
 * {{{
 *  ClassDef(Modifiers(PRIVATE), TypeName("C"), Nil, ...)
 * }}}
 *
 * Flags can also be combined with the vertical bar operator (`|`).
 * For example, a private final class is written something like:
 * {{{
 *  ClassDef(Modifiers(PRIVATE | FINAL), TypeName("C"), Nil, ...)
 * }}}
 *
 * The list of all available flags is defined in [[scala.reflect.api.FlagSets#FlagValues]], available via
 * [[scala.reflect.api.FlagSets#Flag]]. (Typically one writes a wildcard import for this, e.g.
 * `import scala.reflect.runtime.universe.Flag._`).
 *
 * Definition trees are compiled down to symbols, so flags on modifiers of these trees are transformed into flags
 * on the resulting symbols. Unlike trees, symbols don't expose flags, but rather provide `isXXX` test methods
 * (e.g. `isFinal` can be used to test finality). These test methods might require an upcast with `asTerm`,
 * `asType` or `asClass` as some flags only make sense for certain kinds of symbols.
 *
 * ''Of Note:'' This part of the Reflection API is being considered as a candidate for redesign. It is
 * quite possible that in future releases of the reflection API, flag sets could be replaced with something else.
 *
 * For more details about `FlagSet`s and other aspects of Scala reflection, see the
 * [[http://docs.scala-lang.org/overviews/reflection/overview.html Reflection Guide]]
 *
 * @group ReflectionAPI
 *
 */
trait FlagSets { self: Universe =>

  /** An abstract type representing sets of flags (like private, final, etc.) that apply to definition trees and symbols
   *  @template
   *  @group Flags
   */
  type FlagSet

  /** The API of `FlagSet` instances.
   *  The main source of information about flag sets is the [[scala.reflect.api.FlagSets]] page.
   *  @group Flags
   */
  trait FlagOps extends Any {
    /** Produces a flag set that's a union of this flag set and the provided flag set. */
    def | (right: FlagSet): FlagSet
  }

  /** The API of `FlagSet` instances.
   *  @group Flags
   */
  implicit def addFlagOps(left: FlagSet): FlagOps

  /** A module that contains all possible values that can constitute flag sets.
   *  @group Flags
   */
  val Flag: FlagValues

  // Q: I have a pretty flag. Can I put it here?
  // A: Only if there's a tree that cannot be built without it.
  //    If you want to put a flag here so that it can be tested against,
  //    introduce an `isXXX` method in one of the `api.Symbols` classes instead.

  /** All possible values that can constitute flag sets.
   *  The main source of information about flag sets is the [[scala.reflect.api.FlagSets]] page.
   *  @group Flags
   */
  trait FlagValues {

    /** Flag indicating that tree represents a trait */
    val TRAIT: FlagSet

    /** Flag indicating that a tree is an interface (i.e. a trait which defines only abstract methods) */
    val INTERFACE: FlagSet

    /** Flag indicating that tree represents a mutable variable */
    val MUTABLE: FlagSet

    /** Flag indicating that tree represents a macro definition. */
    val MACRO: FlagSet

    /** Flag indicating that tree represents an abstract type, method, or value */
    val DEFERRED: FlagSet

    /** Flag indicating that tree represents an abstract class */
    val ABSTRACT: FlagSet

    /** Flag indicating that tree has `final` modifier set */
    val FINAL: FlagSet

    /** Flag indicating that tree has `sealed` modifier set */
    val SEALED: FlagSet

    /** Flag indicating that tree has `implicit` modifier set */
    val IMPLICIT: FlagSet

    /** Flag indicating that tree has `lazy` modifier set */
    val LAZY: FlagSet

    /** Flag indicating that tree has `override` modifier set */
    val OVERRIDE: FlagSet

    /** Flag indicating that tree has `private` modifier set */
    val PRIVATE: FlagSet

    /** Flag indicating that tree has `protected` modifier set */
    val PROTECTED: FlagSet

    /** Flag indicating that tree represents a member local to current class,
     *  i.e. private[this] or protected[this].
     *  This requires having either PRIVATE or PROTECTED set as well.
     */
    val LOCAL: FlagSet

    /** Flag indicating that tree has `case` modifier set */
    val CASE: FlagSet

    /** Flag indicating that tree has `abstract` and `override` modifiers set */
    val ABSOVERRIDE: FlagSet

    /** Flag indicating that tree represents a by-name parameter */
    val BYNAMEPARAM: FlagSet

    /** Flag indicating that tree represents a class or parameter.
     *  Both type and value parameters carry the flag. */
    val PARAM: FlagSet

    /** Flag indicating that tree represents a covariant
     *  type parameter (marked with `+`). */
    val COVARIANT: FlagSet

    /** Flag indicating that tree represents a contravariant
     *  type parameter (marked with `-`). */
    val CONTRAVARIANT: FlagSet

    /** Flag indicating that tree represents a parameter that has a default value */
    val DEFAULTPARAM: FlagSet

    /** Flag indicating that tree represents an early definition */
    val PRESUPER: FlagSet

    /** Flag indicating that tree represents a variable or a member initialized to the default value */
    val DEFAULTINIT: FlagSet

    /** Flag indicating that tree represents an enum.
     *
     *  It can only appear at
     *  - the enum's class
     *  - enum constants
     **/
    val ENUM: FlagSet

    /** Flag indicating that tree represents a parameter of the primary constructor of some class
     *  or a synthetic member underlying thereof. E.g. here's how 'class C(val x: Int)' is represented:
     *
     *      [[syntax trees at end of parser]]// Scala source: tmposDU52
     *      class C extends scala.AnyRef {
     *        <paramaccessor> val x: Int = _;
     *        def <init>(x: Int) = {
     *          super.<init>();
     *          ()
     *        }
     *      }
     *      ClassDef(
     *        Modifiers(), TypeName("C"), List(),
     *        Template(
     *          List(Select(Ident(scala), TypeName("AnyRef"))),
     *          noSelfType,
     *          List(
     *            ValDef(Modifiers(PARAMACCESSOR), TermName("x"), Ident(TypeName("Int")), EmptyTree),
     *            DefDef(
     *              Modifiers(), nme.CONSTRUCTOR, List(),
     *              List(List(ValDef(Modifiers(PARAM | PARAMACCESSOR), TermName("x"), Ident(TypeName("Int")), EmptyTree))), TypeTree(),
     *              Block(List(pendingSuperCall), Literal(Constant(())))))))))
     */
    val PARAMACCESSOR: FlagSet

    /** Flag indicating that tree represents a parameter of the primary constructor of some case class
     *  or a synthetic member underlying thereof.  E.g. here's how 'case class C(val x: Int)' is represented:
     *
     *      [[syntax trees at end of parser]]// Scala source: tmpnHkJ3y
     *      case class C extends scala.Product with scala.Serializable {
     *        <caseaccessor> <paramaccessor> val x: Int = _;
     *        def <init>(x: Int) = {
     *          super.<init>();
     *          ()
     *        }
     *      }
     *      ClassDef(
     *        Modifiers(CASE), TypeName("C"), List(),
     *        Template(
     *          List(Select(Ident(scala), TypeName("Product")), Select(Ident(scala), TypeName("Serializable"))),
     *          noSelfType,
     *          List(
     *            ValDef(Modifiers(CASEACCESSOR | PARAMACCESSOR), TermName("x"), Ident(TypeName("Int")), EmptyTree),
     *            DefDef(
     *              Modifiers(), nme.CONSTRUCTOR, List(),
     *              List(List(ValDef(Modifiers(PARAM | PARAMACCESSOR), TermName("x"), Ident(TypeName("Int")), EmptyTree))), TypeTree(),
     *              Block(List(pendingSuperCall), Literal(Constant(())))))))))
     */
    val CASEACCESSOR: FlagSet

    /** Flag used to distinguish programmatically generated definitions from user-written ones.
     *  @see ARTIFACT
     */
    val SYNTHETIC: FlagSet

    /** Flag used to distinguish platform-specific implementation details.
     *  Trees and symbols which are currently marked ARTIFACT by scalac:
     *    * $outer fields and accessors
     *    * super accessors
     *    * protected accessors
     *    * lazy local accessors
     *    * bridge methods
     *    * default argument getters
     *    * evaluation-order preserving locals for right-associative and out-of-order named arguments
     *    * catch-expression storing vals
     *    * anything else which feels a setFlag(ARTIFACT)
     *
     *  @see SYNTHETIC
     */
    val ARTIFACT: FlagSet

    /** Flag that indicates methods that are supposed to be stable
     *  (e.g. synthetic getters of valdefs).
     */
    val STABLE: FlagSet
  }

  /** The empty set of flags
   *  @group Flags
   */
  val NoFlags: FlagSet
}