@@ -2,7 +2,7 @@ package tasty
22
33object definitions {
44
5- // ------ Names --------------------------------
5+ // ====== Names ======================================
66
77 trait Name
88 trait PossiblySignedName
@@ -23,45 +23,62 @@ object definitions {
2323
2424 case class TypeName (name : TermName ) extends Name
2525
26- // ------ Positions ---------------------------
26+ // ====== Positions ==================================
2727
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+ }
2934
3035 trait Positioned {
3136 def pos : Position = ???
3237 }
3338
39+ // ====== Trees ======================================
40+
41+ trait Tree extends Positioned
42+
3443// ------ Statements ---------------------------------
3544
36- sealed trait TopLevelStatement extends Positioned
45+ sealed trait TopLevelStatement extends Tree
3746 sealed trait Statement extends TopLevelStatement
3847
39- case class Package (pkg : Term , body : List [TopLevelStatement ]) extends TopLevelStatement
48+ case class PackageClause (pkg : Term , body : List [TopLevelStatement ]) extends TopLevelStatement
4049
4150 case class Import (expr : Term , selector : List [ImportSelector ]) extends Statement
4251
4352 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 )
4756 }
4857
4958 case class Id (name : String ) extends Positioned // untyped ident
5059
5160// ------ Definitions ---------------------------------
5261
53- trait Definition extends Statement {
54- def name : Name
62+ trait Definition {
5563 def owner : Definition = ???
5664 }
5765
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+ }
5970 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
6582
6683// ------ Terms ---------------------------------
6784
@@ -91,35 +108,39 @@ object definitions {
91108 }
92109
93110 /** Trees denoting types */
94- enum TypeTree extends Positioned {
111+ enum TypeTree extends Tree {
95112 def tpe : Type = ???
96113 case Synthetic ()
97114 case Ident (name : TypeName , override val tpe : Type )
98115 case Select (prefix : Term , name : TypeName )
99116 case Singleton (ref : Term )
100117 case Refined (underlying : TypeTree , refinements : List [Definition ])
101118 case Applied (tycon : TypeTree , args : List [TypeTree ])
102- case TypeBounds (loBound : TypeTree , hiBound : TypeTree )
103119 case Annotated (tpt : TypeTree , annotation : Term )
104120 case And (left : TypeTree , right : TypeTree )
105121 case Or (left : TypeTree , right : TypeTree )
106122 case ByName (tpt : TypeTree )
107123 }
108124
125+ /** Trees denoting type bounds*/
126+ case class TypeBoundsTree (loBound : TypeTree , hiBound : TypeTree ) extends Tree {
127+ def tpe : Type .TypeBounds = ???
128+ }
129+
109130 /** Trees denoting patterns */
110- enum Pattern extends Positioned {
131+ enum Pattern extends Tree {
111132 def tpe : Type = ???
112133 case Value (v : Term )
113134 case Bind (name : TermName , pat : Pattern )
114135 case Unapply (unapply : Term , implicits : List [Term ], pats : List [Pattern ])
115136 case Alternative (pats : List [Pattern ])
116137 case TypeTest (tpt : TypeTree )
117- case Wildcard ()
118138 }
119139
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
121142
122- // ------ Types ---------------------------------
143+ // ====== Types ======================================
123144
124145 sealed trait Type
125146
@@ -137,6 +158,7 @@ object definitions {
137158 case class OrType (left : Type , right : Type ) extends Type
138159 case class ByNameType (underlying : Type ) extends Type
139160 case class ParamRef (binder : LambdaType [_, _, _], idx : Int ) extends Type
161+ case class ThisType (tp : Type ) extends Type
140162 case class RecursiveThis (binder : RecursiveType ) extends Type
141163
142164 case class RecursiveType private (private var _underlying : Type ) extends Type {
@@ -197,43 +219,56 @@ object definitions {
197219 object ErasedImplicitMethodType extends SpecializedMethodTypeCompanion
198220
199221 case class TypeBounds (loBound : Type , hiBound : Type )
222+
200223 case class NoPrefix ()
201224 object NoPrefix extends NoPrefix
202225 }
203226
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+
224229
230+ enum Modifier {
231+ case Flags (flags : FlagSet )
225232 case QualifiedPrivate (boundary : Type )
226233 case QualifiedProtected (boundary : Type )
227234 case Annotation (tree : Term )
228235 }
229236
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 ==================================
231267
232268 enum Constant (val value : Any ) {
233269 case Unit extends Constant (())
234- case False extends Constant (false )
235- case True extends Constant (true )
236270 case Null extends Constant (null )
271+ case Boolean (v : scala.Boolean ) extends Constant (v)
237272 case Byte (v : scala.Byte ) extends Constant (v)
238273 case Short (v : scala.Short ) extends Constant (v)
239274 case Char (v : scala.Char ) extends Constant (v)
@@ -246,3 +281,170 @@ object definitions {
246281 case Enum (v : Type ) extends Constant (v)
247282 }
248283}
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