Skip to content

Commit 0e31883

Browse files
Merge pull request #4270 from dotty-staging/tasty-adt
Tasty Reflection
2 parents a23ae50 + 7e201e2 commit 0e31883

File tree

3 files changed

+322
-15
lines changed

3 files changed

+322
-15
lines changed

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2862,15 +2862,16 @@ object Types {
28622862

28632863
type This = MethodType
28642864

2865+
val paramInfos = paramInfosExp(this)
2866+
val resType = resultTypeExp(this)
2867+
assert(resType.exists)
2868+
28652869
def companion: MethodTypeCompanion
28662870

28672871
final override def isJavaMethod: Boolean = companion eq JavaMethodType
28682872
final override def isImplicitMethod: Boolean = companion.eq(ImplicitMethodType) || companion.eq(ErasedImplicitMethodType)
28692873
final override def isErasedMethod: Boolean = companion.eq(ErasedMethodType) || companion.eq(ErasedImplicitMethodType)
28702874

2871-
val paramInfos = paramInfosExp(this)
2872-
val resType = resultTypeExp(this)
2873-
assert(resType.exists)
28742875

28752876
def computeSignature(implicit ctx: Context): Signature = {
28762877
val params = if (isErasedMethod) Nil else paramInfos

compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,10 @@ Standard-Section: "ASTs" TopLevelStat*
5656
Stat
5757
5858
Stat = Term
59-
VALDEF Length NameRef Type rhs_Term? Modifier*
60-
DEFDEF Length NameRef TypeParam* Params* return_Type rhs_Term?
59+
VALDEF Length NameRef type_Term rhs_Term? Modifier*
60+
DEFDEF Length NameRef TypeParam* Params* returnType_Term rhs_Term?
6161
Modifier*
62-
TYPEDEF Length NameRef (Type | Template) Modifier*
62+
TYPEDEF Length NameRef (type_Term | Template) Modifier*
6363
IMPORT Length qual_Term Selector*
6464
Selector = IMPORTED name_NameRef
6565
RENAMED to_NameRef
@@ -69,20 +69,19 @@ Standard-Section: "ASTs" TopLevelStat*
6969
TypeParam = TYPEPARAM Length NameRef Type Modifier*
7070
Params = PARAMS Length Param*
7171
Param = PARAM Length NameRef Type rhs_Term? Modifier* // rhs_Term is present in the case of an aliased class parameter
72-
Template = TEMPLATE Length TypeParam* Param* Parent* Self? Stat* // Stat* always starts with the primary constructor.
73-
Parent = Application
74-
Type
72+
Template = TEMPLATE Length TypeParam* Param* parent_Term* Self? Stat* // Stat* always starts with the primary constructor.
7573
Self = SELFDEF selfName_NameRef selfType_Type
7674
7775
Term = Path
78-
Application
7976
IDENT NameRef Type // used when term ident’s type is not a TermRef
8077
SELECT possiblySigned_NameRef qual_Term
8178
QUALTHIS typeIdent_Tree
82-
NEW cls_Type
79+
NEW clsType_Term
8380
NAMEDARG paramName_NameRef arg_Term
81+
APPLY Length fn_Term arg_Term*
82+
TYPEAPPLY Length fn_Term arg_Type*
8483
SUPER Length this_Term mixinTypeIdent_Tree?
85-
TYPED Length expr_Term ascription_Type
84+
TYPED Length expr_Term ascriptionType_Tern
8685
ASSIGN Length lhs_Term rhs_Term
8786
BLOCK Length expr_Term Stat*
8887
INLINED Length call_Term expr_Term Stat*
@@ -98,7 +97,7 @@ Standard-Section: "ASTs" TopLevelStat*
9897
UNAPPLY Length fun_Term ImplicitArg* pat_Type pat_Term*
9998
IDENTtpt NameRef Type // used for all type idents
10099
SELECTtpt NameRef qual_Term
101-
SINGLETONtpt Path
100+
SINGLETONtpt ref_Term
102101
REFINEDtpt Length underlying_Term refinement_Stat*
103102
APPLIEDtpt Length tycon_Term arg_Term*
104103
POLYtpt Length TypeParam* body_Term
@@ -110,9 +109,7 @@ Standard-Section: "ASTs" TopLevelStat*
110109
EMPTYTREE
111110
SHAREDterm term_ASTRef
112111
HOLE Length idx_Nat arg_Tree*
113-
Application = APPLY Length fn_Term arg_Term*
114112
115-
TYPEAPPLY Length fn_Term arg_Type*
116113
CaseDef = CASEDEF Length pat_Term rhs_Tree guard_Tree?
117114
ImplicitArg = IMPLICITARG arg_Term
118115
ASTRef = Nat // byte position in AST payload
@@ -179,6 +176,7 @@ Standard-Section: "ASTs" TopLevelStat*
179176
SEALED
180177
CASE
181178
IMPLICIT
179+
ERASED
182180
LAZY
183181
OVERRIDE
184182
INLINE // inline method

tests/pos/TastyADT.scala

Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
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

Comments
 (0)