1
+ object tasty {
2
+
3
+ // ------ Names --------------------------------
4
+
5
+ trait Name
6
+ trait PossiblySignedName
7
+
8
+ enum TermName extends Name with PossiblySignedName {
9
+ case Simple (str : String )
10
+ case Qualified (prefix : TermName , selector : String ) // s"$prefix.$name"
11
+ case Unique (underlying : TermName , separator : String , idx : Int ) // s"$underlying$separator$idx"
12
+ case DefaultGetter (methodName : TermName , idx : String ) // s"$methodName${"$default$"}${idx+1}"
13
+ case Variant (underlying : TermName , covariant : Boolean ) // s"${if (covariant) "+" else "-"}$underlying"
14
+ case SuperAccessor (underlying : TermName ) // s"${"super$"}$underlying"
15
+ case ProtectedAccessor (underlying : TermName ) // s"${"protectded$"}$underlying"
16
+ case ProtectedSetter (underlying : TermName ) // s"${"protectded$set"}$underlying"
17
+ case ObjectClass (underlying : TermName ) // s"$underlying${"$"}"
18
+
19
+ case Expanded (prefix : TermName , selector : String ) // s"$prefix${"$$"}$name" , used only for symbols coming from Scala 2
20
+ case ExpandedPrefix (prefix : TermName , selector : String ) // s"$prefix${"$"}$name" , used only for symbols coming from Scala 2
21
+ }
22
+
23
+ case class SignedName (name : TermName , resultSig : TypeName , paramSigs : List [TypeName ]) extends PossiblySignedName
24
+
25
+ case class TypeName (name : TermName ) extends Name
26
+
27
+ // ------ Positions ---------------------------
28
+
29
+ case class Position (firstOffset : Int , lastOffset : Int )
30
+
31
+ trait Positioned {
32
+ def pos : Position = ???
33
+ }
34
+
35
+ // ------ Statements ---------------------------------
36
+
37
+ // Note: Definitions are written as extractors, because they may be referred to
38
+ // recursively from some of their arguments (since we equate symbols with definitions)
39
+
40
+ trait TopLevelStatement extends Positioned
41
+
42
+ trait Statement extends TopLevelStatement
43
+
44
+ case class Package (pkg : Term , body : List [TopLevelStatement ]) extends TopLevelStatement
45
+
46
+ trait Definition extends Statement {
47
+ def tpe : Type = Type .SymRef (this , ??? )
48
+ }
49
+
50
+ class ValDef (
51
+ val name : TermName ,
52
+ val tpt : Term ,
53
+ rhsExp : ValDef => Term | Empty ,
54
+ val mods : List [Modifier ])
55
+ extends Definition {
56
+ lazy val rhs = rhsExp(this )
57
+ }
58
+ object ValDef {
59
+ def apply (name : TermName , tpt : Term , rhs : Term | Empty , mods : List [Modifier ] = Nil ) =
60
+ new ValDef (name, tpt, _ => rhs, mods)
61
+ def unapply (vdef : ValDef ) = Some ((vdef.name, vdef.tpt, vdef.rhs, vdef.mods))
62
+ }
63
+
64
+ class DefDef (
65
+ val name : TermName ,
66
+ typeParamsExp : DefDef => List [TypeDef ],
67
+ paramssExp : DefDef => List [List [ValDef ]],
68
+ returnTptExp : DefDef => Term ,
69
+ rhsExp : DefDef => Term | Empty ,
70
+ val mods : List [Modifier ])
71
+ extends Definition {
72
+ val typeParams = typeParamsExp(this )
73
+ val paramss = paramssExp(this )
74
+ val returnTpt = returnTptExp(this )
75
+ lazy val rhs = rhsExp(this )
76
+ }
77
+ object DefDef {
78
+ def apply (name : TermName , typeParams : List [TypeDef ], paramss : List [List [ValDef ]], returnTpt : Term , rhs : Term | Empty , mods : List [Modifier ] = Nil ) =
79
+ new DefDef (name, _ => typeParams, _ => paramss, _ => returnTpt, _ => rhs, mods)
80
+ def unapply (ddef : DefDef ) = Some ((ddef.name, ddef.typeParams, ddef.paramss, ddef.returnTpt, ddef.rhs, ddef.mods))
81
+ }
82
+
83
+ class TypeDef (
84
+ val name : TypeName ,
85
+ rhsExp : TypeDef => Term ,
86
+ val mods : List [Modifier ])
87
+ extends Definition {
88
+ val rhs = rhsExp(this ),
89
+ }
90
+ object TypeDef {
91
+ def apply (name : TypeName , rhs : Term , mods : List [Modifier ] = Nil ) = new TypeDef (name, _ => rhs, mods)
92
+ def unapply (tdef : TypeDef ) = Some ((tdef.name, tdef.rhs, tdef.mods))
93
+ }
94
+
95
+ class ClassDef (
96
+ val name : TypeName ,
97
+ rhsExp : ClassDef => Template ,
98
+ val mods : List [Modifier ])
99
+ extends Definition {
100
+ val rhs = rhsExp(this )
101
+ }
102
+ object ClassDef {
103
+ def apply (name : TypeName , rhs : Template , mods : List [Modifier ] = Nil ) = new ClassDef (name, _ => rhs, mods)
104
+ def unapply (tdef : ClassDef ) = Some ((tdef.name, tdef.rhs, tdef.mods))
105
+ }
106
+
107
+ case class Template (
108
+ typeParams : List [TypeDef ],
109
+ paramss : List [List [ValDef ]],
110
+ parents : List [Term ],
111
+ self : ValDef | Empty ,
112
+ body : List [Statement ])
113
+
114
+ case class Import (expr : Term , selector : List [ImportSelector ]) extends Statement
115
+
116
+ enum ImportSelector {
117
+ case Simple (id : Id )
118
+ case Rename (id1 : Id , id2 : Id )
119
+ case Omit (id1 : Id )
120
+ }
121
+
122
+ case class Id (name : String ) extends Positioned // untyped ident
123
+
124
+ // ------ Terms ---------------------------------
125
+
126
+ /** Trees denoting terms */
127
+ enum Term extends Statement {
128
+ def tpe : Type = ???
129
+ case Ident (name : TermName , override val tpe : Type )
130
+ case Select (prefix : Term , name : PossiblySignedName )
131
+ case Literal (value : Constant )
132
+ case This (id : Id | Empty )
133
+ case New (tpt : Term )
134
+ case NamedArg (name : TermName , arg : Term )
135
+ case Apply (fn : Term , args : List [Term ])
136
+ case TypeApply (fn : Term , args : List [Term ])
137
+ case Super (thiz : Term , mixin : Id | Empty )
138
+ case Typed (expr : Term , tpt : Term )
139
+ case Assign (lhs : Term , rhs : Term )
140
+ case Block (stats : List [Statement ], expr : Term )
141
+ case Inlined (call : Term , bindings : List [Definition ], expr : Term )
142
+ case Lambda (method : Term , tpt : Term | Empty )
143
+ case If (cond : Term , thenPart : Term , elsePart : Term )
144
+ case Match (scrutinee : Term , cases : List [CaseDef ])
145
+ case Try (body : Term , catches : List [CaseDef ], finalizer : Term | Empty )
146
+ case Return (expr : Term )
147
+ case Repeated (args : List [Term ])
148
+ case SelectOuter (from : Term , levels : Int , target : Type ) // can be generated by inlining
149
+ case Tpt (underlying : TypeTerm | Empty )
150
+ }
151
+
152
+ /** Trees denoting types */
153
+ enum TypeTerm extends Positioned {
154
+ def tpe : Type = ???
155
+ case Ident (name : TypeName , override val tpe : Type )
156
+ case Select (prefix : Term , name : TypeName )
157
+ case Singleton (ref : Term )
158
+ case Refined (underlying : TypeTerm , refinements : List [Definition ])
159
+ case Applied (tycon : TypeTerm , args : List [TypeTerm ])
160
+ case TypeBounds (loBound : TypeTerm , hiBound : TypeTerm )
161
+ case Annotated (tpt : TypeTerm , annotation : Term )
162
+ case And (left : TypeTerm , right : TypeTerm )
163
+ case Or (left : TypeTerm , right : TypeTerm )
164
+ case ByName (tpt : TypeTerm )
165
+ }
166
+
167
+ /** Trees denoting patterns */
168
+ enum Pattern extends Positioned {
169
+ def tpe : Type = ???
170
+ case Value (v : Term )
171
+ case Bind (name : TermName , pat : Pattern )
172
+ case Unapply (unapply : Term , implicits : List [Term ], pats : List [Pattern ])
173
+ case Alternative (pats : List [Pattern ])
174
+ case TypeTest (tpt : Term )
175
+ case Wildcard ()
176
+ }
177
+
178
+ case class CaseDef (pat : Pattern , guard : Term | Empty , rhs : Term ) extends Positioned
179
+
180
+ sealed trait Type
181
+
182
+ // ------ Types ---------------------------------
183
+
184
+ object Type {
185
+ case class ConstantType (value : Constant ) extends Type
186
+ case class SymRef (sym : Definition , qualifier : Type | Empty = Empty ) extends Type
187
+ case class NameRef (name : Name , qualifier : Type | Empty = Empty ) extends Type // Empty means: select from _root_
188
+ case class SuperType (thistp : Type , underlying : Type ) extends Type
189
+ case class Refinement (underlying : Type , name : Name , tpe : Type ) extends Type
190
+ case class AppliedType (tycon : Type , args : Type | TypeBounds ) extends Type
191
+ case class AnnotatedType (underlying : Type , annotation : Term ) extends Type
192
+ case class AndType (left : Type , right : Type ) extends Type
193
+ case class OrType (left : Type , right : Type ) extends Type
194
+ case class ByNameType (underlying : Type ) extends Type
195
+ case class ParamRef (binder : LambdaType , idx : Int ) extends Type
196
+ case class RecThis (binder : RecursiveType ) extends Type
197
+
198
+ // The following types are all expressed by extractors because they may be referred
199
+ // to from some of their arguments
200
+
201
+ class RecursiveType (underlyingExp : RecursiveType => Type ) extends Type {
202
+ val underlying = underlyingExp(this )
203
+ }
204
+ object RecursiveType {
205
+ def unapply (tp : RecursiveType ): Option [Type ] = Some (tp.underlying)
206
+ }
207
+
208
+ trait LambdaType extends Type {
209
+ type ParamName
210
+ type ParamInfo
211
+ def paramNames : List [ParamName ]
212
+ def paramInfos : List [ParamInfo ]
213
+ def resultType : Type
214
+ }
215
+
216
+ class MethodType (val paramNames : List [TermName ], paramTypesExp : MethodType => List [Type ],
217
+ resultTypeExp : MethodType => Type , val mods : List [Modifier ]) extends LambdaType {
218
+ type ParamName = TermName
219
+ type ParamInfo = Type
220
+ val paramTypes = paramTypesExp(this )
221
+ val resultType = resultTypeExp(this )
222
+ def paramInfos = paramTypes
223
+ }
224
+ object MethodType {
225
+ def apply (paramNames : List [TermName ], paramTypes : List [Type ], resultType : Type , mods : List [Modifier ] = Nil ) =
226
+ new MethodType (paramNames, _ => paramTypes, _ => resultType, mods)
227
+ def unapply (tp : MethodType ) = Some ((tp.paramNames, tp.paramTypes, tp.resultType, tp.mods))
228
+ }
229
+
230
+ class PolyType (val paramNames : List [TypeName ], paramBoundsExp : PolyType => List [TypeBounds ],
231
+ resultTypeExp : PolyType => Type ) extends LambdaType {
232
+ type ParamName = TypeName
233
+ type ParamInfo = TypeBounds
234
+ val paramBounds = paramBoundsExp(this )
235
+ val resultType = resultTypeExp(this )
236
+ def paramInfos = paramBounds
237
+ }
238
+ object PolyType {
239
+ def apply (paramNames : List [TypeName ], paramBounds : List [TypeBounds ], resultType : Type ) =
240
+ new PolyType (paramNames, _ => paramBounds, _ => resultType)
241
+ def unapply (tp : PolyType ) = Some ((tp.paramNames, tp.paramBounds, tp.resultType))
242
+ }
243
+
244
+ class TypeLambda (val paramNames : List [TypeName ], paramBoundsExp : TypeLambda => List [TypeBounds ],
245
+ resultTypeExp : TypeLambda => Type ) extends LambdaType {
246
+ type ParamName = TypeName
247
+ type ParamInfo = TypeBounds
248
+ val paramBounds = paramBoundsExp(this )
249
+ val resultType = resultTypeExp(this )
250
+ def paramInfos = paramBounds
251
+ }
252
+ object TypeLambda {
253
+ def apply (paramNames : List [TypeName ], paramBounds : List [TypeBounds ], resultType : Type ) =
254
+ new TypeLambda (paramNames, _ => paramBounds, _ => resultType)
255
+ def unapply (tp : TypeLambda ) = Some ((tp.paramNames, tp.paramBounds, tp.resultType))
256
+ }
257
+
258
+ case class TypeBounds (loBound : Type , hiBound : Type )
259
+ }
260
+
261
+ // ------ Modifiers ---------------------------------
262
+
263
+ enum Modifier extends Positioned {
264
+ case Private , Protected , Abstract , Final , Sealed , Case , Implicit , Erased , Lazy , Override , Inline ,
265
+ Macro , // inline method containing toplevel splices
266
+ Static , // mapped to static Java member
267
+ Object , // an object or its class (used for a ValDef or a ClassDef, respectively)
268
+ Trait , // a trait (used for a ClassDef)
269
+ Local , // used in conjunction with Private/Protected to mean private[this], proctected[this]
270
+ Synthetic , // generated by Scala compiler
271
+ Artifact , // to be tagged Java Synthetic
272
+ Mutable , // when used on a ValDef: a var
273
+ Label , // method generated as a label
274
+ FieldAccessor , // a getter or setter
275
+ CaseAcessor , // getter for case class parameter
276
+ Covariant , // type parameter marked “+”
277
+ Contravariant , // type parameter marked “-”
278
+ Scala2X , // Imported from Scala2.x
279
+ DefaultParameterized , // Method with default parameters
280
+ Stable // Method that is assumed to be stable
281
+
282
+ case QualifiedPrivate (boundary : Type )
283
+ case QualifiedProtected (boundary : Type )
284
+ case Annotation (tree : Term )
285
+ }
286
+
287
+ // ------ Constants ---------------------------------
288
+
289
+ enum Constant (value : Any ) {
290
+ case Unit extends Constant (())
291
+ case False extends Constant (false )
292
+ case True extends Constant (true )
293
+ case Null extends Constant (null )
294
+ case Byte (value : scala.Byte ) extends Constant (value)
295
+ case Short (value : scala.Short ) extends Constant (value)
296
+ case Char (value : scala.Char ) extends Constant (value)
297
+ case Int (value : scala.Int ) extends Constant (value)
298
+ case Long (value : scala.Long ) extends Constant (value)
299
+ case Float (value : scala.Float ) extends Constant (value)
300
+ case Double (value : scala.Double ) extends Constant (value)
301
+ case String (value : java.lang.String ) extends Constant (value)
302
+ case Class (value : Type ) extends Constant (value)
303
+ case Enum (value : Type ) extends Constant (value)
304
+ }
305
+
306
+ sealed class Empty ()
307
+ object Empty extends Empty
308
+ }
0 commit comments