@@ -2,7 +2,7 @@ package tasty
2
2
3
3
object definitions {
4
4
5
- // ------ Names --------------------------------
5
+ // ====== Names ======================================
6
6
7
7
trait Name
8
8
trait PossiblySignedName
@@ -23,45 +23,62 @@ object definitions {
23
23
24
24
case class TypeName (name : TermName ) extends Name
25
25
26
- // ------ Positions ---------------------------
26
+ // ====== Positions ==================================
27
27
28
- case class Position (firstOffset : Int , lastOffset : Int )
28
+ case class Position (firstOffset : Int , lastOffset : Int , sourceFile : String ) {
29
+ def startLine : Int = ???
30
+ def startColumn : Int = ???
31
+ def endLine : Int = ???
32
+ def endColumn : Int = ???
33
+ }
29
34
30
35
trait Positioned {
31
36
def pos : Position = ???
32
37
}
33
38
39
+ // ====== Trees ======================================
40
+
41
+ trait Tree extends Positioned
42
+
34
43
// ------ Statements ---------------------------------
35
44
36
- sealed trait TopLevelStatement extends Positioned
45
+ sealed trait TopLevelStatement extends Tree
37
46
sealed trait Statement extends TopLevelStatement
38
47
39
- case class Package (pkg : Term , body : List [TopLevelStatement ]) extends TopLevelStatement
48
+ case class PackageClause (pkg : Term , body : List [TopLevelStatement ]) extends TopLevelStatement
40
49
41
50
case class Import (expr : Term , selector : List [ImportSelector ]) extends Statement
42
51
43
52
enum ImportSelector {
44
- case Simple (id : Id )
45
- case Rename (id1 : Id , id2 : Id )
46
- case Omit (id1 : Id )
53
+ case SimpleSelector (id : Id )
54
+ case RenameSelector (id1 : Id , id2 : Id )
55
+ case OmitSelector (id1 : Id )
47
56
}
48
57
49
58
case class Id (name : String ) extends Positioned // untyped ident
50
59
51
60
// ------ Definitions ---------------------------------
52
61
53
- trait Definition extends Statement {
54
- def name : Name
62
+ trait Definition {
55
63
def owner : Definition = ???
56
64
}
57
65
58
- case class ValDef (name : TermName , tpt : Term , rhs : Option [Term ], mods : List [Modifier ]) extends Definition
66
+ // Does DefDef need a `def tpe: MethodType | PolyType`?
67
+ case class ValDef (name : TermName , tpt : TypeTree , rhs : Option [Term ]) extends Definition {
68
+ def mods : List [Modifier ] = ???
69
+ }
59
70
case class DefDef (name : TermName , typeParams : List [TypeDef ], paramss : List [List [ValDef ]],
60
- returnTpt : Term , rhs : Option [Term ], mods : List [Modifier ]) extends Definition
61
- case class TypeDef (name : TypeName , rhs : Term , mods : List [Modifier ]) extends Definition
62
- case class ClassDef (name : TypeName , constructor : DefDef , parents : List [Term ],
63
- self : Option [ValDef ], body : List [Statement ], mods : List [Modifier ]) extends Definition
64
-
71
+ returnTpt : TypeTree , rhs : Option [Term ]) extends Definition {
72
+ def mods : List [Modifier ] = ???
73
+ }
74
+ case class TypeDef (name : TypeName , rhs : TypeTree | TypeBoundsTree ) extends Definition {
75
+ def mods : List [Modifier ] = ???
76
+ }
77
+ case class ClassDef (name : TypeName , constructor : DefDef , parents : List [Term | TypeTree ],
78
+ self : Option [ValDef ], body : List [Statement ]) extends Definition {
79
+ def mods : List [Modifier ] = ???
80
+ }
81
+ case class PackageDef (name : TermName , members : List [Statement ]) extends Definition
65
82
66
83
// ------ Terms ---------------------------------
67
84
@@ -92,35 +109,39 @@ object definitions {
92
109
}
93
110
94
111
/** Trees denoting types */
95
- enum TypeTree extends Positioned {
112
+ enum TypeTree extends Tree {
96
113
def tpe : Type = ???
97
114
case Synthetic ()
98
115
case Ident (name : TypeName , override val tpe : Type )
99
116
case Select (prefix : Term , name : TypeName )
100
117
case Singleton (ref : Term )
101
118
case Refined (underlying : TypeTree , refinements : List [Definition ])
102
119
case Applied (tycon : TypeTree , args : List [TypeTree ])
103
- case TypeBounds (loBound : TypeTree , hiBound : TypeTree )
104
120
case Annotated (tpt : TypeTree , annotation : Term )
105
121
case And (left : TypeTree , right : TypeTree )
106
122
case Or (left : TypeTree , right : TypeTree )
107
123
case ByName (tpt : TypeTree )
108
124
}
109
125
126
+ /** Trees denoting type bounds*/
127
+ case class TypeBoundsTree (loBound : TypeTree , hiBound : TypeTree ) extends Tree {
128
+ def tpe : Type .TypeBounds = ???
129
+ }
130
+
110
131
/** Trees denoting patterns */
111
- enum Pattern extends Positioned {
132
+ enum Pattern extends Tree {
112
133
def tpe : Type = ???
113
134
case Value (v : Term )
114
135
case Bind (name : TermName , pat : Pattern )
115
136
case Unapply (unapply : Term , implicits : List [Term ], pats : List [Pattern ])
116
137
case Alternative (pats : List [Pattern ])
117
138
case TypeTest (tpt : TypeTree )
118
- case Wildcard ()
119
139
}
120
140
121
- case class CaseDef (pat : Pattern , guard : Option [Term ], rhs : Term ) extends Positioned
141
+ /** Tree denoting pattern match case */
142
+ case class CaseDef (pat : Pattern , guard : Option [Term ], rhs : Term ) extends Tree
122
143
123
- // ------ Types ---------------------------------
144
+ // ====== Types ======================================
124
145
125
146
sealed trait Type
126
147
@@ -138,6 +159,7 @@ object definitions {
138
159
case class OrType (left : Type , right : Type ) extends Type
139
160
case class ByNameType (underlying : Type ) extends Type
140
161
case class ParamRef (binder : LambdaType [_, _, _], idx : Int ) extends Type
162
+ case class ThisType (tp : Type ) extends Type
141
163
case class RecursiveThis (binder : RecursiveType ) extends Type
142
164
143
165
case class RecursiveType private (private var _underlying : Type ) extends Type {
@@ -198,43 +220,56 @@ object definitions {
198
220
object ErasedImplicitMethodType extends SpecializedMethodTypeCompanion
199
221
200
222
case class TypeBounds (loBound : Type , hiBound : Type )
223
+
201
224
case class NoPrefix ()
202
225
object NoPrefix extends NoPrefix
203
226
}
204
227
205
- // ------ Modifiers ---------------------------------
206
-
207
- enum Modifier extends Positioned {
208
- case Private , Protected , Abstract , Final , Sealed , Case , Implicit , Erased , Lazy , Override , Inline ,
209
- Macro , // inline method containing toplevel splices
210
- Static , // mapped to static Java member
211
- Object , // an object or its class (used for a ValDef or a ClassDef, respectively)
212
- Trait , // a trait (used for a ClassDef)
213
- Local , // used in conjunction with Private/private[Type] to mean private[this], proctected[this]
214
- Synthetic , // generated by Scala compiler
215
- Artifact , // to be tagged Java Synthetic
216
- Mutable , // when used on a ValDef: a var
217
- Label , // method generated as a label
218
- FieldAccessor , // a getter or setter
219
- CaseAcessor , // getter for case class parameter
220
- Covariant , // type parameter marked “+”
221
- Contravariant , // type parameter marked “-”
222
- Scala2X , // Imported from Scala2.x
223
- DefaultParameterized , // Method with default parameters
224
- Stable // Method that is assumed to be stable
228
+ // ====== Modifiers ==================================
229
+
225
230
231
+ enum Modifier {
232
+ case Flags (flags : FlagSet )
226
233
case QualifiedPrivate (boundary : Type )
227
234
case QualifiedProtected (boundary : Type )
228
235
case Annotation (tree : Term )
229
236
}
230
237
231
- // ------ Constants ---------------------------------
238
+ trait FlagSet {
239
+ def isProtected : Boolean
240
+ def isAbstract : Boolean
241
+ def isFinal : Boolean
242
+ def isSealed : Boolean
243
+ def isCase : Boolean
244
+ def isImplicit : Boolean
245
+ def isErased : Boolean
246
+ def isLazy : Boolean
247
+ def isOverride : Boolean
248
+ def isInline : Boolean
249
+ def isMacro : Boolean // inline method containing toplevel splices
250
+ def isStatic : Boolean // mapped to static Java member
251
+ def isObject : Boolean // an object or its class (used for a ValDef or a ClassDef extends Modifier respectively)
252
+ def isTrait : Boolean // a trait (used for a ClassDef)
253
+ def isLocal : Boolean // used in conjunction with Private/private[Type] to mean private[this] extends Modifier proctected[this]
254
+ def isSynthetic : Boolean // generated by Scala compiler
255
+ def isArtifact : Boolean // to be tagged Java Synthetic
256
+ def isMutable : Boolean // when used on a ValDef: a var
257
+ def isLabel : Boolean // method generated as a label
258
+ def isFieldAccessor : Boolean // a getter or setter
259
+ def isCaseAcessor : Boolean // getter for class parameter
260
+ def isCovariant : Boolean // type parameter marked “+”
261
+ def isContravariant : Boolean // type parameter marked “-”
262
+ def isScala2X : Boolean // Imported from Scala2.x
263
+ def isDefaultParameterized : Boolean // Method with default parameters
264
+ def isStable : Boolean // Method that is assumed to be stable
265
+ }
266
+
267
+ // ====== Constants ==================================
232
268
233
269
enum Constant (val value : Any ) {
234
270
case Unit extends Constant (())
235
- case False extends Constant (false )
236
- case True extends Constant (true )
237
271
case Null extends Constant (null )
272
+ case Boolean (v : scala.Boolean ) extends Constant (v)
238
273
case Byte (v : scala.Byte ) extends Constant (v)
239
274
case Short (v : scala.Short ) extends Constant (v)
240
275
case Char (v : scala.Char ) extends Constant (v)
@@ -247,3 +282,170 @@ object definitions {
247
282
case Enum (v : Type ) extends Constant (v)
248
283
}
249
284
}
285
+
286
+ // --- A sample extractor ------------------
287
+
288
+ // The abstract class, that's what we export to macro users
289
+ abstract class Tasty {
290
+
291
+ type Type
292
+ trait AbstractType {
293
+ // exported type fields
294
+ }
295
+ implicit def TypeDeco (x : Type ): AbstractType
296
+
297
+ type Symbol
298
+ trait AbstractSymbol {
299
+ // exported symbol fields
300
+ }
301
+ implicit def SymbolDeco (s : Symbol ): AbstractSymbol
302
+
303
+ type Context
304
+ trait AbstractContext {
305
+ val owner : Symbol
306
+ // more exported fields
307
+ }
308
+ implicit def ContextDeco (x : Context ): AbstractContext
309
+
310
+ type Position
311
+ trait AbstractPosition {
312
+ val start : Int
313
+ val end : Int
314
+ // more fields
315
+ }
316
+ implicit def PositionDeco (p : Position ): AbstractPosition
317
+
318
+ trait TypedPositioned {
319
+ val pos : Position
320
+ val tpe : Type
321
+ }
322
+
323
+ type Pattern
324
+ implicit def PatternDeco (p : Pattern ): TypedPositioned
325
+
326
+ type Term
327
+ implicit def TermDeco (t : Term ): TypedPositioned
328
+
329
+ type CaseDef
330
+ implicit def CaseDefDeco (c : CaseDef ): TypedPositioned
331
+
332
+ val CaseDef : CaseDefExtractor
333
+ abstract class CaseDefExtractor {
334
+ def apply (pat : Pattern , guard : Term , rhs : Term )(implicit ctx : Context ): CaseDef
335
+ def unapply (x : CaseDef ): Some [(Pattern , Term , Term )]
336
+ }
337
+ // and analogously for all other concrete trees, patterns, types, etc
338
+ }
339
+
340
+ // The concrete implementation - hidden from users.
341
+ object TastyImpl extends Tasty {
342
+ import definitions ._
343
+ import dotty .tools .dotc ._
344
+ import ast .tpd
345
+ import core .{Types , Symbols , Contexts }
346
+ import util .{Positions }
347
+
348
+ type Type = Types .Type
349
+ implicit class TypeDeco (x : Type ) extends AbstractType {}
350
+
351
+ type Symbol = Symbols .Symbol
352
+ implicit class SymbolDeco (s : Symbol ) extends AbstractSymbol {}
353
+
354
+ type Context = Contexts .Context
355
+ implicit class ContextDeco (c : Context ) extends AbstractContext {
356
+ val owner = c.owner
357
+ }
358
+
359
+ type Position = Positions .Position
360
+ implicit class PositionDeco (p : Position ) extends AbstractPosition {
361
+ val start = p.start
362
+ val end = p.end
363
+ }
364
+
365
+ type Pattern = tpd.Tree
366
+ implicit class PatternDeco (p : Pattern ) extends TypedPositioned {
367
+ val pos = p.pos
368
+ val tpe = p.tpe
369
+ }
370
+
371
+ type Term = tpd.Tree
372
+ implicit class TermDeco (t : Term ) extends TypedPositioned {
373
+ val pos = t.pos
374
+ val tpe = t.tpe
375
+ }
376
+
377
+ type CaseDef = tpd.CaseDef
378
+ implicit class CaseDefDeco (c : CaseDef ) extends TypedPositioned {
379
+ val pos = c.pos
380
+ val tpe = c.tpe
381
+ }
382
+
383
+ object CaseDef extends CaseDefExtractor {
384
+ def apply (pat : Pattern , guard : Term , rhs : Term )(implicit ctx : Context ): CaseDef =
385
+ tpd.CaseDef (pat, guard, rhs)
386
+ def unapply (x : CaseDef ): Some [(Pattern , Term , Term )] =
387
+ Some ((x.pat, x.guard, x.body))
388
+ }
389
+ }
390
+
391
+ /* Dependencies:
392
+
393
+ the reflect library (which is probably part of stdlib) contains a
394
+
395
+ val tasty: Tasty
396
+
397
+ this val is implemented reflectively, loading TastyImpl on demand. TastyImpl in turn
398
+ depends on `tools.dotc`.
399
+
400
+ */
401
+
402
+
403
+ /* If the dotty implementations all inherit the ...Abstract traits,
404
+ and the Abstract traits inherit thmeselves from ProductN, we can
405
+ also do the following, faster implementation.
406
+ This still does full information hiding, but should be almost
407
+ as fast as native access.
408
+
409
+ object TastyImpl extends TastyAST {
410
+ import definitions._
411
+ import dotty.tools.dotc._
412
+ import ast.tpd
413
+ import core.{Types, Symbols, Contexts}
414
+ import util.{Positions}
415
+
416
+ type Type = Types.Type
417
+ implicit def TypeDeco(x: Type) = x
418
+
419
+ type Symbol = Symbols.Symbol
420
+ implicit def SymbolDeco(s: Symbol) = s
421
+
422
+ type Context = Contexts.Context
423
+ implicit def ContextDeco(c: Context) = c
424
+
425
+ type Position = Positions.Position
426
+ implicit def PositionDeco(p: Position) = p
427
+
428
+ type Pattern = tpd.Tree
429
+ implicit def PatternDeco(p: Pattern) = p
430
+
431
+ type Term = tpd.Tree
432
+ implicit def TermDeco(t: Term) = t
433
+
434
+ type CaseDef = tpd.CaseDef
435
+ implicit def CaseDefDeco(c: CaseDef) = c
436
+
437
+ object CaseDef extends CaseDefExtractor {
438
+ def apply(pat: Pattern, guard: Term, rhs: Term)(implicit ctx: Context): CaseDef =
439
+ tpd.CaseDef(pat, guard, rhs)
440
+ def unapply(x: CaseDef): AbstractCaseDef = x
441
+ }
442
+ }
443
+
444
+ This approach is fast because all accesses work without boxing. But there are also downsides:
445
+
446
+ 1. The added reflect supertypes for the dotty types might have a negative performance
447
+ impact for normal compilation.
448
+
449
+ 2. There would be an added dependency from compiler to reflect library, which
450
+ complicates things.
451
+ */
0 commit comments