From 96e7a3635c63d6f9a55f56e7e4980b734767e15d Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 6 Apr 2018 17:27:16 +0200 Subject: [PATCH 1/4] Tasty Reflection As a first step towards a reflective macro system based on Tasty, a high-level view of what tasty trees are. So far omitted are positions and how to compute types. This first commit should serve ad a blueprint for an extractor-based approach that connects to the underling trees. --- .../src/dotty/tools/dotc/core/Types.scala | 7 +- .../tools/dotc/core/tasty/TastyFormat.scala | 22 +- tests/pos/TastyADT.scala | 276 ++++++++++++++++++ 3 files changed, 290 insertions(+), 15 deletions(-) create mode 100644 tests/pos/TastyADT.scala diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index c30f711c6096..1c98582d5259 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -2862,15 +2862,16 @@ object Types { type This = MethodType + val paramInfos = paramInfosExp(this) + val resType = resultTypeExp(this) + assert(resType.exists) + def companion: MethodTypeCompanion final override def isJavaMethod: Boolean = companion eq JavaMethodType final override def isImplicitMethod: Boolean = companion.eq(ImplicitMethodType) || companion.eq(ErasedImplicitMethodType) final override def isErasedMethod: Boolean = companion.eq(ErasedMethodType) || companion.eq(ErasedImplicitMethodType) - val paramInfos = paramInfosExp(this) - val resType = resultTypeExp(this) - assert(resType.exists) def computeSignature(implicit ctx: Context): Signature = { val params = if (isErasedMethod) Nil else paramInfos diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala index f082765d6cb7..c320675d281d 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala @@ -56,10 +56,10 @@ Standard-Section: "ASTs" TopLevelStat* Stat Stat = Term - VALDEF Length NameRef Type rhs_Term? Modifier* - DEFDEF Length NameRef TypeParam* Params* return_Type rhs_Term? + VALDEF Length NameRef type_Term rhs_Term? Modifier* + DEFDEF Length NameRef TypeParam* Params* returnType_Term rhs_Term? Modifier* - TYPEDEF Length NameRef (Type | Template) Modifier* + TYPEDEF Length NameRef (type_Term | Template) Modifier* IMPORT Length qual_Term Selector* Selector = IMPORTED name_NameRef RENAMED to_NameRef @@ -69,20 +69,19 @@ Standard-Section: "ASTs" TopLevelStat* TypeParam = TYPEPARAM Length NameRef Type Modifier* Params = PARAMS Length Param* Param = PARAM Length NameRef Type rhs_Term? Modifier* // rhs_Term is present in the case of an aliased class parameter - Template = TEMPLATE Length TypeParam* Param* Parent* Self? Stat* // Stat* always starts with the primary constructor. - Parent = Application - Type + Template = TEMPLATE Length TypeParam* Param* parent_Term* Self? Stat* // Stat* always starts with the primary constructor. Self = SELFDEF selfName_NameRef selfType_Type Term = Path - Application IDENT NameRef Type // used when term ident’s type is not a TermRef SELECT possiblySigned_NameRef qual_Term QUALTHIS typeIdent_Tree - NEW cls_Type + NEW clsType_Term NAMEDARG paramName_NameRef arg_Term + APPLY Length fn_Term arg_Term* + TYPEAPPLY Length fn_Term arg_Type* SUPER Length this_Term mixinTypeIdent_Tree? - TYPED Length expr_Term ascription_Type + TYPED Length expr_Term ascriptionType_Tern ASSIGN Length lhs_Term rhs_Term BLOCK Length expr_Term Stat* INLINED Length call_Term expr_Term Stat* @@ -98,7 +97,7 @@ Standard-Section: "ASTs" TopLevelStat* UNAPPLY Length fun_Term ImplicitArg* pat_Type pat_Term* IDENTtpt NameRef Type // used for all type idents SELECTtpt NameRef qual_Term - SINGLETONtpt Path + SINGLETONtpt ref_Term REFINEDtpt Length underlying_Term refinement_Stat* APPLIEDtpt Length tycon_Term arg_Term* POLYtpt Length TypeParam* body_Term @@ -110,9 +109,7 @@ Standard-Section: "ASTs" TopLevelStat* EMPTYTREE SHAREDterm term_ASTRef HOLE Length idx_Nat arg_Tree* - Application = APPLY Length fn_Term arg_Term* - TYPEAPPLY Length fn_Term arg_Type* CaseDef = CASEDEF Length pat_Term rhs_Tree guard_Tree? ImplicitArg = IMPLICITARG arg_Term ASTRef = Nat // byte position in AST payload @@ -179,6 +176,7 @@ Standard-Section: "ASTs" TopLevelStat* SEALED CASE IMPLICIT + ERASED LAZY OVERRIDE INLINE // inline method diff --git a/tests/pos/TastyADT.scala b/tests/pos/TastyADT.scala new file mode 100644 index 000000000000..206cfc439b93 --- /dev/null +++ b/tests/pos/TastyADT.scala @@ -0,0 +1,276 @@ +object tasty { + + trait PossiblySignedName + + enum Name extends PossiblySignedName { + case Simple(str: String) + case Qualified(prefix: Name, selector: String) // s"$prefix.$name" + case Unique(underlying: Name, separator: String, idx: Int) // s"$underlying$separator$idx" + case DefaultGetter(methodName: Name, idx: String) // s"$methodName${"$default$"}${idx+1}" + case Variant(underlying: Name, covariant: Boolean) // s"${if (covariant) "+" else "-"}$underlying" + case SuperAccessor(underlying: Name) // s"${"super$"}$underlying" + case ProtectedAccessor(underlying: Name) // s"${"protectded$"}$underlying" + case ProtectedSetter(underlying: Name) // s"${"protectded$set"}$underlying" + case ObjectClass(underlying: Name) // s"$underlying${"$"}" + + case Expanded(prefix: Name, selector: String) // s"$prefix${"$$"}$name" , used only for symbols coming from Scala 2 + case ExpandedPrefix(prefix: Name, selector: String) // s"$prefix${"$"}$name" , used only for symbols coming from Scala 2 + } + + case class SignedName(name: Name, resultSig: Name, paramSigs: List[Name]) extends PossiblySignedName + + trait TopLevelStatement + + trait Statement extends TopLevelStatement + + case class Package(pkg: Term, body: List[TopLevelStatement]) extends TopLevelStatement + + trait Definition extends Statement { + def tpe: Type = Type.SymRef(this, ???) + } + + class ValDef( + val name: Name, + val tpt: Term, + rhsExp: ValDef => Term | Empty, + val mods: List[Modifier]) + extends Definition { + lazy val rhs = rhsExp(this) + } + object ValDef { + def apply(name: Name, tpt: Term, rhs: Term | Empty, mods: List[Modifier] = Nil) = + new ValDef(name, tpt, _ => rhs, mods) + def unapply(vdef: ValDef) = Some((vdef.name, vdef.tpt, vdef.rhs, vdef.mods)) + } + + class DefDef( + val name: Name, + typeParamsExp: DefDef => List[TypeDef], + paramssExp: DefDef => List[List[ValDef]], + returnTptExp: DefDef => Term, + rhsExp: DefDef => Term | Empty, + val mods: List[Modifier]) + extends Definition { + val typeParams = typeParamsExp(this) + val paramss = paramssExp(this) + val returnTpt = returnTptExp(this) + lazy val rhs = rhsExp(this) + } + object DefDef { + def apply(name: Name, typeParams: List[TypeDef], paramss: List[List[ValDef]], returnTpt: Term, rhs: Term | Empty, mods: List[Modifier] = Nil) = + new DefDef(name, _ => typeParams, _ => paramss, _ => returnTpt, _ => rhs, mods) + def unapply(ddef: DefDef) = Some((ddef.name, ddef.typeParams, ddef.paramss, ddef.returnTpt, ddef.rhs)) + } + + class TypeDef( + val name: Name, + rhsExp: TypeDef => Term, + val mods: List[Modifier]) + extends Definition { + val rhs = rhsExp(this), + } + object TypeDef { + def apply(name: Name, rhs: Term, mods: List[Modifier] = Nil) = new TypeDef(name, _ => rhs, mods) + def unapply(tdef: TypeDef) = Some((tdef.name, tdef.rhs)) + } + + class ClassDef( + val name: Name, + rhsExp: ClassDef => Template, + val mods: List[Modifier]) + extends Definition { + val rhs = rhsExp(this) + } + object ClassDef { + def apply(name: Name, rhs: Template, mods: List[Modifier] = Nil) = new ClassDef(name, _ => rhs, mods) + def unapply(tdef: ClassDef) = Some((tdef.name, tdef.rhs)) + } + + case class Template( + typeParams: List[TypeDef], + paramss: List[List[ValDef]], + parents: List[Term], + self: ValDef | Empty, + body: List[Statement]) + + case class Import(expr: Term, selector: List[ImportSelector]) + + enum ImportSelector { + case Simple(id: Id) + case Rename(id1: Id, id2: Id) + case Omit(id1: Id) + } + + case class Id(name: Name) // untyped ident + + enum Term { + def tpe: Type = ??? + case Ident(name: Name, override val tpe: Type) + case Select(prefix: Term, name: PossiblySignedName) + case Literal(value: Constant) + case This(id: Id | Empty) + case New(tpt: Term) + case NamedArg(name: Name, arg: Term) + case Apply(fn: Term, args: List[Term]) + case TypeApply(fn: Term, args: List[Term]) + case Super(thiz: Term, mixin: Id | Empty) + case Typed(expr: Term, tpt: Term) + case Assign(lhs: Term, rhs: Term) + case Block(stats: List[Statement], expr: Term) + case Inlined(call: Term, bindings: List[Definition], expr: Term) + case Lambda(method: Term, tpt: Term | Empty) + case If(cond: Term, thenPart: Term, elsePart: Term) + case Match(scrutinee: Term, cases: List[CaseDef]) + case Try(body: Term, catches: List[CaseDef], finalizer: Term | Empty) + case Return(expr: Term) + case Repeated(args: List[Term]) + case SelectOuter(from: Term, levels: Int, target: Type) // can be generated by inlining + case Tpt(underlying: TypeTerm | Empty) + } + + enum TypeTerm { + def tpe: Type = ??? + case Ident(name: Name, override val tpe: Type) + case Select(prefix: Term, name: Name) + case Singleton(ref: Term) + case Refined(underlying: TypeTerm, refinements: List[Definition]) + case Applied(tycon: TypeTerm, args: List[TypeTerm]) + case TypeBounds(loBound: TypeTerm, hiBound: TypeTerm) + case Annotated(tpt: TypeTerm, annotation: Term) + case And(left: TypeTerm, right: TypeTerm) + case Or(left: TypeTerm, right: TypeTerm) + case ByName(tpt: TypeTerm) + } + + enum Pattern { + def tpe: Type = ??? + case Value(v: Term) + case Bind(name: Name, pat: Pattern) + case Unapply(unapply: Term, implicits: List[Term], pats: List[Pattern]) + case Alternative(pats: List[Pattern]) + case TypeTest(tpt: Term) + case Wildcard() + } + + case class CaseDef(pat: Pattern, guard: Term | Empty, rhs: Term) + + sealed trait Type + + object Type { + case class ConstantType(value: Constant) extends Type + case class SymRef(sym: Definition, qualifier: Type | Empty = Empty) extends Type + case class TypeNameRef(name: Name, qualifier: Type | Empty = Empty) extends Type // Empty means: select from _root_ + case class TermNameRef(name: Name, qualifier: Type | Empty = Empty) extends Type // Empty means: select from _root_ + case class SuperType(thistp: Type, underlying: Type) extends Type + case class TermRefinement(underlying: Type, name: Name, tpe: Type) extends Type + case class TypeRefinement(underlying: Type, name: Name, info: TypeBounds) extends Type + case class AppliedType(tycon: Type, args: Type | TypeBounds) extends Type + case class AnnotatedType(underlying: Type, annotation: Term) extends Type + case class AndType(left: Type, right: Type) extends Type + case class OrType(left: Type, right: Type) extends Type + case class ByNameType(underlying: Type) extends Type + case class ParamRef(binder: LambdaType, idx: Int) extends Type + case class RecThis(binder: RecursiveType) extends Type + + class RecursiveType(underlyingExp: RecursiveType => Type) extends Type { + val underlying = underlyingExp(this) + } + object RecursiveType { + def unapply(tp: RecursiveType): Option[Type] = Some(tp.underlying) + } + + trait LambdaType extends Type { + type ParamInfo + def paramNames: List[Name] + def paramInfos: List[ParamInfo] + def resultType: Type + } + + class MethodType(val paramNames: List[Name], paramTypesExp: MethodType => List[Type], + resultTypeExp: MethodType => Type, val mods: List[Modifier]) extends LambdaType { + type ParamInfo = Type + val paramTypes = paramTypesExp(this) + val resultType = resultTypeExp(this) + def paramInfos = paramTypes + } + object MethodType { + def apply(paramNames: List[Name], paramTypes: List[Type], resultType: Type, mods: List[Modifier] = Nil) = + new MethodType(paramNames, _ => paramTypes, _ => resultType, mods) + def unapply(tp: MethodType) = Some((tp.paramNames, tp.paramTypes, tp.resultType, tp.mods)) + } + + class PolyType(val paramNames: List[Name], paramBoundsExp: PolyType => List[TypeBounds], + resultTypeExp: PolyType => Type) extends LambdaType { + type This = PolyType + type ParamInfo = TypeBounds + val paramBounds = paramBoundsExp(this) + val resultType = resultTypeExp(this) + def paramInfos = paramBounds + } + object PolyType { + def apply(paramNames: List[Name], paramBounds: List[TypeBounds], resultType: Type) = + new PolyType(paramNames, _ => paramBounds, _ => resultType) + def unapply(tp: PolyType) = Some((tp.paramNames, tp.paramBounds, tp.resultType)) + } + + class TypeLambda(val paramNames: List[Name], paramBoundsExp: TypeLambda => List[TypeBounds], + resultTypeExp: TypeLambda => Type) extends LambdaType { + type This = TypeLambda + type ParamInfo = TypeBounds + val paramBounds = paramBoundsExp(this) + val resultType = resultTypeExp(this) + def paramInfos = paramBounds + } + object TypeLambda { + def apply(paramNames: List[Name], paramBounds: List[TypeBounds], resultType: Type) = + new TypeLambda(paramNames, _ => paramBounds, _ => resultType) + def unapply(tp: TypeLambda) = Some((tp.paramNames, tp.paramBounds, tp.resultType)) + } + + case class TypeBounds(loBound: Type, hiBound: Type) + } + + enum Modifier { + case Private, Protected, Abstract, Final, Sealed, Case, Implicit, Erased, Lazy, Override, Inline, + Macro, // inline method containing toplevel splices + Static, // mapped to static Java member + Object, // an object or its class (used for a ValDef or a ClassDef, respectively) + Trait, // a trait (used for a ClassDef) + Local, // used in conjunction with Private/Protected to mean private[this], proctected[this] + Synthetic, // generated by Scala compiler + Artifact, // to be tagged Java Synthetic + Mutable, // when used on a ValDef: a var + Label, // method generated as a label + FieldAccessor, // a getter or setter + CaseAcessor, // getter for case class parameter + Covariant, // type parameter marked “+” + Contravariant, // type parameter marked “-” + Scala2X, // Imported from Scala2.x + DefaultParameterized, // Method with default parameters + Stable // Method that is assumed to be stable + + case QualifiedPrivate(boundary: Type) + case QualifiedProtected(boundary: Type) + case Annotation(tree: Term) + } + + enum Constant(value: Any) { + case Unit extends Constant(()) + case False extends Constant(false) + case True extends Constant(true) + case Null extends Constant(null) + case Byte(value: scala.Byte) extends Constant(value) + case Short(value: scala.Short) extends Constant(value) + case Char(value: scala.Char) extends Constant(value) + case Int(value: scala.Int) extends Constant(value) + case Long(value: scala.Long) extends Constant(value) + case Float(value: scala.Float) extends Constant(value) + case Double(value: scala.Double) extends Constant(value) + case String(value: java.lang.String) extends Constant(value) + case Class(value: Type) extends Constant(value) + case Enum(value: Type) extends Constant(value) + } + + sealed class Empty() + object Empty extends Empty +} \ No newline at end of file From 774270c8b2ca5ecbea44593704e489d0f786ab4a Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 6 Apr 2018 17:38:05 +0200 Subject: [PATCH 2/4] Some polishings Add outline for where positions go. Add some missing extends clauses. Add some mods fields in extractors. --- tests/pos/TastyADT.scala | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/tests/pos/TastyADT.scala b/tests/pos/TastyADT.scala index 206cfc439b93..a08acd6a3fd6 100644 --- a/tests/pos/TastyADT.scala +++ b/tests/pos/TastyADT.scala @@ -19,7 +19,13 @@ object tasty { case class SignedName(name: Name, resultSig: Name, paramSigs: List[Name]) extends PossiblySignedName - trait TopLevelStatement + case class Position(firstOffset: Int, lastOffset: Int) + + trait Positioned { + def pos: Position = ??? + } + + trait TopLevelStatement extends Positioned trait Statement extends TopLevelStatement @@ -59,7 +65,7 @@ object tasty { object DefDef { def apply(name: Name, typeParams: List[TypeDef], paramss: List[List[ValDef]], returnTpt: Term, rhs: Term | Empty, mods: List[Modifier] = Nil) = new DefDef(name, _ => typeParams, _ => paramss, _ => returnTpt, _ => rhs, mods) - def unapply(ddef: DefDef) = Some((ddef.name, ddef.typeParams, ddef.paramss, ddef.returnTpt, ddef.rhs)) + def unapply(ddef: DefDef) = Some((ddef.name, ddef.typeParams, ddef.paramss, ddef.returnTpt, ddef.rhs, ddef.mods)) } class TypeDef( @@ -71,7 +77,7 @@ object tasty { } object TypeDef { def apply(name: Name, rhs: Term, mods: List[Modifier] = Nil) = new TypeDef(name, _ => rhs, mods) - def unapply(tdef: TypeDef) = Some((tdef.name, tdef.rhs)) + def unapply(tdef: TypeDef) = Some((tdef.name, tdef.rhs, tdef.mods)) } class ClassDef( @@ -83,7 +89,7 @@ object tasty { } object ClassDef { def apply(name: Name, rhs: Template, mods: List[Modifier] = Nil) = new ClassDef(name, _ => rhs, mods) - def unapply(tdef: ClassDef) = Some((tdef.name, tdef.rhs)) + def unapply(tdef: ClassDef) = Some((tdef.name, tdef.rhs, tdef.mods)) } case class Template( @@ -93,7 +99,7 @@ object tasty { self: ValDef | Empty, body: List[Statement]) - case class Import(expr: Term, selector: List[ImportSelector]) + case class Import(expr: Term, selector: List[ImportSelector]) extends Statement enum ImportSelector { case Simple(id: Id) @@ -101,9 +107,9 @@ object tasty { case Omit(id1: Id) } - case class Id(name: Name) // untyped ident + case class Id(name: Name) extends Positioned // untyped ident - enum Term { + enum Term extends Statement { def tpe: Type = ??? case Ident(name: Name, override val tpe: Type) case Select(prefix: Term, name: PossiblySignedName) @@ -128,7 +134,7 @@ object tasty { case Tpt(underlying: TypeTerm | Empty) } - enum TypeTerm { + enum TypeTerm extends Positioned { def tpe: Type = ??? case Ident(name: Name, override val tpe: Type) case Select(prefix: Term, name: Name) @@ -142,7 +148,7 @@ object tasty { case ByName(tpt: TypeTerm) } - enum Pattern { + enum Pattern extends Positioned { def tpe: Type = ??? case Value(v: Term) case Bind(name: Name, pat: Pattern) @@ -152,7 +158,7 @@ object tasty { case Wildcard() } - case class CaseDef(pat: Pattern, guard: Term | Empty, rhs: Term) + case class CaseDef(pat: Pattern, guard: Term | Empty, rhs: Term) extends Positioned sealed trait Type @@ -230,7 +236,7 @@ object tasty { case class TypeBounds(loBound: Type, hiBound: Type) } - enum Modifier { + enum Modifier extends Positioned { case Private, Protected, Abstract, Final, Sealed, Case, Implicit, Erased, Lazy, Override, Inline, Macro, // inline method containing toplevel splices Static, // mapped to static Java member From 760f329b5e416674a8fa747192597a885d7578e6 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 6 Apr 2018 17:50:28 +0200 Subject: [PATCH 3/4] Add docs --- tests/pos/TastyADT.scala | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/pos/TastyADT.scala b/tests/pos/TastyADT.scala index a08acd6a3fd6..179ca17c9034 100644 --- a/tests/pos/TastyADT.scala +++ b/tests/pos/TastyADT.scala @@ -1,5 +1,7 @@ object tasty { +// ------ Names -------------------------------- + trait PossiblySignedName enum Name extends PossiblySignedName { @@ -19,12 +21,19 @@ object tasty { case class SignedName(name: Name, resultSig: Name, paramSigs: List[Name]) extends PossiblySignedName +// ------ Positions --------------------------- + case class Position(firstOffset: Int, lastOffset: Int) trait Positioned { def pos: Position = ??? } +// ------ Statements --------------------------------- + +// Note: Definitions are written as extractors, because they may be referred to +// recursively from some of their arguments (since we equate symbols with definitions) + trait TopLevelStatement extends Positioned trait Statement extends TopLevelStatement @@ -109,6 +118,9 @@ object tasty { case class Id(name: Name) extends Positioned // untyped ident +// ------ Terms --------------------------------- + + /** Trees denoting terms */ enum Term extends Statement { def tpe: Type = ??? case Ident(name: Name, override val tpe: Type) @@ -134,6 +146,7 @@ object tasty { case Tpt(underlying: TypeTerm | Empty) } + /** Trees denoting types */ enum TypeTerm extends Positioned { def tpe: Type = ??? case Ident(name: Name, override val tpe: Type) @@ -148,6 +161,7 @@ object tasty { case ByName(tpt: TypeTerm) } + /** Trees denoting patterns */ enum Pattern extends Positioned { def tpe: Type = ??? case Value(v: Term) @@ -162,6 +176,8 @@ object tasty { sealed trait Type +// ------ Types --------------------------------- + object Type { case class ConstantType(value: Constant) extends Type case class SymRef(sym: Definition, qualifier: Type | Empty = Empty) extends Type @@ -178,6 +194,9 @@ object tasty { case class ParamRef(binder: LambdaType, idx: Int) extends Type case class RecThis(binder: RecursiveType) extends Type + // The following types are all expressed by extractors because they may be referred + // to from some of their arguments + class RecursiveType(underlyingExp: RecursiveType => Type) extends Type { val underlying = underlyingExp(this) } @@ -236,6 +255,8 @@ object tasty { case class TypeBounds(loBound: Type, hiBound: Type) } +// ------ Modifiers --------------------------------- + enum Modifier extends Positioned { case Private, Protected, Abstract, Final, Sealed, Case, Implicit, Erased, Lazy, Override, Inline, Macro, // inline method containing toplevel splices @@ -260,6 +281,8 @@ object tasty { case Annotation(tree: Term) } +// ------ Constants --------------------------------- + enum Constant(value: Any) { case Unit extends Constant(()) case False extends Constant(false) From 7e201e286a430dd8c9b796873e69699ae03d880a Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 6 Apr 2018 18:21:29 +0200 Subject: [PATCH 4/4] Split Name into TermName and TypeName Saves some Type classes and is closer to how compilers handle it. --- tests/pos/TastyADT.scala | 83 +++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 40 deletions(-) diff --git a/tests/pos/TastyADT.scala b/tests/pos/TastyADT.scala index 179ca17c9034..933360df01f2 100644 --- a/tests/pos/TastyADT.scala +++ b/tests/pos/TastyADT.scala @@ -2,24 +2,27 @@ object tasty { // ------ Names -------------------------------- + trait Name trait PossiblySignedName - enum Name extends PossiblySignedName { + enum TermName extends Name with PossiblySignedName { case Simple(str: String) - case Qualified(prefix: Name, selector: String) // s"$prefix.$name" - case Unique(underlying: Name, separator: String, idx: Int) // s"$underlying$separator$idx" - case DefaultGetter(methodName: Name, idx: String) // s"$methodName${"$default$"}${idx+1}" - case Variant(underlying: Name, covariant: Boolean) // s"${if (covariant) "+" else "-"}$underlying" - case SuperAccessor(underlying: Name) // s"${"super$"}$underlying" - case ProtectedAccessor(underlying: Name) // s"${"protectded$"}$underlying" - case ProtectedSetter(underlying: Name) // s"${"protectded$set"}$underlying" - case ObjectClass(underlying: Name) // s"$underlying${"$"}" - - case Expanded(prefix: Name, selector: String) // s"$prefix${"$$"}$name" , used only for symbols coming from Scala 2 - case ExpandedPrefix(prefix: Name, selector: String) // s"$prefix${"$"}$name" , used only for symbols coming from Scala 2 + case Qualified(prefix: TermName, selector: String) // s"$prefix.$name" + case Unique(underlying: TermName, separator: String, idx: Int) // s"$underlying$separator$idx" + case DefaultGetter(methodName: TermName, idx: String) // s"$methodName${"$default$"}${idx+1}" + case Variant(underlying: TermName, covariant: Boolean) // s"${if (covariant) "+" else "-"}$underlying" + case SuperAccessor(underlying: TermName) // s"${"super$"}$underlying" + case ProtectedAccessor(underlying: TermName) // s"${"protectded$"}$underlying" + case ProtectedSetter(underlying: TermName) // s"${"protectded$set"}$underlying" + case ObjectClass(underlying: TermName) // s"$underlying${"$"}" + + case Expanded(prefix: TermName, selector: String) // s"$prefix${"$$"}$name" , used only for symbols coming from Scala 2 + case ExpandedPrefix(prefix: TermName, selector: String) // s"$prefix${"$"}$name" , used only for symbols coming from Scala 2 } - case class SignedName(name: Name, resultSig: Name, paramSigs: List[Name]) extends PossiblySignedName + case class SignedName(name: TermName, resultSig: TypeName, paramSigs: List[TypeName]) extends PossiblySignedName + + case class TypeName(name: TermName) extends Name // ------ Positions --------------------------- @@ -45,7 +48,7 @@ object tasty { } class ValDef( - val name: Name, + val name: TermName, val tpt: Term, rhsExp: ValDef => Term | Empty, val mods: List[Modifier]) @@ -53,13 +56,13 @@ object tasty { lazy val rhs = rhsExp(this) } object ValDef { - def apply(name: Name, tpt: Term, rhs: Term | Empty, mods: List[Modifier] = Nil) = + def apply(name: TermName, tpt: Term, rhs: Term | Empty, mods: List[Modifier] = Nil) = new ValDef(name, tpt, _ => rhs, mods) def unapply(vdef: ValDef) = Some((vdef.name, vdef.tpt, vdef.rhs, vdef.mods)) } class DefDef( - val name: Name, + val name: TermName, typeParamsExp: DefDef => List[TypeDef], paramssExp: DefDef => List[List[ValDef]], returnTptExp: DefDef => Term, @@ -72,32 +75,32 @@ object tasty { lazy val rhs = rhsExp(this) } object DefDef { - def apply(name: Name, typeParams: List[TypeDef], paramss: List[List[ValDef]], returnTpt: Term, rhs: Term | Empty, mods: List[Modifier] = Nil) = + def apply(name: TermName, typeParams: List[TypeDef], paramss: List[List[ValDef]], returnTpt: Term, rhs: Term | Empty, mods: List[Modifier] = Nil) = new DefDef(name, _ => typeParams, _ => paramss, _ => returnTpt, _ => rhs, mods) def unapply(ddef: DefDef) = Some((ddef.name, ddef.typeParams, ddef.paramss, ddef.returnTpt, ddef.rhs, ddef.mods)) } class TypeDef( - val name: Name, + val name: TypeName, rhsExp: TypeDef => Term, val mods: List[Modifier]) extends Definition { val rhs = rhsExp(this), } object TypeDef { - def apply(name: Name, rhs: Term, mods: List[Modifier] = Nil) = new TypeDef(name, _ => rhs, mods) + def apply(name: TypeName, rhs: Term, mods: List[Modifier] = Nil) = new TypeDef(name, _ => rhs, mods) def unapply(tdef: TypeDef) = Some((tdef.name, tdef.rhs, tdef.mods)) } class ClassDef( - val name: Name, + val name: TypeName, rhsExp: ClassDef => Template, val mods: List[Modifier]) extends Definition { val rhs = rhsExp(this) } object ClassDef { - def apply(name: Name, rhs: Template, mods: List[Modifier] = Nil) = new ClassDef(name, _ => rhs, mods) + def apply(name: TypeName, rhs: Template, mods: List[Modifier] = Nil) = new ClassDef(name, _ => rhs, mods) def unapply(tdef: ClassDef) = Some((tdef.name, tdef.rhs, tdef.mods)) } @@ -116,19 +119,19 @@ object tasty { case Omit(id1: Id) } - case class Id(name: Name) extends Positioned // untyped ident + case class Id(name: String) extends Positioned // untyped ident // ------ Terms --------------------------------- /** Trees denoting terms */ enum Term extends Statement { def tpe: Type = ??? - case Ident(name: Name, override val tpe: Type) + case Ident(name: TermName, override val tpe: Type) case Select(prefix: Term, name: PossiblySignedName) case Literal(value: Constant) case This(id: Id | Empty) case New(tpt: Term) - case NamedArg(name: Name, arg: Term) + case NamedArg(name: TermName, arg: Term) case Apply(fn: Term, args: List[Term]) case TypeApply(fn: Term, args: List[Term]) case Super(thiz: Term, mixin: Id | Empty) @@ -149,8 +152,8 @@ object tasty { /** Trees denoting types */ enum TypeTerm extends Positioned { def tpe: Type = ??? - case Ident(name: Name, override val tpe: Type) - case Select(prefix: Term, name: Name) + case Ident(name: TypeName, override val tpe: Type) + case Select(prefix: Term, name: TypeName) case Singleton(ref: Term) case Refined(underlying: TypeTerm, refinements: List[Definition]) case Applied(tycon: TypeTerm, args: List[TypeTerm]) @@ -165,7 +168,7 @@ object tasty { enum Pattern extends Positioned { def tpe: Type = ??? case Value(v: Term) - case Bind(name: Name, pat: Pattern) + case Bind(name: TermName, pat: Pattern) case Unapply(unapply: Term, implicits: List[Term], pats: List[Pattern]) case Alternative(pats: List[Pattern]) case TypeTest(tpt: Term) @@ -181,11 +184,9 @@ object tasty { object Type { case class ConstantType(value: Constant) extends Type case class SymRef(sym: Definition, qualifier: Type | Empty = Empty) extends Type - case class TypeNameRef(name: Name, qualifier: Type | Empty = Empty) extends Type // Empty means: select from _root_ - case class TermNameRef(name: Name, qualifier: Type | Empty = Empty) extends Type // Empty means: select from _root_ + case class NameRef(name: Name, qualifier: Type | Empty = Empty) extends Type // Empty means: select from _root_ case class SuperType(thistp: Type, underlying: Type) extends Type - case class TermRefinement(underlying: Type, name: Name, tpe: Type) extends Type - case class TypeRefinement(underlying: Type, name: Name, info: TypeBounds) extends Type + case class Refinement(underlying: Type, name: Name, tpe: Type) extends Type case class AppliedType(tycon: Type, args: Type | TypeBounds) extends Type case class AnnotatedType(underlying: Type, annotation: Term) extends Type case class AndType(left: Type, right: Type) extends Type @@ -205,49 +206,51 @@ object tasty { } trait LambdaType extends Type { + type ParamName type ParamInfo - def paramNames: List[Name] + def paramNames: List[ParamName] def paramInfos: List[ParamInfo] def resultType: Type } - class MethodType(val paramNames: List[Name], paramTypesExp: MethodType => List[Type], + class MethodType(val paramNames: List[TermName], paramTypesExp: MethodType => List[Type], resultTypeExp: MethodType => Type, val mods: List[Modifier]) extends LambdaType { + type ParamName = TermName type ParamInfo = Type val paramTypes = paramTypesExp(this) val resultType = resultTypeExp(this) def paramInfos = paramTypes } object MethodType { - def apply(paramNames: List[Name], paramTypes: List[Type], resultType: Type, mods: List[Modifier] = Nil) = + def apply(paramNames: List[TermName], paramTypes: List[Type], resultType: Type, mods: List[Modifier] = Nil) = new MethodType(paramNames, _ => paramTypes, _ => resultType, mods) def unapply(tp: MethodType) = Some((tp.paramNames, tp.paramTypes, tp.resultType, tp.mods)) } - class PolyType(val paramNames: List[Name], paramBoundsExp: PolyType => List[TypeBounds], + class PolyType(val paramNames: List[TypeName], paramBoundsExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type) extends LambdaType { - type This = PolyType + type ParamName = TypeName type ParamInfo = TypeBounds val paramBounds = paramBoundsExp(this) val resultType = resultTypeExp(this) def paramInfos = paramBounds } object PolyType { - def apply(paramNames: List[Name], paramBounds: List[TypeBounds], resultType: Type) = + def apply(paramNames: List[TypeName], paramBounds: List[TypeBounds], resultType: Type) = new PolyType(paramNames, _ => paramBounds, _ => resultType) def unapply(tp: PolyType) = Some((tp.paramNames, tp.paramBounds, tp.resultType)) } - class TypeLambda(val paramNames: List[Name], paramBoundsExp: TypeLambda => List[TypeBounds], + class TypeLambda(val paramNames: List[TypeName], paramBoundsExp: TypeLambda => List[TypeBounds], resultTypeExp: TypeLambda => Type) extends LambdaType { - type This = TypeLambda + type ParamName = TypeName type ParamInfo = TypeBounds val paramBounds = paramBoundsExp(this) val resultType = resultTypeExp(this) def paramInfos = paramBounds } object TypeLambda { - def apply(paramNames: List[Name], paramBounds: List[TypeBounds], resultType: Type) = + def apply(paramNames: List[TypeName], paramBounds: List[TypeBounds], resultType: Type) = new TypeLambda(paramNames, _ => paramBounds, _ => resultType) def unapply(tp: TypeLambda) = Some((tp.paramNames, tp.paramBounds, tp.resultType)) }