@@ -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
@@ -92,35 +109,39 @@ object definitions {
92109 }
93110
94111 /** Trees denoting types */
95- enum TypeTree extends Positioned {
112+ enum TypeTree extends Tree {
96113 def tpe : Type = ???
97114 case Synthetic ()
98115 case Ident (name : TypeName , override val tpe : Type )
99116 case Select (prefix : Term , name : TypeName )
100117 case Singleton (ref : Term )
101118 case Refined (underlying : TypeTree , refinements : List [Definition ])
102119 case Applied (tycon : TypeTree , args : List [TypeTree ])
103- case TypeBounds (loBound : TypeTree , hiBound : TypeTree )
104120 case Annotated (tpt : TypeTree , annotation : Term )
105121 case And (left : TypeTree , right : TypeTree )
106122 case Or (left : TypeTree , right : TypeTree )
107123 case ByName (tpt : TypeTree )
108124 }
109125
126+ /** Trees denoting type bounds*/
127+ case class TypeBoundsTree (loBound : TypeTree , hiBound : TypeTree ) extends Tree {
128+ def tpe : Type .TypeBounds = ???
129+ }
130+
110131 /** Trees denoting patterns */
111- enum Pattern extends Positioned {
132+ enum Pattern extends Tree {
112133 def tpe : Type = ???
113134 case Value (v : Term )
114135 case Bind (name : TermName , pat : Pattern )
115136 case Unapply (unapply : Term , implicits : List [Term ], pats : List [Pattern ])
116137 case Alternative (pats : List [Pattern ])
117138 case TypeTest (tpt : TypeTree )
118- case Wildcard ()
119139 }
120140
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
122143
123- // ------ Types ---------------------------------
144+ // ====== Types ======================================
124145
125146 sealed trait Type
126147
@@ -138,6 +159,7 @@ object definitions {
138159 case class OrType (left : Type , right : Type ) extends Type
139160 case class ByNameType (underlying : Type ) extends Type
140161 case class ParamRef (binder : LambdaType [_, _, _], idx : Int ) extends Type
162+ case class ThisType (tp : Type ) extends Type
141163 case class RecursiveThis (binder : RecursiveType ) extends Type
142164
143165 case class RecursiveType private (private var _underlying : Type ) extends Type {
@@ -198,43 +220,56 @@ object definitions {
198220 object ErasedImplicitMethodType extends SpecializedMethodTypeCompanion
199221
200222 case class TypeBounds (loBound : Type , hiBound : Type )
223+
201224 case class NoPrefix ()
202225 object NoPrefix extends NoPrefix
203226 }
204227
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+
225230
231+ enum Modifier {
232+ case Flags (flags : FlagSet )
226233 case QualifiedPrivate (boundary : Type )
227234 case QualifiedProtected (boundary : Type )
228235 case Annotation (tree : Term )
229236 }
230237
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 ==================================
232268
233269 enum Constant (val value : Any ) {
234270 case Unit extends Constant (())
235- case False extends Constant (false )
236- case True extends Constant (true )
237271 case Null extends Constant (null )
272+ case Boolean (v : scala.Boolean ) extends Constant (v)
238273 case Byte (v : scala.Byte ) extends Constant (v)
239274 case Short (v : scala.Short ) extends Constant (v)
240275 case Char (v : scala.Char ) extends Constant (v)
@@ -247,3 +282,170 @@ object definitions {
247282 case Enum (v : Type ) extends Constant (v)
248283 }
249284}
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