summaryrefslogtreecommitdiff
path: root/src/reflect/scala/reflect/macros/Universe.scala
blob: f6a4ef6c9b9719b10c05ba29ac3b59969009cf28 (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
package scala.reflect
package macros

abstract class Universe extends scala.reflect.api.Universe {

  val treeBuild: TreeBuilder { val global: Universe.this.type }

  trait AttachableApi {
    /** ... */
    def attachments: base.Attachments { type Pos = Position }

    /** ... */
    def updateAttachment[T: ClassTag](attachment: T): AttachableApi.this.type

    /** ... */
    def removeAttachment[T: ClassTag]: AttachableApi.this.type
  }

  // Symbol extensions ---------------------------------------------------------------

  override type Symbol >: Null <: SymbolContextApi

  /** The extended API of symbols that's supported in macro context universes
   */
  trait SymbolContextApi extends SymbolApi with AttachableApi { self: Symbol =>

    def deSkolemize: Symbol

    /** The position of this symbol
     */
    def pos: Position

    def setTypeSignature(tpe: Type): Symbol

    def setAnnotations(annots: AnnotationInfo*): Symbol

    def setName(name: Name): Symbol

    def setPrivateWithin(sym: Symbol): Symbol
  }

  // Tree extensions ---------------------------------------------------------------

  override type Tree >: Null <: TreeContextApi

  /** The extended API of trees that's supported in macro context universes
   */
  trait TreeContextApi extends TreeApi with AttachableApi { self: Tree =>

    /** ... */
    def pos_=(pos: Position): Unit

    /** ... */
    def setPos(newpos: Position): Tree

    /** ... */
    def tpe_=(t: Type): Unit

    /** Set tpe to give `tp` and return this.
     */
    def setType(tp: Type): Tree

    /** Like `setType`, but if this is a previously empty TypeTree that
     *  fact is remembered so that resetAllAttrs will snap back.
     *
     *  @PP: Attempting to elaborate on the above, I find: If defineType
     *  is called on a TypeTree whose type field is null or NoType,
     *  this is recorded as "wasEmpty = true". That value is used in
     *  ResetAttrsTraverser, which nulls out the type field of TypeTrees
     *  for which wasEmpty is true, leaving the others alone.
     *
     *  resetAllAttrs is used in situations where some speculative
     *  typing of a tree takes place, fails, and the tree needs to be
     *  returned to its former state to try again. So according to me:
     *  using `defineType` instead of `setType` is how you communicate
     *  that the type being set does not depend on any previous state,
     *  and therefore should be abandoned if the current line of type
     *  inquiry doesn't work out.
     */
    def defineType(tp: Type): Tree

    /** ... */
    def symbol_=(sym: Symbol): Unit

    /** ... */
    def setSymbol(sym: Symbol): Tree
  }

  override type SymTree >: Null <: Tree with SymTreeContextApi

  /** The extended API of sym trees that's supported in macro context universes
   */
  trait SymTreeContextApi extends SymTreeApi { this: SymTree =>
    var symbol: Symbol
  }

  override type TypeTree >: Null <: TypTree with TypeTreeContextApi

  /** The extended API of sym trees that's supported in macro context universes
   */
  trait TypeTreeContextApi extends TypeTreeApi { this: TypeTree =>
    def setOriginal(tree: Tree): this.type
  }

  override type Ident >: Null <: RefTree with IdentContextApi

  /** The extended API of idents that's supported in macro context universes
   */
  trait IdentContextApi extends IdentApi { this: Ident =>
    def isBackquoted: Boolean
  }
}