From a2a8d3f340e2ed6e20055a1245d3609871c3fcdc Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 7 Aug 2018 15:20:47 +0200 Subject: [PATCH 1/4] Remove class tags from Tasty reflect interface We found that when the implementation of those class tags uses the same class tags, type matches are unsound. Instead, we replace the more precise scrutinee by equivalent extractors. In the future, we intend to language support for abstract type pattern matching where the scrutinee can get a more precise type. --- .../tools/dotc/tastyreflect/TastyImpl.scala | 185 +++++++----- library/src/scala/tasty/Tasty.scala | 279 +++++++++--------- .../src/scala/tasty/util/ShowExtractors.scala | 4 +- .../src/scala/tasty/util/ShowSourceCode.scala | 79 +++-- .../scala/tasty/util/TreeAccumulator.scala | 14 +- tests/run/tasty-custom-show/quoted_1.scala | 4 +- .../tasty-extractors-owners/quoted_1.scala | 4 +- 7 files changed, 298 insertions(+), 271 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala b/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala index f7b645eb03b7..29c2976e9964 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala @@ -12,7 +12,6 @@ import dotty.tools.dotc.reporting.diagnostic.MessageContainer import dotty.tools.dotc.util.{Positions, SourcePosition} import scala.quoted -import scala.reflect.ClassTag import scala.tasty.util.{Show, ShowExtractors, ShowSourceCode} import dotty.tools.dotc.tastyreflect.FromSymbol._ @@ -58,13 +57,8 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit def name(implicit ctx: Context): String = id.name.toString } - def idClassTag: ClassTag[Id] = implicitly[ClassTag[Id]] - object Id extends IdExtractor { - def unapply(x: Id): Option[String] = x match { - case x: untpd.Ident => Some(x.name.toString) // TODO how to make sure it is not a Ident or TypeIdent? Check x.tpe? - case _ => None - } + def unapply(id: Id): Option[String] = Some(id.name.toString) } // ===== Trees ==================================================== @@ -78,10 +72,15 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit type PackageClause = tpd.PackageDef - def packageClauseClassTag: ClassTag[PackageClause] = implicitly[ClassTag[PackageClause]] + object IsPackageClause extends IsPackageClauseExtractor { + def unapply(tree: Tree)(implicit ctx: Context): Option[PackageClause] = tree match { + case x: tpd.PackageDef @unchecked => Some(x) + case _ => None + } + } object PackageClause extends PackageClauseExtractor { - def unapply(x: PackageClause)(implicit ctx: Context): Option[(Term, List[Tree])] = x match { + def unapply(tree: Tree)(implicit ctx: Context): Option[(Term, List[Tree])] = tree match { case x: tpd.PackageDef @unchecked => Some((x.pid, x.stats)) case _ => None } @@ -97,10 +96,8 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit type Import = tpd.Import - def importClassTag: ClassTag[Import] = implicitly[ClassTag[Import]] - object Import extends ImportExtractor { - def unapply(x: Import)(implicit ctx: Context): Option[(Term, List[ImportSelector])] = x match { + def unapply(x: Tree)(implicit ctx: Context): Option[(Term, List[ImportSelector])] = x match { case x: tpd.Import @unchecked => Some((x.expr, x.selectors)) case _ => None } @@ -113,11 +110,9 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit type ImportSelector = untpd.Tree - def importSelectorClassTag: ClassTag[ImportSelector] = implicitly[ClassTag[ImportSelector]] - object SimpleSelector extends SimpleSelectorExtractor { def unapply(x: ImportSelector)(implicit ctx: Context): Option[Id] = x match { - case x: untpd.Ident => Some(x) // TODO make sure it will not match other idents + case x: untpd.Ident => Some(x) case _ => None } } @@ -140,9 +135,11 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit type Definition = tpd.Tree - object Definition extends DefinitionExtractor { - def unapply(x: Definition)(implicit ctx: Context): Boolean = - x.isInstanceOf[Trees.MemberDef[_]] + object IsDefinition extends IsDefinitionExtractor { + def unapply(tree: Tree)(implicit ctx: Context): Option[Definition] = tree match { + case tree: tpd.MemberDef => Some(tree) + case _ => None + } } def DefinitionDeco(definition: Definition): DefinitionAPI = new DefinitionAPI { @@ -178,16 +175,19 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit else ctx } - def definitionClassTag: ClassTag[Definition] = implicitly[ClassTag[Definition]] - // ClassDef type ClassDef = tpd.TypeDef - def classDefClassTag: ClassTag[ClassDef] = implicitly[ClassTag[ClassDef]] + object IsClassDef extends IsClassDefExtractor { + def unapply(tree: Tree)(implicit ctx: Context): Option[ClassDef] = tree match { + case x: tpd.TypeDef @unchecked if x.isClassDef => Some(x) + case _ => None + } + } object ClassDef extends ClassDefExtractor { - def unapply(x: ClassDef)(implicit ctx: Context): Option[(String, DefDef, List[Parent], Option[ValDef], List[Statement])] = x match { + def unapply(tree: Tree)(implicit ctx: Context): Option[(String, DefDef, List[Parent], Option[ValDef], List[Statement])] = tree match { case x: tpd.TypeDef @unchecked if x.isClassDef => val deco = ClassDefDeco(x) Some((x.name.toString, deco.constructor, deco.parents, deco.self, deco.body)) @@ -207,10 +207,15 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit type DefDef = tpd.DefDef - def defDefClassTag: ClassTag[DefDef] = implicitly[ClassTag[DefDef]] + object IsDefDef extends IsDefDefExtractor { + def unapply(tree: Tree)(implicit ctx: Context): Option[DefDef] = tree match { + case x: tpd.DefDef @unchecked => Some(x) + case _ => None + } + } object DefDef extends DefDefExtractor { - def unapply(x: DefDef)(implicit ctx: Context): Option[(String, List[TypeDef], List[List[ValDef]], TypeTree, Option[Term])] = x match { + def unapply(tree: Tree)(implicit ctx: Context): Option[(String, List[TypeDef], List[List[ValDef]], TypeTree, Option[Term])] = tree match { case x: tpd.DefDef @unchecked => Some((x.name.toString, x.tparams, x.vparamss, x.tpt, optional(x.rhs))) case _ => None @@ -228,10 +233,15 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit type ValDef = tpd.ValDef - def valDefClassTag: ClassTag[ValDef] = implicitly[ClassTag[ValDef]] + object IsValDef extends IsValDefExtractor { + def unapply(tree: Tree)(implicit ctx: Context): Option[ValDef] = tree match { + case x: tpd.ValDef @unchecked => Some(x) + case _ => None + } + } object ValDef extends ValDefExtractor { - def unapply(x: ValDef)(implicit ctx: Context): Option[(String, TypeTree, Option[Term])] = x match { + def unapply(tree: Tree)(implicit ctx: Context): Option[(String, TypeTree, Option[Term])] = tree match { case x: tpd.ValDef @unchecked => Some((x.name.toString, x.tpt, optional(x.rhs))) case _ => None @@ -247,10 +257,15 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit type TypeDef = tpd.TypeDef - def typeDefClassTag: ClassTag[TypeDef] = implicitly[ClassTag[TypeDef]] + object IsTypeDef extends IsTypeDefExtractor { + def unapply(tree: Tree)(implicit ctx: Context): Option[TypeDef] = tree match { + case x: tpd.TypeDef @unchecked if !x.symbol.isClass => Some(x) + case _ => None + } + } object TypeDef extends TypeDefExtractor { - def unapply(x: TypeDef)(implicit ctx: Context): Option[(String, TypeOrBoundsTree /* TypeTree | TypeBoundsTree */)] = x match { + def unapply(tree: Tree)(implicit ctx: Context): Option[(String, TypeOrBoundsTree /* TypeTree | TypeBoundsTree */)] = tree match { case x: tpd.TypeDef @unchecked if !x.symbol.isClass => Some((x.name.toString, x.rhs)) case _ => None } @@ -274,10 +289,15 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit } } - def packageDefClassTag: ClassTag[PackageDef] = implicitly[ClassTag[PackageDef]] + object IsPackageDef extends IsPackageDefExtractor { + def unapply(tree: Tree)(implicit ctx: Context): Option[PackageDef] = tree match { + case x: PackageDefinition => Some(x) + case _ => None + } + } object PackageDef extends PackageDefExtractor { - def unapply(x: PackageDef)(implicit ctx: Context): Option[(String, PackageDef)] = x match { + def unapply(tree: Tree)(implicit ctx: Context): Option[(String, PackageDef)] = tree match { case x: PackageDefinition => Some((x.symbol.name.toString, packageDefFromSym(x.symbol.owner))) case _ => None @@ -328,12 +348,15 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit } } - def termClassTag: ClassTag[Term] = implicitly[ClassTag[Term]] + object IsTerm extends IsTermExtractor { + def unapply(tree: Tree)(implicit ctx: Context): Option[Term] = + if (tree.isTerm) Some(tree) else None + def unapply(parent: Parent)(implicit ctx: Context, dummy: DummyImplicit): Option[Term] = + if (parent.isTerm) Some(parent) else None + } object Term extends TermModule { - def unapply(x: Term)(implicit ctx: Context): Boolean = x.isTerm - object Ident extends IdentExtractor { def unapply(x: Term)(implicit ctx: Context): Option[String] = x match { case x: tpd.Ident @unchecked if x.isTerm => Some(x.name.show) @@ -540,8 +563,6 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit type CaseDef = tpd.CaseDef - def caseDefClassTag: ClassTag[CaseDef] = implicitly[ClassTag[CaseDef]] - def CaseDefDeco(caseDef: CaseDef): CaseDefAPI = new CaseDefAPI { def show(implicit ctx: Context, s: Show[TastyImpl.this.type]): String = s.showCaseDef(caseDef) def pattern(implicit ctx: Context): Pattern = caseDef.pat @@ -567,8 +588,6 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit def tpe(implicit ctx: Context): Types.Type = pattern.tpe.stripTypeVar } - def patternClassTag: ClassTag[Pattern] = implicitly[ClassTag[Pattern]] - object Pattern extends PatternModule { object Value extends ValueExtractor { @@ -635,12 +654,15 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit def tpe(implicit ctx: Context): Types.Type = tpt.tpe.stripTypeVar } - def typeTreeClassTag: ClassTag[TypeTree] = implicitly[ClassTag[TypeTree]] + object IsTypeTree extends IsTypeTreeExtractor { + def unapply(x: TypeOrBoundsTree)(implicit ctx: Context): Option[TypeTree] = + if (x.isType) Some(x) else None + def unapply(x: Parent)(implicit ctx: Context, dummy: DummyImplicit): Option[TypeTree] = + if (x.isType) Some(x) else None + } object TypeTree extends TypeTreeModule { - def unapply(x: TypeTree)(implicit ctx: Context): Boolean = x.isType - object Synthetic extends SyntheticExtractor { def unapply(x: TypeTree)(implicit ctx: Context): Boolean = x match { case x @ Trees.TypeTree() => !x.tpe.isInstanceOf[Types.TypeBounds] @@ -743,17 +765,22 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit def hi(implicit ctx: Context): TypeTree = bounds.asInstanceOf[tpd.TypeBoundsTree].hi } - def typeBoundsTreeClassTag: ClassTag[TypeBoundsTree] = implicitly[ClassTag[TypeBoundsTree]] + object IsTypeBoundsTree extends IsTypeBoundsTreeExtractor { + def unapply(x: TypeOrBoundsTree)(implicit ctx: Context): Option[TypeBoundsTree] = x match { + case x: tpd.TypeBoundsTree @unchecked => Some(x) + case _ => None + } + } object TypeBoundsTree extends TypeBoundsTreeExtractor { - def unapply(x: TypeBoundsTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] = x match { + def unapply(x: TypeOrBoundsTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] = x match { case x: tpd.TypeBoundsTree @unchecked => Some(x.lo, x.hi) case _ => None } } object SyntheticBounds extends SyntheticBoundsExtractor { - def unapply(x: TypeBoundsTree)(implicit ctx: Context): Boolean = x match { + def unapply(x: TypeOrBoundsTree)(implicit ctx: Context): Boolean = x match { case x @ Trees.TypeTree() => x.tpe.isInstanceOf[Types.TypeBounds] case Trees.Ident(nme.WILDCARD) => x.tpe.isInstanceOf[Types.TypeBounds] case _ => false @@ -783,12 +810,6 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit type PolyType = Types.PolyType type TypeLambda = Types.TypeLambda - def typeClassTag: ClassTag[Type] = implicitly[ClassTag[Type]] - def recursiveTypeClassTag: ClassTag[RecursiveType] = implicitly[ClassTag[RecursiveType]] - def methodTypeClassTag: ClassTag[MethodType] = implicitly[ClassTag[MethodType]] - def polyTypeClassTag: ClassTag[PolyType] = implicitly[ClassTag[PolyType]] - def typeLambdaClassTag: ClassTag[TypeLambda] = implicitly[ClassTag[TypeLambda]] - def MethodTypeDeco(tpe: MethodType): MethodTypeAPI = new MethodTypeAPI { def isErased: Boolean = tpe.isErasedMethod def isImplicit: Boolean = tpe.isImplicitMethod @@ -809,22 +830,25 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit def resultTpe(implicit ctx: Context): Type = tpe.resType } - object Type extends TypeModule { - - def unapply(x: Type)(implicit ctx: Context): Boolean = x match { - case x: Types.TypeBounds => false - case x => x != Types.NoPrefix + object IsType extends IsTypeExtractor { + def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[Type] = x match { + case x: Types.TypeBounds => None + case x if x == Types.NoPrefix => None + case _ => Some(x) } + } + + object Type extends TypeModule { object ConstantType extends ConstantTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[Constant] = x match { + def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[Constant] = x match { case Types.ConstantType(value) => Some(value) case _ => None } } object SymRef extends SymRefExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Definition, TypeOrBounds /* Type | NoPrefix */)] = x match { + def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[(Definition, TypeOrBounds /* Type | NoPrefix */)] = x match { case tp: Types.NamedType => tp.designator match { case sym: Symbol => Some((definitionFromSym(sym), tp.prefix)) @@ -835,7 +859,7 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit } object TermRef extends TermRefExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(String, TypeOrBounds /* Type | NoPrefix */)] = x match { + def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[(String, TypeOrBounds /* Type | NoPrefix */)] = x match { case tp: Types.NamedType => tp.designator match { case name: Names.TermName => Some(name.toString, tp.prefix) @@ -846,7 +870,7 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit } object TypeRef extends TypeRefExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(String, TypeOrBounds /* Type | NoPrefix */)] = x match { + def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[(String, TypeOrBounds /* Type | NoPrefix */)] = x match { case tp: Types.NamedType => tp.designator match { case name: Names.TypeName => Some(name.toString, tp.prefix) @@ -857,56 +881,56 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit } object SuperType extends SuperTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] = x match { + def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[(Type, Type)] = x match { case Types.SuperType(thistpe, supertpe) => Some(thistpe, supertpe) case _ => None } } object Refinement extends RefinementExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, String, TypeOrBounds /* Type | TypeBounds */)] = x match { + def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[(Type, String, TypeOrBounds /* Type | TypeBounds */)] = x match { case Types.RefinedType(parent, name, info) => Some(parent, name.toString, info) case _ => None } } object AppliedType extends AppliedTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, List[TypeOrBounds /* Type | TypeBounds */])] = x match { + def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[(Type, List[TypeOrBounds /* Type | TypeBounds */])] = x match { case Types.AppliedType(tycon, args) => Some((tycon.stripTypeVar, args.map(_.stripTypeVar))) case _ => None } } object AnnotatedType extends AnnotatedTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, Term)] = x match { + def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[(Type, Term)] = x match { case Types.AnnotatedType(underlying, annot) => Some((underlying.stripTypeVar, annot.tree)) case _ => None } } object AndType extends AndTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] = x match { + def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[(Type, Type)] = x match { case Types.AndType(left, right) => Some(left.stripTypeVar, right.stripTypeVar) case _ => None } } object OrType extends OrTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] = x match { + def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[(Type, Type)] = x match { case Types.OrType(left, right) => Some(left.stripTypeVar, right.stripTypeVar) case _ => None } } object ByNameType extends ByNameTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[Type] = x match { + def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[Type] = x match { case Types.ExprType(resType) => Some(resType.stripTypeVar) case _ => None } } object ParamRef extends ParamRefExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(LambdaType[TypeOrBounds], Int)] = x match { + def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[(LambdaType[TypeOrBounds], Int)] = x match { case Types.TypeParamRef(binder, idx) => Some(( binder.asInstanceOf[LambdaType[TypeOrBounds]], // Cast to tpd @@ -917,42 +941,42 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit } object ThisType extends ThisTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[Type] = x match { + def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[Type] = x match { case Types.ThisType(tp) => Some(tp) case _ => None } } object RecursiveThis extends RecursiveThisExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[RecursiveType] = x match { + def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[RecursiveType] = x match { case Types.RecThis(binder) => Some(binder) case _ => None } } object RecursiveType extends RecursiveTypeExtractor { - def unapply(x: RecursiveType)(implicit ctx: Context): Option[Type] = x match { + def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[Type] = x match { case tp: Types.RecType => Some(tp.underlying.stripTypeVar) case _ => None } } object MethodType extends MethodTypeExtractor { - def unapply(x: MethodType)(implicit ctx: Context): Option[(List[String], List[Type], Type)] = x match { + def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[(List[String], List[Type], Type)] = x match { case x: MethodType => Some(x.paramNames.map(_.toString), x.paramInfos, x.resType) case _ => None } } object PolyType extends PolyTypeExtractor { - def unapply(x: PolyType)(implicit ctx: Context): Option[(List[String], List[TypeBounds], Type)] = x match { + def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[(List[String], List[TypeBounds], Type)] = x match { case x: PolyType => Some(x.paramNames.map(_.toString), x.paramInfos, x.resType) case _ => None } } object TypeLambda extends TypeLambdaExtractor { - def unapply(x: TypeLambda)(implicit ctx: Context): Option[(List[String], List[TypeBounds], Type)] = x match { + def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[(List[String], List[TypeBounds], Type)] = x match { case x: TypeLambda => Some(x.paramNames.map(_.toString), x.paramInfos, x.resType) case _ => None } @@ -964,10 +988,15 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit type TypeBounds = Types.TypeBounds - def typeBoundsClassTag: ClassTag[TypeBounds] = implicitly[ClassTag[TypeBounds]] + object IsTypeBounds extends IsTypeBoundsExtractor { + def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[TypeBounds] = x match { + case x: Types.TypeBounds => Some(x) + case _ => None + } + } object TypeBounds extends TypeBoundsExtractor { - def unapply(x: TypeBounds)(implicit ctx: Context): Option[(Type, Type)] = x match { + def unapply(x: TypeOrBounds)(implicit ctx: Context): Option[(Type, Type)] = x match { case x: Types.TypeBounds => Some(x.lo, x.hi) case _ => None } @@ -982,10 +1011,8 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit type NoPrefix = Types.NoPrefix.type - def noPrefixClassTag: ClassTag[NoPrefix] = implicitly[ClassTag[NoPrefix]] - object NoPrefix extends NoPrefixExtractor { - def unapply(x: NoPrefix)(implicit ctx: Context): Boolean = x == Types.NoPrefix + def unapply(x: TypeOrBounds)(implicit ctx: Context): Boolean = x == Types.NoPrefix } // ===== Constants ================================================ @@ -997,8 +1024,6 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit def value: Any = const.value } - def constantClassTag: ClassTag[Constant] = implicitly[ClassTag[Constant]] - object Constant extends ConstantModule { object Unit extends UnitExtractor { @@ -1097,8 +1122,6 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit type Signature = core.Signature - def signatureClassTag: ClassTag[Signature] = implicitly[ClassTag[Signature]] - object Signature extends SignatureExtractor { def unapply(x: Signature)(implicit ctx: Context): Option[(List[String], String)] = { Some((x.paramsSig.map(_.toString), x.resSig.toString)) diff --git a/library/src/scala/tasty/Tasty.scala b/library/src/scala/tasty/Tasty.scala index e49fa631a101..a85bf4c4bc7d 100644 --- a/library/src/scala/tasty/Tasty.scala +++ b/library/src/scala/tasty/Tasty.scala @@ -1,6 +1,5 @@ package scala.tasty -import scala.reflect.ClassTag import scala.tasty.reflect.StandardDefinitions import scala.tasty.util.Show @@ -11,12 +10,12 @@ abstract class Tasty extends StandardDefinitions { tasty => trait QuotedExprAPI { def toTasty(implicit ctx: Context): Term } - implicit def QuotedExprDeco[T](x: quoted.Expr[T]): QuotedExprAPI + implicit def QuotedExprDeco[T](expr: quoted.Expr[T]): QuotedExprAPI trait QuotedTypeAPI { def toTasty(implicit ctx: Context): TypeTree } - implicit def QuotedTypeDeco[T](x: quoted.Type[T]): QuotedTypeAPI + implicit def QuotedTypeDeco[T](tpe: quoted.Type[T]): QuotedTypeAPI // ===== Show ===================================================== @@ -52,11 +51,9 @@ abstract class Tasty extends StandardDefinitions { tasty => } implicit def IdDeco(id: Id): IdAPI - implicit def idClassTag: ClassTag[Id] - val Id: IdExtractor abstract class IdExtractor { - def unapply(x: Id): Option[String] + def unapply(id: Id): Option[String] } // ===== Trees ==================================================== @@ -70,11 +67,14 @@ abstract class Tasty extends StandardDefinitions { tasty => type PackageClause <: Tree - implicit def packageClauseClassTag: ClassTag[PackageClause] + val IsPackageClause: IsPackageClauseExtractor + abstract class IsPackageClauseExtractor { + def unapply(tree: Tree)(implicit ctx: Context): Option[PackageClause] + } val PackageClause: PackageClauseExtractor abstract class PackageClauseExtractor { - def unapply(x: PackageClause)(implicit ctx: Context): Option[(Term, List[Tree])] + def unapply(tree: Tree)(implicit ctx: Context): Option[(Term, List[Tree])] } trait PackageClauseAPI { @@ -88,11 +88,9 @@ abstract class Tasty extends StandardDefinitions { tasty => type Import <: Statement - implicit def importClassTag: ClassTag[Import] - val Import: ImportExtractor abstract class ImportExtractor { - def unapply(x: Import)(implicit ctx: Context): Option[(Term, List[ImportSelector])] + def unapply(imp: Tree)(implicit ctx: Context): Option[(Term, List[ImportSelector])] } trait ImportAPI { @@ -103,34 +101,30 @@ abstract class Tasty extends StandardDefinitions { tasty => type ImportSelector - implicit def importSelectorClassTag: ClassTag[ImportSelector] - val SimpleSelector: SimpleSelectorExtractor abstract class SimpleSelectorExtractor { - def unapply(x: ImportSelector)(implicit ctx: Context): Option[Id] + def unapply(importSelector: ImportSelector)(implicit ctx: Context): Option[Id] } val RenameSelector: RenameSelectorExtractor abstract class RenameSelectorExtractor { - def unapply(x: ImportSelector)(implicit ctx: Context): Option[(Id, Id)] + def unapply(importSelector: ImportSelector)(implicit ctx: Context): Option[(Id, Id)] } val OmitSelector: OmitSelectorExtractor abstract class OmitSelectorExtractor { - def unapply(x: ImportSelector)(implicit ctx: Context): Option[Id] + def unapply(importSelector: ImportSelector)(implicit ctx: Context): Option[Id] } // ----- Definitions ---------------------------------------------- type Definition <: Statement - val Definition: DefinitionExtractor - abstract class DefinitionExtractor { - def unapply(x: Definition)(implicit ctx: Context): Boolean + val IsDefinition: IsDefinitionExtractor + abstract class IsDefinitionExtractor { + def unapply(tree: Tree)(implicit ctx: Context): Option[Definition] } - implicit def definitionClassTag: ClassTag[Definition] - trait DefinitionAPI { def name(implicit ctx: Context): String def flags(implicit ctx: Context): FlagSet @@ -146,11 +140,14 @@ abstract class Tasty extends StandardDefinitions { tasty => type ClassDef <: Definition - implicit def classDefClassTag: ClassTag[ClassDef] + val IsClassDef: IsClassDefExtractor + abstract class IsClassDefExtractor { + def unapply(tree: Tree)(implicit ctx: Context): Option[ClassDef] + } val ClassDef: ClassDefExtractor abstract class ClassDefExtractor { - def unapply(x: ClassDef)(implicit ctx: Context): Option[(String, DefDef, List[Parent], Option[ValDef], List[Statement])] + def unapply(tree: Tree)(implicit ctx: Context): Option[(String, DefDef, List[Parent], Option[ValDef], List[Statement])] } trait ClassDefAPI { @@ -165,11 +162,14 @@ abstract class Tasty extends StandardDefinitions { tasty => type DefDef <: Definition - implicit def defDefClassTag: ClassTag[DefDef] + val IsDefDef: IsDefDefExtractor + abstract class IsDefDefExtractor { + def unapply(tree: Tree)(implicit ctx: Context): Option[DefDef] + } val DefDef: DefDefExtractor abstract class DefDefExtractor { - def unapply(x: DefDef)(implicit ctx: Context): Option[(String, List[TypeDef], List[List[ValDef]], TypeTree, Option[Term])] + def unapply(tree: Tree)(implicit ctx: Context): Option[(String, List[TypeDef], List[List[ValDef]], TypeTree, Option[Term])] } trait DefDefAPI { @@ -184,11 +184,14 @@ abstract class Tasty extends StandardDefinitions { tasty => type ValDef <: Definition - implicit def valDefClassTag: ClassTag[ValDef] + val IsValDef: IsValDefExtractor + abstract class IsValDefExtractor { + def unapply(tree: Tree)(implicit ctx: Context): Option[ValDef] + } val ValDef: ValDefExtractor abstract class ValDefExtractor { - def unapply(x: ValDef)(implicit ctx: Context): Option[(String, TypeTree, Option[Term])] + def unapply(tree: Tree)(implicit ctx: Context): Option[(String, TypeTree, Option[Term])] } trait ValDefAPI { @@ -201,11 +204,14 @@ abstract class Tasty extends StandardDefinitions { tasty => type TypeDef <: Definition - implicit def typeDefClassTag: ClassTag[TypeDef] + val IsTypeDef: IsTypeDefExtractor + abstract class IsTypeDefExtractor { + def unapply(tree: Tree)(implicit ctx: Context): Option[TypeDef] + } val TypeDef: TypeDefExtractor abstract class TypeDefExtractor { - def unapply(x: TypeDef)(implicit ctx: Context): Option[(String, TypeOrBoundsTree /* TypeTree | TypeBoundsTree */)] + def unapply(tree: Tree)(implicit ctx: Context): Option[(String, TypeOrBoundsTree /* TypeTree | TypeBoundsTree */)] } trait TypeDefAPI { @@ -217,17 +223,20 @@ abstract class Tasty extends StandardDefinitions { tasty => type PackageDef <: Definition + val IsPackageDef: IsPackageDefExtractor + abstract class IsPackageDefExtractor { + def unapply(tree: Tree)(implicit ctx: Context): Option[PackageDef] + } + trait PackageDefAPI { def owner(implicit ctx: Context): PackageDef def members(implicit ctx: Context): List[Statement] } implicit def PackageDefDeco(pdef: PackageDef): PackageDefAPI - implicit def packageDefClassTag: ClassTag[PackageDef] - val PackageDef: PackageDefExtractor abstract class PackageDefExtractor { - def unapply(x: PackageDef)(implicit ctx: Context): Option[(String, PackageDef)] + def unapply(tree: Tree)(implicit ctx: Context): Option[(String, PackageDef)] } // ----- Parents -------------------------------------------------- @@ -243,156 +252,159 @@ abstract class Tasty extends StandardDefinitions { tasty => } implicit def TermDeco(term: Term): TermAPI - implicit def termClassTag: ClassTag[Term] + val IsTerm: IsTermExtractor + abstract class IsTermExtractor { + /** Matches any term */ + def unapply(tree: Tree)(implicit ctx: Context): Option[Term] + /** Matches any term */ + def unapply(parent: Parent)(implicit ctx: Context, dummy: DummyImplicit): Option[Term] + } /** Scala term. Any tree that can go in expression position. */ val Term: TermModule abstract class TermModule { - /** Matches any term */ - def unapply(x: Term)(implicit ctx: Context): Boolean - /** Scala term identifier */ val Ident: IdentExtractor abstract class IdentExtractor { /** Matches a term identifier and returns its name */ - def unapply(x: Term)(implicit ctx: Context): Option[String] + def unapply(tree: Tree)(implicit ctx: Context): Option[String] } /** Scala term selection */ val Select: SelectExtractor abstract class SelectExtractor { /** Matches `.: ` */ - def unapply(x: Term)(implicit ctx: Context): Option[(Term, String, Option[Signature])] + def unapply(tree: Tree)(implicit ctx: Context): Option[(Term, String, Option[Signature])] } /** Scala literal constant */ val Literal: LiteralExtractor abstract class LiteralExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[Constant] + def unapply(tree: Tree)(implicit ctx: Context): Option[Constant] } /** Scala `this` or `this[id]` */ val This: ThisExtractor abstract class ThisExtractor { /** Matches new `this[` */ - def unapply(x: Term)(implicit ctx: Context): Option[Option[Id]] + def unapply(tree: Tree)(implicit ctx: Context): Option[Option[Id]] } /** Scala `new` */ val New: NewExtractor abstract class NewExtractor { /** Matches new `new ` */ - def unapply(x: Term)(implicit ctx: Context): Option[TypeTree] + def unapply(tree: Tree)(implicit ctx: Context): Option[TypeTree] } /** Scala named argument `x = y` in argument position */ val NamedArg: NamedArgExtractor abstract class NamedArgExtractor { /** Matches ` = ` */ - def unapply(x: Term)(implicit ctx: Context): Option[(String, Term)] + def unapply(tree: Tree)(implicit ctx: Context): Option[(String, Term)] } /** Scala parameter application */ val Apply: ApplyExtractor abstract class ApplyExtractor { /** Matches function application `()` */ - def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[Term])] + def unapply(tree: Tree)(implicit ctx: Context): Option[(Term, List[Term])] } /** Scala type parameter application */ val TypeApply: TypeApplyExtractor abstract class TypeApplyExtractor { /** Matches function type application `[]` */ - def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[TypeTree])] + def unapply(tree: Tree)(implicit ctx: Context): Option[(Term, List[TypeTree])] } /** Scala `x.super` or `x.super[id]` */ val Super: SuperExtractor abstract class SuperExtractor { /** Matches new `.super[` */ - def unapply(x: Term)(implicit ctx: Context): Option[(Term, Option[Id])] + def unapply(tree: Tree)(implicit ctx: Context): Option[(Term, Option[Id])] } /** Scala ascription `x: T` */ val Typed: TypedExtractor abstract class TypedExtractor { /** Matches `: ` */ - def unapply(x: Term)(implicit ctx: Context): Option[(Term, TypeTree)] + def unapply(tree: Tree)(implicit ctx: Context): Option[(Term, TypeTree)] } /** Scala assign `x = y` */ val Assign: AssignExtractor abstract class AssignExtractor { /** Matches ` = ` */ - def unapply(x: Term)(implicit ctx: Context): Option[(Term, Term)] + def unapply(tree: Tree)(implicit ctx: Context): Option[(Term, Term)] } /** Scala code block `{ stat0; ...; statN; expr }` term */ val Block: BlockExtractor abstract class BlockExtractor { /** Matches `{ ; }` */ - def unapply(x: Term)(implicit ctx: Context): Option[(List[Statement], Term)] + def unapply(tree: Tree)(implicit ctx: Context): Option[(List[Statement], Term)] } val Lambda: LambdaExtractor abstract class LambdaExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(Term, Option[TypeTree])] + def unapply(tree: Tree)(implicit ctx: Context): Option[(Term, Option[TypeTree])] } /** Scala `if`/`else` term */ val If: IfExtractor abstract class IfExtractor { /** Matches `if () else ` */ - def unapply(x: Term)(implicit ctx: Context): Option[(Term, Term, Term)] + def unapply(tree: Tree)(implicit ctx: Context): Option[(Term, Term, Term)] } /** Scala `match` term */ val Match: MatchExtractor abstract class MatchExtractor { /** Matches ` match { }` */ - def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[CaseDef])] + def unapply(tree: Tree)(implicit ctx: Context): Option[(Term, List[CaseDef])] } /** Scala `try`/`catch`/`finally` term */ val Try: TryExtractor abstract class TryExtractor { /** Matches `try catch { } finally ` */ - def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[CaseDef], Option[Term])] + def unapply(tree: Tree)(implicit ctx: Context): Option[(Term, List[CaseDef], Option[Term])] } /** Scala local `return` */ val Return: ReturnExtractor abstract class ReturnExtractor { /** Matches `return ` */ - def unapply(x: Term)(implicit ctx: Context): Option[Term] + def unapply(tree: Tree)(implicit ctx: Context): Option[Term] } val Repeated: RepeatedExtractor abstract class RepeatedExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[List[Term]] + def unapply(tree: Tree)(implicit ctx: Context): Option[List[Term]] } val Inlined: InlinedExtractor abstract class InlinedExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(Option[Term], List[Definition], Term)] + def unapply(tree: Tree)(implicit ctx: Context): Option[(Option[Term], List[Definition], Term)] } val SelectOuter: SelectOuterExtractor abstract class SelectOuterExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(Term, Int, Type)] + def unapply(tree: Tree)(implicit ctx: Context): Option[(Term, Int, Type)] } val While: WhileExtractor abstract class WhileExtractor { /** Extractor for while loops. Matches `while () ` and returns (, ) */ - def unapply(x: Term)(implicit ctx: Context): Option[(Term, Term)] + def unapply(tree: Tree)(implicit ctx: Context): Option[(Term, Term)] } val DoWhile: DoWhileExtractor abstract class DoWhileExtractor { /** Extractor for do while loops. Matches `do while ()` and returns (, ) */ - def unapply(x: Term)(implicit ctx: Context): Option[(Term, Term)] + def unapply(tree: Tree)(implicit ctx: Context): Option[(Term, Term)] } } @@ -400,8 +412,6 @@ abstract class Tasty extends StandardDefinitions { tasty => type CaseDef - implicit def caseDefClassTag: ClassTag[CaseDef] - trait CaseDefAPI { def show(implicit ctx: Context, s: Show[tasty.type]): String def pattern(implicit ctx: Context): Pattern @@ -425,34 +435,32 @@ abstract class Tasty extends StandardDefinitions { tasty => } implicit def PatternDeco(pattern: Pattern): PatternAPI - implicit def patternClassTag: ClassTag[Pattern] - val Pattern: PatternModule abstract class PatternModule { val Value: ValueExtractor abstract class ValueExtractor { - def unapply(x: Pattern)(implicit ctx: Context): Option[Term] + def unapply(pattern: Pattern)(implicit ctx: Context): Option[Term] } val Bind: BindExtractor abstract class BindExtractor { - def unapply(x: Pattern)(implicit ctx: Context): Option[(String, Pattern)] + def unapply(pattern: Pattern)(implicit ctx: Context): Option[(String, Pattern)] } val Unapply: UnapplyExtractor abstract class UnapplyExtractor { - def unapply(x: Pattern)(implicit ctx: Context): Option[(Term, List[Term], List[Pattern])] + def unapply(pattern: Pattern)(implicit ctx: Context): Option[(Term, List[Term], List[Pattern])] } val Alternative: AlternativeExtractor abstract class AlternativeExtractor { - def unapply(x: Pattern)(implicit ctx: Context): Option[List[Pattern]] + def unapply(pattern: Pattern)(implicit ctx: Context): Option[List[Pattern]] } val TypeTest: TypeTestExtractor abstract class TypeTestExtractor { - def unapply(x: Pattern)(implicit ctx: Context): Option[TypeTree] + def unapply(pattern: Pattern)(implicit ctx: Context): Option[TypeTree] } } @@ -470,83 +478,85 @@ abstract class Tasty extends StandardDefinitions { tasty => // ----- TypeTrees ------------------------------------------------ - type TypeTree <: TypeOrBoundsTree with Parent + type TypeTree <: TypeOrBoundsTree trait TypeTreeAPI extends Typed with Positioned implicit def TypeTreeDeco(tpt: TypeTree): TypeTreeAPI - implicit def typeTreeClassTag: ClassTag[TypeTree] + val IsTypeTree: IsTypeTreeExtractor + abstract class IsTypeTreeExtractor { + def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[TypeTree] + def unapply(parent: Parent)(implicit ctx: Context, dummy: DummyImplicit): Option[TypeTree] + } val TypeTree: TypeTreeModule abstract class TypeTreeModule { - def unapply(x: TypeTree)(implicit ctx: Context): Boolean - /** TypeTree containing an inferred type */ val Synthetic: SyntheticExtractor abstract class SyntheticExtractor { /** Matches a TypeTree containing an inferred type */ - def unapply(x: TypeTree)(implicit ctx: Context): Boolean + def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Boolean } val TypeIdent: TypeIdentExtractor abstract class TypeIdentExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[String] + def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[String] } val TermSelect: TermSelectExtractor abstract class TermSelectExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[(Term, String)] + def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[(Term, String)] } val TypeSelect: TypeSelectExtractor abstract class TypeSelectExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, String)] + def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[(TypeTree, String)] } val Singleton: SingletonExtractor abstract class SingletonExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[Term] + def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[Term] } val Refined: RefinedExtractor abstract class RefinedExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, List[Definition])] + def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[(TypeTree, List[Definition])] } val Applied: AppliedExtractor abstract class AppliedExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, List[TypeOrBoundsTree])] + def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[(TypeTree, List[TypeOrBoundsTree])] } val Annotated: AnnotatedExtractor abstract class AnnotatedExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, Term)] + def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[(TypeTree, Term)] } val And: AndExtractor abstract class AndExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] + def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] } val Or: OrExtractor abstract class OrExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] + def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] } val ByName: ByNameExtractor abstract class ByNameExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[TypeTree] + def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[TypeTree] } val TypeLambdaTree: TypeLambdaTreeExtractor abstract class TypeLambdaTreeExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[(List[TypeDef], TypeOrBoundsTree)] + def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[(List[TypeDef], TypeOrBoundsTree)] } val Bind: BindExtractor abstract class BindExtractor{ - def unapply(x: TypeTree)(implicit ctx: Context): Option[(String, TypeBoundsTree)] + def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[(String, TypeBoundsTree)] } } @@ -561,18 +571,21 @@ abstract class Tasty extends StandardDefinitions { tasty => } implicit def TypeBoundsTreeDeco(tpt: TypeBoundsTree): TypeBoundsTreeAPI - implicit def typeBoundsTreeClassTag: ClassTag[TypeBoundsTree] + val IsTypeBoundsTree: IsTypeBoundsTreeExtractor + abstract class IsTypeBoundsTreeExtractor { + def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[TypeBoundsTree] + } val TypeBoundsTree: TypeBoundsTreeExtractor abstract class TypeBoundsTreeExtractor { - def unapply(x: TypeBoundsTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] + def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] } /** TypeBoundsTree containing an inferred type bounds */ val SyntheticBounds: SyntheticBoundsExtractor abstract class SyntheticBoundsExtractor { /** Matches a TypeBoundsTree containing inferred type bounds */ - def unapply(x: TypeBoundsTree)(implicit ctx: Context): Boolean + def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Boolean } // ===== Types ==================================================== @@ -605,12 +618,6 @@ abstract class Tasty extends StandardDefinitions { tasty => type PolyType <: LambdaType[TypeBounds] type TypeLambda <: LambdaType[TypeBounds] - implicit def typeClassTag: ClassTag[Type] - implicit def methodTypeClassTag: ClassTag[MethodType] - implicit def polyTypeClassTag: ClassTag[PolyType] - implicit def typeLambdaClassTag: ClassTag[TypeLambda] - implicit def recursiveTypeClassTag: ClassTag[RecursiveType] - trait MethodTypeAPI { def isImplicit: Boolean def isErased: Boolean @@ -634,99 +641,102 @@ abstract class Tasty extends StandardDefinitions { tasty => } implicit def TypeLambdaDeco(tpt: TypeLambda): TypeLambdaAPI + val IsType: IsTypeExtractor + abstract class IsTypeExtractor { + def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[Type] + } + val Type: TypeModule abstract class TypeModule { - def unapply(x: Type)(implicit ctx: Context): Boolean - val ConstantType: ConstantTypeExtractor abstract class ConstantTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[Constant] + def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[Constant] } val SymRef: SymRefExtractor abstract class SymRefExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Definition, TypeOrBounds /* Type | NoPrefix */)] + def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[(Definition, TypeOrBounds /* Type | NoPrefix */)] } val TermRef: TermRefExtractor abstract class TermRefExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(String, TypeOrBounds /* Type | NoPrefix */)] + def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[(String, TypeOrBounds /* Type | NoPrefix */)] } val TypeRef: TypeRefExtractor abstract class TypeRefExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(String, TypeOrBounds /* Type | NoPrefix */)] + def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[(String, TypeOrBounds /* Type | NoPrefix */)] } val SuperType: SuperTypeExtractor abstract class SuperTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] + def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[(Type, Type)] } val Refinement: RefinementExtractor abstract class RefinementExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, String, TypeOrBounds /* Type | TypeBounds */)] + def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[(Type, String, TypeOrBounds /* Type | TypeBounds */)] } val AppliedType: AppliedTypeExtractor abstract class AppliedTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, List[TypeOrBounds /* Type | TypeBounds */])] + def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[(Type, List[TypeOrBounds /* Type | TypeBounds */])] } val AnnotatedType: AnnotatedTypeExtractor abstract class AnnotatedTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, Term)] + def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[(Type, Term)] } val AndType: AndTypeExtractor abstract class AndTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] + def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[(Type, Type)] } val OrType: OrTypeExtractor abstract class OrTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] + def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[(Type, Type)] } val ByNameType: ByNameTypeExtractor abstract class ByNameTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[Type] + def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[Type] } val ParamRef: ParamRefExtractor abstract class ParamRefExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(LambdaType[TypeOrBounds], Int)] + def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[(LambdaType[TypeOrBounds], Int)] } val ThisType: ThisTypeExtractor abstract class ThisTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[Type] + def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[Type] } val RecursiveThis: RecursiveThisExtractor abstract class RecursiveThisExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[RecursiveType] + def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[RecursiveType] } val RecursiveType: RecursiveTypeExtractor abstract class RecursiveTypeExtractor { - def unapply(x: RecursiveType)(implicit ctx: Context): Option[Type] + def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[Type] } val MethodType: MethodTypeExtractor abstract class MethodTypeExtractor { - def unapply(x: MethodType)(implicit ctx: Context): Option[(List[String], List[Type], Type)] + def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[(List[String], List[Type], Type)] } val PolyType: PolyTypeExtractor abstract class PolyTypeExtractor { - def unapply(x: PolyType)(implicit ctx: Context): Option[(List[String], List[TypeBounds], Type)] + def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[(List[String], List[TypeBounds], Type)] } val TypeLambda: TypeLambdaExtractor abstract class TypeLambdaExtractor { - def unapply(x: TypeLambda)(implicit ctx: Context): Option[(List[String], List[TypeBounds], Type)] + def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[(List[String], List[TypeBounds], Type)] } } @@ -735,11 +745,14 @@ abstract class Tasty extends StandardDefinitions { tasty => type TypeBounds <: TypeOrBounds - implicit def typeBoundsClassTag: ClassTag[TypeBounds] + val IsTypeBounds: IsTypeBoundsExtractor + abstract class IsTypeBoundsExtractor { + def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[TypeBounds] + } val TypeBounds: TypeBoundsExtractor abstract class TypeBoundsExtractor { - def unapply(x: TypeBounds)(implicit ctx: Context): Option[(Type, Type)] + def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Option[(Type, Type)] } trait TypeBoundsAPI { @@ -752,11 +765,9 @@ abstract class Tasty extends StandardDefinitions { tasty => type NoPrefix <: TypeOrBounds - implicit def noPrefixClassTag: ClassTag[NoPrefix] - val NoPrefix: NoPrefixExtractor abstract class NoPrefixExtractor { - def unapply(x: NoPrefix)(implicit ctx: Context): Boolean + def unapply(typeOrBounds: TypeOrBounds)(implicit ctx: Context): Boolean } // ===== Constants ================================================ @@ -768,76 +779,74 @@ abstract class Tasty extends StandardDefinitions { tasty => } implicit def ConstantDeco(const: Constant): ConstantAPI - implicit def constantClassTag: ClassTag[Constant] - val Constant: ConstantModule abstract class ConstantModule { val Unit: UnitExtractor abstract class UnitExtractor { - def unapply(x: Constant): Boolean + def unapply(constant: Constant): Boolean } val Null: NullExtractor abstract class NullExtractor { - def unapply(x: Constant): Boolean + def unapply(constant: Constant): Boolean } val Boolean: BooleanExtractor abstract class BooleanExtractor { - def unapply(x: Constant): Option[Boolean] + def unapply(constant: Constant): Option[Boolean] } val Byte: ByteExtractor abstract class ByteExtractor { - def unapply(x: Constant): Option[Byte] + def unapply(constant: Constant): Option[Byte] } val Short: ShortExtractor abstract class ShortExtractor { - def unapply(x: Constant): Option[Short] + def unapply(constant: Constant): Option[Short] } val Char: CharExtractor abstract class CharExtractor { - def unapply(x: Constant): Option[Char] + def unapply(constant: Constant): Option[Char] } val Int: IntExtractor abstract class IntExtractor { - def unapply(x: Constant): Option[Int] + def unapply(constant: Constant): Option[Int] } val Long: LongExtractor abstract class LongExtractor { - def unapply(x: Constant): Option[Long] + def unapply(constant: Constant): Option[Long] } val Float: FloatExtractor abstract class FloatExtractor { - def unapply(x: Constant): Option[Float] + def unapply(constant: Constant): Option[Float] } val Double: DoubleExtractor abstract class DoubleExtractor { - def unapply(x: Constant): Option[Double] + def unapply(constant: Constant): Option[Double] } val String: StringExtractor abstract class StringExtractor { - def unapply(x: Constant): Option[String] + def unapply(constant: Constant): Option[String] } val ClassTag: ClassTagExtractor abstract class ClassTagExtractor { - def unapply(x: Constant): Option[Type] + def unapply(constant: Constant): Option[Type] } /** Extractor for scala.Symbol literals */ val Symbol: SymbolExtractor /** Extractor for scala.Symbol literals */ abstract class SymbolExtractor { - def unapply(x: Constant): Option[scala.Symbol] + def unapply(constant: Constant): Option[scala.Symbol] } } @@ -845,11 +854,9 @@ abstract class Tasty extends StandardDefinitions { tasty => type Signature - implicit def signatureClassTag: ClassTag[Signature] - val Signature: SignatureExtractor abstract class SignatureExtractor { - def unapply(x: Signature)(implicit ctx: Context): Option[(List[String], String)] + def unapply(sig: Signature)(implicit ctx: Context): Option[(List[String], String)] } trait SignatureAPI { diff --git a/library/src/scala/tasty/util/ShowExtractors.scala b/library/src/scala/tasty/util/ShowExtractors.scala index 90b8889fff4a..d6db42a4aaca 100644 --- a/library/src/scala/tasty/util/ShowExtractors.scala +++ b/library/src/scala/tasty/util/ShowExtractors.scala @@ -77,8 +77,8 @@ class ShowExtractors[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty case ClassDef(name, constr, parents, self, body) => this += "ClassDef(\"" += name += "\", " += constr += ", " visitList[Parent](parents, { - case parent @ Term() => this += parent - case parent @ TypeTree() => this += parent + case IsTerm(parent) => this += parent + case IsTypeTree(parent) => this += parent }) this += ", " += self += ", " ++= body += ")" case PackageDef(name, owner) => diff --git a/library/src/scala/tasty/util/ShowSourceCode.scala b/library/src/scala/tasty/util/ShowSourceCode.scala index c29e15dfc70e..fefbd3195c90 100644 --- a/library/src/scala/tasty/util/ShowSourceCode.scala +++ b/library/src/scala/tasty/util/ShowSourceCode.scala @@ -71,8 +71,8 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty case tree @ PackageClause(name, stats) => val stats1 = stats.collect { - case stat @ PackageClause(_, _) => stat - case stat @ Definition() if !(stat.flags.isObject && stat.flags.isLazy) => stat + case IsPackageClause(stat) => stat + case IsDefinition(stat) if !(stat.flags.isObject && stat.flags.isLazy) => stat case stat @ Import(_, _) => stat } name match { @@ -90,7 +90,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty this += "." printImportSelectors(selectors) - case cdef @ ClassDef(name, DefDef(_, targs, argss, _, _), parents, self, stats) => + case IsClassDef(cdef @ ClassDef(name, DefDef(_, targs, argss, _, _), parents, self, stats)) => printDefAnnotations(cdef) val flags = cdef.flags @@ -115,29 +115,26 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty } val parents1 = parents.filter { - case Term.Apply(Term.Select(Term.New(tpt), _, _), _) => !Types.JavaLangObject.unapply(tpt.tpe) - case TypeTree.TermSelect(Term.Select(Term.Ident("_root_"), "scala", _), "Product") => false + case IsTerm(Term.Apply(Term.Select(Term.New(tpt), _, _), _)) => !Types.JavaLangObject.unapply(tpt.tpe) + case IsTypeTree(TypeTree.TermSelect(Term.Select(Term.Ident("_root_"), "scala", _), "Product")) => false case _ => true } if (parents1.nonEmpty) this += " extends " def printParent(parent: Parent): Unit = parent match { - case parent @ Term.TypeApply(fun, targs) => + case IsTypeTree(parent) => + printTypeTree(parent) + case IsTerm(Term.TypeApply(fun, targs)) => printParent(fun) inSquare(printTypeOrBoundsTrees(targs, ", ")) - - case parent @ Term.Apply(fun, args) => + case IsTerm(Term.Apply(fun, args)) => printParent(fun) inParens(printTrees(args, ", ")) - - case parent @ Term.Select(Term.New(tpt), _, _) => + case IsTerm(Term.Select(Term.New(tpt), _, _)) => printTypeTree(tpt) - - case parent @ TypeTree() => - printTypeTree(parent) - - case parent @ Term() => throw new MatchError(parent.show) + case IsTerm(parent) => + throw new MatchError(parent.show) } def printSeparated(list: List[Parent]): Unit = list match { @@ -168,9 +165,9 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty !flags.isParam && !flags.isParamAccessor && !flags.isFieldAccessor && !isCaseClassUnOverridableMethod && !isInnerModuleObject } val stats1 = stats.collect { - case stat @ Definition() if keepDefinition(stat) => stat + case IsDefinition(stat) if keepDefinition(stat) => stat case stat @ Import(_, _) => stat - case stat @ Term() => stat + case IsTerm(stat) => stat } def printBody(printSelf: Boolean) = { @@ -202,12 +199,12 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty } this - case tdef @ TypeDef(name, rhs) => + case IsTypeDef(tdef @ TypeDef(name, rhs)) => printDefAnnotations(tdef) this += "type " printTargDef(tdef, isMember = true) - case vdef @ ValDef(name, tpt, rhs) => + case IsValDef(vdef @ ValDef(name, tpt, rhs)) => printDefAnnotations(vdef) val flags = vdef.flags @@ -240,7 +237,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty printTree(body) += " while " inParens(printTree(cond)) - case ddef @ DefDef(name, targs, argss, tpt, rhs) => + case IsDefDef(ddef @ DefDef(name, targs, argss, tpt, rhs)) => printDefAnnotations(ddef) val isConstructor = name == "" @@ -269,7 +266,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty } this - case tree @ Term.Ident(_) => + case IsTerm(tree @ Term.Ident(_)) => printType(tree.tpe) case Term.Select(qual, name, sig) => @@ -362,7 +359,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty case Term.Block(stats0, expr) => val stats = stats0.filter { - case tree @ ValDef(_, _, _) => !tree.flags.isObject + case IsValDef(tree) => !tree.flags.isObject case _ => true } @@ -557,13 +554,13 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty def printTargDef(arg: TypeDef, isMember: Boolean = false): Buffer = { this += arg.name arg.rhs match { - case rhs @ TypeBoundsTree(lo, hi) => printBoundsTree(rhs) + case IsTypeBoundsTree(rhs) => printBoundsTree(rhs) case rhs @ SyntheticBounds() => printTypeOrBound(rhs.tpe) case rhs @ TypeTree.TypeLambdaTree(tparams, body) => def printParam(t: TypeOrBoundsTree): Unit = t match { - case t @ TypeBoundsTree(_, _) => printBoundsTree(t) - case t @ TypeTree() => printTypeTree(t) + case IsTypeBoundsTree(t) => printBoundsTree(t) + case IsTypeTree(t) => printTypeTree(t) } def printSeparated(list: List[TypeDef]): Unit = list match { case Nil => @@ -582,7 +579,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty printTypeOrBoundsTree(body) } else this - case rhs @ TypeTree() => + case IsTypeTree(rhs) => this += " = " printTypeTree(rhs) } @@ -627,7 +624,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty case DefDef("", _, _, _, _) => val ClassDef(_, _, _, _, body) = arg.owner.owner body.collectFirst { - case vdef @ ValDef(`name`, _, _) if vdef.flags.isParamAccessor => + case IsValDef(vdef @ ValDef(`name`, _, _)) if vdef.flags.isParamAccessor => if (!vdef.flags.isLocal) { var printedPrefix = false if (vdef.flags.isOverride) { @@ -734,7 +731,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty printTypeTree(hi) case tpt @ SyntheticBounds() => printTypeOrBound(tpt.tpe) - case tpt @ TypeTree() => + case IsTypeTree(tpt) => printTypeTree(tpt) } @@ -819,7 +816,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty printType(lo) this += " <: " printType(hi) - case tpe@Type() => printType(tpe) + case IsType(tpe) => printType(tpe) } def printType(tpe: Type): Buffer = tpe match { @@ -829,10 +826,10 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty case Type.SymRef(sym, prefix) => prefix match { case Types.EmptyPrefix() => - case prefix @ Type.SymRef(ClassDef(_, _, _, _, _), _) => + case IsType(prefix @ Type.SymRef(ClassDef(_, _, _, _, _), _)) => printType(prefix) this += "#" - case prefix @ Type() => + case IsType(prefix) => if (!sym.flags.isLocal) { printType(prefix) this += "." @@ -844,7 +841,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty prefix match { case Type.ThisType(Types.EmptyPackage()) => this += name - case prefix @ Type() => + case IsType(prefix) => printType(prefix) if (name != "package") this += "." += name @@ -856,7 +853,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty case Type.TypeRef(name, prefix) => prefix match { case NoPrefix() | Type.ThisType(Types.EmptyPackage()) => - case prefix@Type() => printType(prefix) += "." + case IsType(prefix) => printType(prefix) += "." } if (name.endsWith("$")) this += name.stripSuffix("$") += ".type" else this += name @@ -983,7 +980,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty case Type.ByNameType(t) => this += ": " printType(t) - case tp @ Type() => + case IsType(tp) => this += ": " printType(tp) } @@ -993,13 +990,13 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty indented { this += lineBreak() info match { - case info @ TypeBounds(_, _) => + case IsTypeBounds(info) => this += "type " += name printBounds(info) case Type.ByNameType(_) | Type.MethodType(_, _, _) | Type.TypeLambda(_, _, _) => this += "def " += name printMethodicType(info) - case info @ Type() => + case IsType(info) => this += "val " += name printMethodicType(info) } @@ -1014,8 +1011,8 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty def printMethodicTypeParams(paramNames: List[String], params: List[TypeOrBounds]): Unit = { def printInfo(info: TypeOrBounds) = info match { - case info @ TypeBounds(_, _) => printBounds(info) - case info @ Type() => + case IsTypeBounds(info) => printBounds(info) + case IsType(info) => this += ": " printType(info) } @@ -1121,8 +1118,8 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty } private object SpecialOp { - def unapply(arg: Term)(implicit ctx: Context): Option[(String, List[Term])] = arg match { - case arg@Term.Apply(fn, args) => + def unapply(arg: Tree)(implicit ctx: Context): Option[(String, List[Term])] = arg match { + case IsTerm(arg @ Term.Apply(fn, args)) => fn.tpe match { case Type.SymRef(DefDef(op, _, _, _, _), Type.ThisType(Type.SymRef(PackageDef("", _), NoPrefix()))) => Some((op, args)) @@ -1153,7 +1150,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty object Repeated { def unapply(tpe: Type)(implicit ctx: Context): Option[Type] = tpe match { - case Type.AppliedType(Type.TypeRef("", ScalaPackage()), (tp@Type()) :: Nil) => Some(tp) + case Type.AppliedType(Type.TypeRef("", ScalaPackage()), IsType(tp) :: Nil) => Some(tp) case _ => None } } diff --git a/library/src/scala/tasty/util/TreeAccumulator.scala b/library/src/scala/tasty/util/TreeAccumulator.scala index 676e4e820b44..975efbca9230 100644 --- a/library/src/scala/tasty/util/TreeAccumulator.scala +++ b/library/src/scala/tasty/util/TreeAccumulator.scala @@ -59,21 +59,21 @@ abstract class TreeAccumulator[X, T <: Tasty with Singleton](val tasty: T) { foldTrees(x, elems) case Term.Inlined(call, bindings, expansion) => foldTree(foldTrees(x, bindings), expansion) - case vdef @ ValDef(_, tpt, rhs) => + case IsDefinition(vdef @ ValDef(_, tpt, rhs)) => implicit val ctx = localCtx(vdef) foldTrees(foldTypeTree(x, tpt), rhs) - case ddef @ DefDef(_, tparams, vparamss, tpt, rhs) => + case IsDefinition(ddef @ DefDef(_, tparams, vparamss, tpt, rhs)) => implicit val ctx = localCtx(ddef) foldTrees(foldTypeTree((foldTrees(x, tparams) /: vparamss)(foldTrees), tpt), rhs) - case tdef @ TypeDef(_, rhs) => + case IsDefinition(tdef @ TypeDef(_, rhs)) => implicit val ctx = localCtx(tdef) foldTypeTree(x, rhs) - case cdef @ ClassDef(_, constr, parents, self, body) => + case IsDefinition(cdef @ ClassDef(_, constr, parents, self, body)) => implicit val ctx = localCtx(cdef) foldTrees(foldTrees(foldParents(foldTree(x, constr), parents), self), body) case Import(expr, selectors) => foldTree(x, expr) - case clause @ PackageClause(pid, stats) => + case IsPackageClause(clause @ PackageClause(pid, stats)) => foldTrees(foldTree(x, pid), stats)(localCtx(clause.definition)) } } @@ -106,8 +106,8 @@ abstract class TreeAccumulator[X, T <: Tasty with Singleton](val tasty: T) { } private def foldOverParent(x: X, tree: Parent)(implicit ctx: Context): X = tree match { - case tree @ Term() => foldOverTree(x, tree) - case tree @ TypeTree() => foldOverTypeTree(x, tree) + case IsTerm(tree) => foldOverTree(x, tree) + case IsTypeTree(tree) => foldOverTypeTree(x, tree) } } diff --git a/tests/run/tasty-custom-show/quoted_1.scala b/tests/run/tasty-custom-show/quoted_1.scala index dfadb7e83e37..19b716fecf6c 100644 --- a/tests/run/tasty-custom-show/quoted_1.scala +++ b/tests/run/tasty-custom-show/quoted_1.scala @@ -19,12 +19,12 @@ object Macros { // Use custom Show[_] here implicit val printer = new DummyShow(tasty) tree match { - case tree @ DefDef(name, _, _, _, _) => + case IsDefinition(tree @ DefDef(name, _, _, _, _)) => buff.append(name) buff.append("\n") buff.append(tree.owner.show) buff.append("\n\n") - case tree @ ValDef(name, _, _) => + case IsDefinition(tree @ ValDef(name, _, _)) => buff.append(name) buff.append("\n") buff.append(tree.owner.show) diff --git a/tests/run/tasty-extractors-owners/quoted_1.scala b/tests/run/tasty-extractors-owners/quoted_1.scala index dacacdc05a2b..9d15702eee76 100644 --- a/tests/run/tasty-extractors-owners/quoted_1.scala +++ b/tests/run/tasty-extractors-owners/quoted_1.scala @@ -16,12 +16,12 @@ object Macros { val output = new TreeTraverser(tasty) { override def traverseTree(tree: Tree)(implicit ctx: Context): Unit = { tree match { - case tree @ DefDef(name, _, _, _, _) => + case IsDefinition(tree @ DefDef(name, _, _, _, _)) => buff.append(name) buff.append("\n") buff.append(tree.owner.show) buff.append("\n\n") - case tree @ ValDef(name, _, _) => + case IsDefinition(tree @ ValDef(name, _, _)) => buff.append(name) buff.append("\n") buff.append(tree.owner.show) From 02755c7c6b27e0153400e6214b7a211234abefc5 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Thu, 9 Aug 2018 14:29:07 +0200 Subject: [PATCH 2/4] Drop redundant @unchecked matches --- .../tools/dotc/tastyreflect/TastyImpl.scala | 94 +++++++++---------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala b/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala index 29c2976e9964..485baf3fac65 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala @@ -74,14 +74,14 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit object IsPackageClause extends IsPackageClauseExtractor { def unapply(tree: Tree)(implicit ctx: Context): Option[PackageClause] = tree match { - case x: tpd.PackageDef @unchecked => Some(x) + case x: tpd.PackageDef => Some(x) case _ => None } } object PackageClause extends PackageClauseExtractor { def unapply(tree: Tree)(implicit ctx: Context): Option[(Term, List[Tree])] = tree match { - case x: tpd.PackageDef @unchecked => Some((x.pid, x.stats)) + case x: tpd.PackageDef => Some((x.pid, x.stats)) case _ => None } } @@ -98,7 +98,7 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit object Import extends ImportExtractor { def unapply(x: Tree)(implicit ctx: Context): Option[(Term, List[ImportSelector])] = x match { - case x: tpd.Import @unchecked => Some((x.expr, x.selectors)) + case x: tpd.Import => Some((x.expr, x.selectors)) case _ => None } } @@ -181,14 +181,14 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit object IsClassDef extends IsClassDefExtractor { def unapply(tree: Tree)(implicit ctx: Context): Option[ClassDef] = tree match { - case x: tpd.TypeDef @unchecked if x.isClassDef => Some(x) + case x: tpd.TypeDef if x.isClassDef => Some(x) case _ => None } } object ClassDef extends ClassDefExtractor { def unapply(tree: Tree)(implicit ctx: Context): Option[(String, DefDef, List[Parent], Option[ValDef], List[Statement])] = tree match { - case x: tpd.TypeDef @unchecked if x.isClassDef => + case x: tpd.TypeDef if x.isClassDef => val deco = ClassDefDeco(x) Some((x.name.toString, deco.constructor, deco.parents, deco.self, deco.body)) case _ => None @@ -209,14 +209,14 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit object IsDefDef extends IsDefDefExtractor { def unapply(tree: Tree)(implicit ctx: Context): Option[DefDef] = tree match { - case x: tpd.DefDef @unchecked => Some(x) + case x: tpd.DefDef => Some(x) case _ => None } } object DefDef extends DefDefExtractor { def unapply(tree: Tree)(implicit ctx: Context): Option[(String, List[TypeDef], List[List[ValDef]], TypeTree, Option[Term])] = tree match { - case x: tpd.DefDef @unchecked => + case x: tpd.DefDef => Some((x.name.toString, x.tparams, x.vparamss, x.tpt, optional(x.rhs))) case _ => None } @@ -235,14 +235,14 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit object IsValDef extends IsValDefExtractor { def unapply(tree: Tree)(implicit ctx: Context): Option[ValDef] = tree match { - case x: tpd.ValDef @unchecked => Some(x) + case x: tpd.ValDef => Some(x) case _ => None } } object ValDef extends ValDefExtractor { def unapply(tree: Tree)(implicit ctx: Context): Option[(String, TypeTree, Option[Term])] = tree match { - case x: tpd.ValDef @unchecked => + case x: tpd.ValDef => Some((x.name.toString, x.tpt, optional(x.rhs))) case _ => None } @@ -259,14 +259,14 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit object IsTypeDef extends IsTypeDefExtractor { def unapply(tree: Tree)(implicit ctx: Context): Option[TypeDef] = tree match { - case x: tpd.TypeDef @unchecked if !x.symbol.isClass => Some(x) + case x: tpd.TypeDef if !x.symbol.isClass => Some(x) case _ => None } } object TypeDef extends TypeDefExtractor { def unapply(tree: Tree)(implicit ctx: Context): Option[(String, TypeOrBoundsTree /* TypeTree | TypeBoundsTree */)] = tree match { - case x: tpd.TypeDef @unchecked if !x.symbol.isClass => Some((x.name.toString, x.rhs)) + case x: tpd.TypeDef if !x.symbol.isClass => Some((x.name.toString, x.rhs)) case _ => None } } @@ -359,14 +359,14 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit object Ident extends IdentExtractor { def unapply(x: Term)(implicit ctx: Context): Option[String] = x match { - case x: tpd.Ident @unchecked if x.isTerm => Some(x.name.show) + case x: tpd.Ident if x.isTerm => Some(x.name.show) case _ => None } } object Select extends SelectExtractor { def unapply(x: Term)(implicit ctx: Context): Option[(Term, String, Option[Signature])] = x match { - case x: tpd.Select @unchecked if x.isTerm => + case x: tpd.Select if x.isTerm => val sig = if (x.symbol.signature == core.Signature.NotAMethod) None else Some(x.symbol.signature) @@ -391,49 +391,49 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit object New extends NewExtractor { def unapply(x: Term)(implicit ctx: Context): Option[TypeTree] = x match { - case x: tpd.New @unchecked => Some(x.tpt) + case x: tpd.New => Some(x.tpt) case _ => None } } object NamedArg extends NamedArgExtractor { def unapply(x: Term)(implicit ctx: Context): Option[(String, Term)] = x match { - case x: tpd.NamedArg @unchecked if x.name.isInstanceOf[Names.TermName] => Some((x.name.toString, x.arg)) + case x: tpd.NamedArg if x.name.isInstanceOf[Names.TermName] => Some((x.name.toString, x.arg)) case _ => None } } object Apply extends ApplyExtractor { def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[Term])] = x match { - case x: tpd.Apply @unchecked => Some((x.fun, x.args)) + case x: tpd.Apply => Some((x.fun, x.args)) case _ => None } } object TypeApply extends TypeApplyExtractor { def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[TypeTree])] = x match { - case x: tpd.TypeApply @unchecked => Some((x.fun, x.args)) + case x: tpd.TypeApply => Some((x.fun, x.args)) case _ => None } } object Super extends SuperExtractor { def unapply(x: Term)(implicit ctx: Context): Option[(Term, Option[Id])] = x match { - case x: tpd.Super @unchecked => Some((x.qual, if (x.mix.isEmpty) None else Some(x.mix))) + case x: tpd.Super => Some((x.qual, if (x.mix.isEmpty) None else Some(x.mix))) case _ => None } } object Typed extends TypedExtractor { def unapply(x: Term)(implicit ctx: Context): Option[(Term, TypeTree)] = x match { - case x: tpd.Typed @unchecked => Some((x.expr, x.tpt)) + case x: tpd.Typed => Some((x.expr, x.tpt)) case _ => None } } object Assign extends AssignExtractor { def unapply(x: Term)(implicit ctx: Context): Option[(Term, Term)] = x match { - case x: tpd.Assign @unchecked => Some((x.lhs, x.rhs)) + case x: tpd.Assign => Some((x.lhs, x.rhs)) case _ => None } } @@ -476,7 +476,7 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit object Inlined extends InlinedExtractor { def unapply(x: Term)(implicit ctx: Context): Option[(Option[Term], List[Statement], Term)] = x match { - case x: tpd.Inlined @unchecked => + case x: tpd.Inlined => Some((optional(x.call), x.bindings, x.expansion)) case _ => None } @@ -484,49 +484,49 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit object Lambda extends LambdaExtractor { def unapply(x: Term)(implicit ctx: Context): Option[(Term, Option[TypeTree])] = x match { - case x: tpd.Closure @unchecked => Some((x.meth, optional(x.tpt))) + case x: tpd.Closure => Some((x.meth, optional(x.tpt))) case _ => None } } object If extends IfExtractor { def unapply(x: Term)(implicit ctx: Context): Option[(Term, Term, Term)] = x match { - case x: tpd.If @unchecked => Some((x.cond, x.thenp, x.elsep)) + case x: tpd.If => Some((x.cond, x.thenp, x.elsep)) case _ => None } } object Match extends MatchExtractor { def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[CaseDef])] = x match { - case x: tpd.Match @unchecked => Some((x.selector, x.cases)) + case x: tpd.Match => Some((x.selector, x.cases)) case _ => None } } object Try extends TryExtractor { def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[CaseDef], Option[Term])] = x match { - case x: tpd.Try @unchecked => Some((x.expr, x.cases, optional(x.finalizer))) + case x: tpd.Try => Some((x.expr, x.cases, optional(x.finalizer))) case _ => None } } object Return extends ReturnExtractor { def unapply(x: Term)(implicit ctx: Context): Option[Term] = x match { - case x: tpd.Return @unchecked => Some(x.expr) + case x: tpd.Return => Some(x.expr) case _ => None } } object Repeated extends RepeatedExtractor { def unapply(x: Term)(implicit ctx: Context): Option[List[Term]] = x match { - case x: tpd.SeqLiteral @unchecked => Some(x.elems) + case x: tpd.SeqLiteral => Some(x.elems) case _ => None } } object SelectOuter extends SelectOuterExtractor { def unapply(x: Term)(implicit ctx: Context): Option[(Term, Int, Type)] = x match { - case x: tpd.Select @unchecked => + case x: tpd.Select => x.name match { case NameKinds.OuterSelectName(_, levels) => Some((x.qualifier, levels, x.tpe.stripTypeVar)) case _ => None @@ -572,7 +572,7 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit object CaseDef extends CaseDefExtractor { def unapply(x: CaseDef): Option[(Pattern, Option[Term], Term)] = x match { - case x: tpd.CaseDef @unchecked => + case x: tpd.CaseDef => Some(x.pat, optional(x.guard), x.body) case _ => None } @@ -592,16 +592,16 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit object Value extends ValueExtractor { def unapply(x: Pattern)(implicit ctx: Context): Option[Term] = x match { - case lit: tpd.Literal @unchecked => Some(lit) - case ref: tpd.RefTree @unchecked if ref.isTerm => Some(ref) - case ths: tpd.This @unchecked => Some(ths) + case lit: tpd.Literal => Some(lit) + case ref: tpd.RefTree if ref.isTerm => Some(ref) + case ths: tpd.This => Some(ths) case _ => None } } object Bind extends BindExtractor { def unapply(x: Pattern)(implicit ctx: Context): Option[(String, Pattern)] = x match { - case x: tpd.Bind @unchecked if x.name.isTermName => Some(x.name.toString, x.body) + case x: tpd.Bind if x.name.isTermName => Some(x.name.toString, x.body) case _ => None } } @@ -620,7 +620,7 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit object Alternative extends AlternativeExtractor { def unapply(x: Pattern)(implicit ctx: Context): Option[List[Pattern]] = x match { - case x: tpd.Alternative @unchecked => Some(x.trees) + case x: tpd.Alternative => Some(x.trees) case _ => None } } @@ -672,70 +672,70 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit object TypeIdent extends TypeIdentExtractor { def unapply(x: TypeTree)(implicit ctx: Context): Option[String] = x match { - case x: tpd.Ident @unchecked if x.isType => Some(x.name.toString) + case x: tpd.Ident if x.isType => Some(x.name.toString) case _ => None } } object TermSelect extends TermSelectExtractor { def unapply(x: TypeTree)(implicit ctx: Context): Option[(Term, String)] = x match { - case x: tpd.Select @unchecked if x.isType && x.qualifier.isTerm => Some(x.qualifier, x.name.toString) + case x: tpd.Select if x.isType && x.qualifier.isTerm => Some(x.qualifier, x.name.toString) case _ => None } } object TypeSelect extends TypeSelectExtractor { def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, String)] = x match { - case x: tpd.Select @unchecked if x.isType && x.qualifier.isType => Some(x.qualifier, x.name.toString) + case x: tpd.Select if x.isType && x.qualifier.isType => Some(x.qualifier, x.name.toString) case _ => None } } object Singleton extends SingletonExtractor { def unapply(x: TypeTree)(implicit ctx: Context): Option[Term] = x match { - case x: tpd.SingletonTypeTree @unchecked => Some(x.ref) + case x: tpd.SingletonTypeTree => Some(x.ref) case _ => None } } object Refined extends RefinedExtractor { def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, List[Definition])] = x match { - case x: tpd.RefinedTypeTree @unchecked => Some(x.tpt, x.refinements) + case x: tpd.RefinedTypeTree => Some(x.tpt, x.refinements) case _ => None } } object Applied extends AppliedExtractor { def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, List[TypeOrBoundsTree])] = x match { - case x: tpd.AppliedTypeTree @unchecked => Some(x.tpt, x.args) + case x: tpd.AppliedTypeTree => Some(x.tpt, x.args) case _ => None } } object Annotated extends AnnotatedExtractor { def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, Term)] = x match { - case x: tpd.Annotated @unchecked => Some(x.arg, x.annot) + case x: tpd.Annotated => Some(x.arg, x.annot) case _ => None } } object And extends AndExtractor { def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] = x match { - case x: tpd.AndTypeTree @unchecked => Some(x.left, x.right) + case x: tpd.AndTypeTree => Some(x.left, x.right) case _ => None } } object Or extends OrExtractor { def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] = x match { - case x: tpd.OrTypeTree @unchecked => Some(x.left, x.right) + case x: tpd.OrTypeTree => Some(x.left, x.right) case _ => None } } object ByName extends ByNameExtractor { def unapply(x: TypeTree)(implicit ctx: Context): Option[TypeTree] = x match { - case x: tpd.ByNameTypeTree @unchecked => Some(x.result) + case x: tpd.ByNameTypeTree => Some(x.result) case _ => None } } @@ -749,7 +749,7 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit object Bind extends BindExtractor { def unapply(x: TypeTree)(implicit ctx: Context): Option[(String, TypeBoundsTree)] = x match { - case x: tpd.Bind @unchecked if x.name.isTypeName => Some((x.name.toString, x.body)) + case x: tpd.Bind if x.name.isTypeName => Some((x.name.toString, x.body)) case _ => None } } @@ -767,14 +767,14 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit object IsTypeBoundsTree extends IsTypeBoundsTreeExtractor { def unapply(x: TypeOrBoundsTree)(implicit ctx: Context): Option[TypeBoundsTree] = x match { - case x: tpd.TypeBoundsTree @unchecked => Some(x) + case x: tpd.TypeBoundsTree => Some(x) case _ => None } } object TypeBoundsTree extends TypeBoundsTreeExtractor { def unapply(x: TypeOrBoundsTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] = x match { - case x: tpd.TypeBoundsTree @unchecked => Some(x.lo, x.hi) + case x: tpd.TypeBoundsTree => Some(x.lo, x.hi) case _ => None } } From ec1c1589bfad24e600da918cc509460204b35bd8 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Thu, 9 Aug 2018 14:34:30 +0200 Subject: [PATCH 3/4] Avoid hack --- compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala b/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala index 485baf3fac65..044b7cdca7c1 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala @@ -189,13 +189,12 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit object ClassDef extends ClassDefExtractor { def unapply(tree: Tree)(implicit ctx: Context): Option[(String, DefDef, List[Parent], Option[ValDef], List[Statement])] = tree match { case x: tpd.TypeDef if x.isClassDef => - val deco = ClassDefDeco(x) - Some((x.name.toString, deco.constructor, deco.parents, deco.self, deco.body)) + Some((x.name.toString, x.constructor, x.parents, x.self, x.body)) case _ => None } } - def ClassDefDeco(cdef: ClassDef): ClassDefAPI = new ClassDefAPI { + implicit def ClassDefDeco(cdef: ClassDef): ClassDefAPI = new ClassDefAPI { private[this] val rhs = cdef.rhs.asInstanceOf[tpd.Template] def constructor(implicit ctx: Context): DefDef = rhs.constr def parents(implicit ctx: Context): List[tpd.Tree] = rhs.parents From dc4459a733ba528c123d8a77ae4ce92a0481fa67 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Thu, 9 Aug 2018 14:56:17 +0200 Subject: [PATCH 4/4] Fix potential bug in IsDefinition --- compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala b/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala index 044b7cdca7c1..1f0d1c01cce9 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala @@ -133,11 +133,12 @@ class TastyImpl(val rootContext: Contexts.Context) extends scala.tasty.Tasty wit // ----- Definitions ---------------------------------------------- - type Definition = tpd.Tree + type Definition = tpd.Tree /* tpd.MemberDef | PackageDef */ object IsDefinition extends IsDefinitionExtractor { def unapply(tree: Tree)(implicit ctx: Context): Option[Definition] = tree match { case tree: tpd.MemberDef => Some(tree) + case tree: PackageDef => Some(tree) case _ => None } }