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