From 57b2afafa7e902c4b3a2f61669b9f11b5d991467 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 3 Dec 2020 14:51:10 +0100 Subject: [PATCH] Add `NameTyped`, `AndOrType`, `LambdaType` and `MethodOrPoly` --- .../quoted/runtime/impl/QuotesImpl.scala | 84 +++++++---- library/src/scala/quoted/Quotes.scala | 135 ++++++++++-------- 2 files changed, 130 insertions(+), 89 deletions(-) diff --git a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala index dd6ef0055cb7..1c0960f72d54 100644 --- a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala +++ b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala @@ -1676,6 +1676,21 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler extension (self: ConstantType) def constant: Constant = self.value end ConstantTypeMethods + type NamedType = dotc.core.Types.NamedType + + object NamedTypeTypeTest extends TypeTest[TypeRepr, NamedType]: + def unapply(x: TypeRepr): Option[NamedType & x.type] = x match + case tpe: (Types.NamedType & x.type) => Some(tpe) + case _ => None + end NamedTypeTypeTest + + given NamedTypeMethods: NamedTypeMethods with + extension (self: NamedType): + def qualifier: TypeRepr = self.prefix + def name: String = self.name.toString + end extension + end NamedTypeMethods + type TermRef = dotc.core.Types.NamedType object TermRefTypeTest extends TypeTest[TypeRepr, TermRef]: @@ -1691,13 +1706,6 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler Some((x.prefix, x.name.toString)) end TermRef - given TermRefMethods: TermRefMethods with - extension (self: TermRef): - def qualifier: TypeRepr = self.prefix - def name: String = self.name.toString - end extension - end TermRefMethods - type TypeRef = dotc.core.Types.NamedType object TypeRefTypeTest extends TypeTest[TypeRepr, TypeRef]: @@ -1713,8 +1721,6 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler given TypeRefMethods: TypeRefMethods with extension (self: TypeRef): - def qualifier: TypeRepr = self.prefix - def name: String = self.name.toString def isOpaqueAlias: Boolean = self.symbol.isOpaqueAlias def translucentSuperType: TypeRepr = self.translucentSuperType end extension @@ -1811,6 +1817,21 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler end extension end AnnotatedTypeMethods + type AndOrType = dotc.core.Types.AndOrType + + object AndOrTypeTypeTest extends TypeTest[TypeRepr, AndOrType]: + def unapply(x: TypeRepr): Option[AndOrType & x.type] = x match + case tpe: (Types.AndOrType & x.type) => Some(tpe) + case _ => None + end AndOrTypeTypeTest + + given AndOrTypeMethods: AndOrTypeMethods with + extension (self: AndOrType): + def left: TypeRepr = self.tp1.stripTypeVar + def right: TypeRepr = self.tp2.stripTypeVar + end extension + end AndOrTypeMethods + type AndType = dotc.core.Types.AndType object AndTypeTypeTest extends TypeTest[TypeRepr, AndType]: @@ -1824,13 +1845,6 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler def unapply(x: AndType): Option[(TypeRepr, TypeRepr)] = Some((x.left, x.right)) end AndType - given AndTypeMethods: AndTypeMethods with - extension (self: AndType): - def left: TypeRepr = self.tp1.stripTypeVar - def right: TypeRepr = self.tp2.stripTypeVar - end extension - end AndTypeMethods - type OrType = dotc.core.Types.OrType object OrTypeTypeTest extends TypeTest[TypeRepr, OrType]: @@ -1844,13 +1858,6 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler def unapply(x: OrType): Option[(TypeRepr, TypeRepr)] = Some((x.left, x.right)) end OrType - given OrTypeMethods: OrTypeMethods with - extension (self: OrType): - def left: TypeRepr = self.tp1.stripTypeVar - def right: TypeRepr = self.tp2.stripTypeVar - end extension - end OrTypeMethods - type MatchType = dotc.core.Types.MatchType object MatchTypeTypeTest extends TypeTest[TypeRepr, MatchType]: @@ -1974,6 +1981,28 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler type LambdaType = dotc.core.Types.LambdaType + object LambdaTypeTypeTest extends TypeTest[TypeRepr, LambdaType]: + def unapply(x: TypeRepr): Option[LambdaType & x.type] = x match + case tpe: (Types.LambdaType & x.type) => Some(tpe) + case _ => None + end LambdaTypeTypeTest + + given LambdaTypeMethods: LambdaTypeMethods with + extension (self: LambdaType): + def paramNames: List[String] = self.paramNames.map(_.toString) + def paramTypes: List[TypeRepr] = self.paramInfos + def resType: TypeRepr = self.resType + end extension + end LambdaTypeMethods + + type MethodOrPoly = dotc.core.Types.MethodOrPoly + + object MethodOrPolyTypeTest extends TypeTest[TypeRepr, MethodOrPoly]: + def unapply(x: TypeRepr): Option[MethodOrPoly & x.type] = x match + case tpe: (Types.MethodOrPoly & x.type) => Some(tpe) + case _ => None + end MethodOrPolyTypeTest + type MethodType = dotc.core.Types.MethodType object MethodTypeTypeTest extends TypeTest[TypeRepr, MethodType]: @@ -1994,9 +2023,6 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler def isErased: Boolean = self.isErasedMethod def isImplicit: Boolean = self.isImplicitMethod def param(idx: Int): TypeRepr = self.newParamRef(idx) - def paramNames: List[String] = self.paramNames.map(_.toString) - def paramTypes: List[TypeRepr] = self.paramInfos - def resType: TypeRepr = self.resType end extension end MethodTypeMethods @@ -2018,9 +2044,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler given PolyTypeMethods: PolyTypeMethods with extension (self: PolyType): def param(idx: Int): TypeRepr = self.newParamRef(idx) - def paramNames: List[String] = self.paramNames.map(_.toString) def paramBounds: List[TypeBounds] = self.paramInfos - def resType: TypeRepr = self.resType end extension end PolyTypeMethods @@ -2041,10 +2065,8 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler given TypeLambdaMethods: TypeLambdaMethods with extension (self: TypeLambda): - def paramNames: List[String] = self.paramNames.map(_.toString) - def paramBounds: List[TypeBounds] = self.paramInfos def param(idx: Int): TypeRepr = self.newParamRef(idx) - def resType: TypeRepr = self.resType + def paramBounds: List[TypeBounds] = self.paramInfos end extension end TypeLambdaMethods diff --git a/library/src/scala/quoted/Quotes.scala b/library/src/scala/quoted/Quotes.scala index 94852bf3223d..002649f4fc7d 100644 --- a/library/src/scala/quoted/Quotes.scala +++ b/library/src/scala/quoted/Quotes.scala @@ -142,24 +142,24 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => * +- Alternatives * * - * +- TypeRepr -+- ConstantType - * +- TermRef - * +- TypeRef + * +- TypeRepr -+- NamedType -+- TermRef + * | +- TypeRef + * +- ConstantType * +- SuperType * +- Refinement * +- AppliedType * +- AnnotatedType - * +- AndType - * +- OrType + * +- AndOrType -+- AndType + * | +- OrType * +- MatchType * +- ByNameType * +- ParamRef * +- ThisType * +- RecursiveThis * +- RecursiveType - * +- MethodType - * +- PolyType - * +- TypeLambda + * +- LambdaType -+- MethodOrPoly -+- MethodType + * | | +- PolyType + * | +- TypeLambda * +- TypeBounds * +- NoPrefix * @@ -172,6 +172,8 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => * * +- Position * + * +- SourceFile + * * +- Documentation * * +- Constant @@ -2203,8 +2205,25 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => end extension end ConstantTypeMethods + /** Type of a reference to a type or term symbol */ + type NamedType <: TypeRepr + + /** `TypeTest` that allows testing at runtime in a pattern match if a `TypeRepr` is a `NamedType` */ + given NamedTypeTypeTest: TypeTest[TypeRepr, NamedType] + + /** Makes extension methods on `NamedType` available without any imports */ + given NamedTypeMethods: NamedTypeMethods + + /** Extension methods of `NamedType` */ + trait NamedTypeMethods: + extension (self: NamedType): + def qualifier: TypeRepr + def name: String + end extension + end NamedTypeMethods + /** Type of a reference to a term symbol */ - type TermRef <: TypeRepr + type TermRef <: NamedType /** `TypeTest` that allows testing at runtime in a pattern match if a `TypeRepr` is a `TermRef` */ given TermRefTypeTest: TypeTest[TypeRepr, TermRef] @@ -2218,19 +2237,8 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => def unapply(x: TermRef): Option[(TypeRepr, String)] } - /** Makes extension methods on `TermRef` available without any imports */ - given TermRefMethods: TermRefMethods - - /** Extension methods of `TermRef` */ - trait TermRefMethods: - extension (self: TermRef): - def qualifier: TypeRepr - def name: String - end extension - end TermRefMethods - /** Type of a reference to a type symbol */ - type TypeRef <: TypeRepr + type TypeRef <: NamedType /** `TypeTest` that allows testing at runtime in a pattern match if a `TypeRepr` is a `TypeRef` */ given TypeRefTypeTest: TypeTest[TypeRepr, TypeRef] @@ -2249,8 +2257,6 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => /** Extension methods of `TypeRef` */ trait TypeRefMethods: extension (self: TypeRef): - def qualifier: TypeRepr - def name: String def isOpaqueAlias: Boolean def translucentSuperType: TypeRepr end extension @@ -2360,8 +2366,26 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => end extension end AnnotatedTypeMethods + + /** Intersection type `T & U` or an union type `T | U` */ + type AndOrType <: TypeRepr + + /** `TypeTest` that allows testing at runtime in a pattern match if a `TypeRepr` is an `AndOrType` */ + given AndOrTypeTypeTest: TypeTest[TypeRepr, AndOrType] + + /** Makes extension methods on `AndOrType` available without any imports */ + given AndOrTypeMethods: AndOrTypeMethods + + /** Extension methods of `AndOrType` */ + trait AndOrTypeMethods: + extension (self: AndOrType): + def left: TypeRepr + def right: TypeRepr + end extension + end AndOrTypeMethods + /** Intersection type `T & U` */ - type AndType <: TypeRepr + type AndType <: AndOrType /** `TypeTest` that allows testing at runtime in a pattern match if a `TypeRepr` is an `AndType` */ given AndTypeTypeTest: TypeTest[TypeRepr, AndType] @@ -2375,19 +2399,8 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => def unapply(x: AndType): Option[(TypeRepr, TypeRepr)] } - /** Makes extension methods on `AndType` available without any imports */ - given AndTypeMethods: AndTypeMethods - - /** Extension methods of `AndType` */ - trait AndTypeMethods: - extension (self: AndType): - def left: TypeRepr - def right: TypeRepr - end extension - end AndTypeMethods - /** Union type `T | U` */ - type OrType <: TypeRepr + type OrType <: AndOrType /** `TypeTest` that allows testing at runtime in a pattern match if a `TypeRepr` is an `OrType` */ given OrTypeTypeTest: TypeTest[TypeRepr, OrType] @@ -2401,17 +2414,6 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => def unapply(x: OrType): Option[(TypeRepr, TypeRepr)] } - /** Makes extension methods on `OrType` available without any imports */ - given OrTypeMethods: OrTypeMethods - - /** Extension methods of `OrType` */ - trait OrTypeMethods: - extension (self: OrType): - def left: TypeRepr - def right: TypeRepr - end extension - end OrTypeMethods - /** Type match `T match { case U => ... }` */ type MatchType <: TypeRepr @@ -2573,8 +2575,32 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => end extension end RecursiveTypeMethods + /** Type of the definition of a method taking a single list of type or term parameters */ + type LambdaType <: TypeRepr + + /** `TypeTest` that allows testing at runtime in a pattern match if a `TypeRepr` is a `LambdaType` */ + given LambdaTypeTypeTest: TypeTest[TypeRepr, LambdaType] + + /** Makes extension methods on `LambdaType` available without any imports */ + given LambdaTypeMethods: LambdaTypeMethods + + /** Extension methods of `LambdaType` */ + trait LambdaTypeMethods: + extension (self: LambdaType): + def paramNames: List[String] + def paramTypes: List[TypeRepr] + def resType: TypeRepr + end extension + end LambdaTypeMethods + + /** Type of the definition of a method taking a single list of type or term parameters */ + type MethodOrPoly <: LambdaType + + /** `TypeTest` that allows testing at runtime in a pattern match if a `TypeRepr` is a `MethodOrPoly` */ + given MethodOrPolyTypeTest: TypeTest[TypeRepr, MethodOrPoly] + /** Type of the definition of a method taking a single list of parameters. It's return type may be a MethodType. */ - type MethodType <: TypeRepr + type MethodType <: MethodOrPoly /** `TypeTest` that allows testing at runtime in a pattern match if a `TypeRepr` is a `MethodType` */ given MethodTypeTypeTest: TypeTest[TypeRepr, MethodType] @@ -2597,14 +2623,11 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => def isImplicit: Boolean def isErased: Boolean def param(idx: Int): TypeRepr - def paramNames: List[String] - def paramTypes: List[TypeRepr] - def resType: TypeRepr end extension end MethodTypeMethods /** Type of the definition of a method taking a list of type parameters. It's return type may be a MethodType. */ - type PolyType <: TypeRepr + type PolyType <: MethodOrPoly /** `TypeTest` that allows testing at runtime in a pattern match if a `TypeRepr` is a `PolyType` */ given PolyTypeTypeTest: TypeTest[TypeRepr, PolyType] @@ -2625,14 +2648,12 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => trait PolyTypeMethods: extension (self: PolyType): def param(idx: Int): TypeRepr - def paramNames: List[String] def paramBounds: List[TypeBounds] - def resType: TypeRepr end extension end PolyTypeMethods /** Type of the definition of a type lambda taking a list of type parameters. It's return type may be a TypeLambda. */ - type TypeLambda <: TypeRepr + type TypeLambda <: LambdaType /** `TypeTest` that allows testing at runtime in a pattern match if a `TypeRepr` is a `TypeLambda` */ given TypeLambdaTypeTest: TypeTest[TypeRepr, TypeLambda] @@ -2652,10 +2673,8 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => /** Extension methods of `TypeLambda` */ trait TypeLambdaMethods: extension (self: TypeLambda): - def paramNames: List[String] - def paramBounds: List[TypeBounds] def param(idx: Int) : TypeRepr - def resType: TypeRepr + def paramBounds: List[TypeBounds] end extension end TypeLambdaMethods